GAEをweb cronとして使う
このエントリの和訳です。http://d.hatena.ne.jp/takahirox/20110430/1304145478
はじめに
以前のエントリでGAEがweb cronとして使えるのではないかと言及しました。
http://d.hatena.ne.jp/takahirox/20110425/1303732480
rubyでbotを作ったときcronの実現方法で悩んだことがありました。
http://d.hatena.ne.jp/takahirox/20090523/1243086497
恐らく「urllib2を使ったGAE python application」と「別のサーバにアップロードし、rubyや他の言語で作成した、CGIで起動するbotプログラム」を使えば、cronの問題が解決できるはずです。
それを実装してみたので、メモを残しておきます。
web cronを検討している人の参考になれば。
特徴
- 長所
bot用のtwitterアカウントを取得する
最初にbot用のアカウントを取得します。そしてtokenやtoken secretも取得します。
ここでの説明は省略します。下記のエントリを参考にしてください。
今回は@supertimebotを再利用しました。以前bot用に取得したアカウントです。詳細はこちら。
好きなwebサーバでbotを作る
その後、botを好きなwebサーバ上で作ります。今回はxreaサーバの上でrubyを使って作りました。
xreaで同じbotを作りたければ、xrea上に自分用のrubygemsをインストールする必要があります。rubygemsのtwitterライブラリを使うからです。インストールの仕方は下記を参考にしてください。
また、今回作ったbotプログラムは、以前rubyで作ったtwitter用のクライアントを基に作成しています。
#!/usr/local/bin/ruby # main.cgi require 'rubygems' require 'twitter' require 'time' require 'cgi' OAUTH_CONSUMER_KEY = 'your consumer token' OAUTH_CONSUMER_SECRET = 'your consumer secret' OAUTH_ACCESS_TOKEN = 'your access token' OAUTH_ACCESS_SECRET = 'your access token secret' PROXY_ADDR = nil oauth = Twitter::OAuth.new( OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET ) oauth.authorize_from_access( OAUTH_ACCESS_TOKEN, OAUTH_ACCESS_SECRET ) base = Twitter::Base.new( oauth ) base.update Time.now cgi = CGI.new puts cgi.header puts 'homuhomu.'
GAEを設定する
最後に、GAE applicationにbotを実行させる設定をします。
bot用にGAE applicationを登録して、下記のファイルをデプロイします。
詳細はこちらのエントリで確認してください。
app.yaml
application: supertimebot version: 1 runtime: python api_version: 1 handlers: - url: /.* script: main.py
cron.yaml
cron: - description: cron job name url: /.* schedule: every 20 minutes
main.py
import urllib2 urllib2.urlopen( 'your bot URL' )
成功すればbotが定期的に呟くはずです。
セキュリティについて
上述したように、セキュリティに気をつける必要があります。URLを叩けば誰でもそのbotを実行できてしまうからです。
対策としてすぐに思いつくのは以下でしょう。
- パスワードを設定する
- USER AGENTをチェックする
- IPをチェックする
- アクセスログを取る
こんな感じに。
#!/usr/local/bin/ruby # main.cgi require 'rubygems' require 'twitter' require 'time' require 'cgi' OAUTH_CONSUMER_KEY = 'your consumer token' OAUTH_CONSUMER_SECRET = 'your consumer secret' OAUTH_ACCESS_TOKEN = 'your access token' OAUTH_ACCESS_SECRET = 'your access token secret' PROXY_ADDR = nil if /\(\+http:\/\/code\.google\.com\/appengine; appid: supertimebot\)/ =~ ENV[ 'HTTP_USER_AGENT' ] then oauth = Twitter::OAuth.new( OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET ) oauth.authorize_from_access( OAUTH_ACCESS_TOKEN, OAUTH_ACCESS_SECRET ) base = Twitter::Base.new( oauth ) base.update Time.now end cgi = CGI.new puts cgi.header puts 'homuhomu.' f = File.open( './homu.txt', 'a' ) f.puts Time.now ENV.each do |key, value| f.puts key, value end f.puts
USER AGENTをチェックしています。さらに、アクセスログを取っています。もちろん、これだけでは不十分ですが。