GAEには定期的にコマンドを実行するcronの機能があるので、cronを使ってTwitterボットを作ってみる。
最終的にこういうボットが出来上がりました。千家は横浜のおいしいラーメン屋です。
参考
以前の日記にも利用したこれ。この本で紹介してるボットはWebからのカスタマイズ可能だったりと結構凝ってるのだけど、今回はただ動かすだけということでもっと簡略化したやつを。
「すっきりわかるGoogle App Engine for Javaクラウドプログラミング」
下準備
適当なボットアカウントを作成し、アプリケーション登録申請を行います。次に発行されたコンシューマー・キーとコンシューマー・シークレットを元にアクセス・トークンとアクセス・トークン・シークレットを発行します。以前Pythonで発行した際の手順をここに書いてます。
今回はJavaで発行しました。冒頭紹介した本の付録Hからの引用です。ちなみにTwitterのライブラリはTwitter4Jを利用。
import java.io.BufferedReader; import java.io.InputStreamReader; import twitter4j.Twitter; import twitter4j.TwitterFactory; import twitter4j.auth.AccessToken; import twitter4j.auth.RequestToken; public class TwitterAuth { static String consumerKey = "xxxxx"; static String consumerSecret = "xxxxx"; public static void main(String args[]){ try{ Twitter twitter = new TwitterFactory().getInstance(); twitter.setOAuthConsumer(consumerKey, consumerSecret); RequestToken requestToken = twitter.getOAuthRequestToken(); AccessToken accessToken = null; BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); while(null==accessToken){ System.out.println("open following URL"); System.out.println(requestToken.getAuthenticationURL()); System.out.println("hit enter:"); String line = br.readLine(); try{ accessToken = twitter.getOAuthAccessToken(); }catch(Exception e){ } } System.out.println("token= " + accessToken.getToken()); System.out.println("tokenSecret= " + accessToken.getTokenSecret()); }catch(Exception e){ System.err.print(e); } } }
Twitterボットプログラム
ボットに必要なトークン等が無事発行できたら、メインの投稿プログラムをTwitter4Jを利用して書きます。今回はツイートしたい文字配列を用意しておき、ランダムに選択したものを投稿するボットにしました。プログラムは普通のサーブレットです。
import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.conf.ConfigurationBuilder; public class SenyaBot extends HttpServlet{ static Logger logger = Logger.getLogger("SenyaBot"); static String consumerKey = "xxxxxx"; static String consumerSecret = "xxxxxx"; static String accessToken = "xxxxx"; static String accessTokenSecret = "xxxxx"; private String getTweet(){ String tweets[] = { "家系といったら千屋っしょ", "通は固めの濃いめ", "やっぱり根岸の千家がいいよね。", "信頼の深夜営業", "水曜は定休日なんだよな", "とりあえず千家行こうぜ", "ユー、ライス付けちゃう?", "ミニカレーも意外と美味しいぜ", "ネギうますぎ", "あのネギ盛見るとテンションあがっちゃうよねー", "大将まじかっけぇ", "ここは食券制です" }; int randint = (int)(Math.random()*tweets.length); return tweets[randint]; } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { //http://twitter4j.org/ja/configuration.html ConfigurationBuilder cb = new ConfigurationBuilder(); cb.setDebugEnabled(true) .setOAuthAccessToken(accessToken) .setOAuthAccessTokenSecret(accessTokenSecret) .setOAuthConsumerKey(consumerKey) .setOAuthConsumerSecret(consumerSecret); String message = getTweet(); Twitter twitter = new TwitterFactory(cb.build()).getInstance(); try { //Twitterに書き出し twitter.updateStatus(message); } catch (TwitterException e) { logger.log(Level.SEVERE, "Twitter error", e); } } }
GAE設定
cron.xml
war/WEB-INF/cron.xmlという感じに配置します。
設定方法は公式にバッチリ乗ってます。
<?xml version="1.0" encoding="utf-8"?> <cronentries> <cron> <url>/cron/senya</url> <description>Love Senya</description> <schedule>every 30 mins</schedule> <timezone>Asia/Tokyo</timezone> </cron> </cronentries>
web.xml
上記Twitterボットプログラムをweb.xmlにサーブレットととして登録すればOK。ただこのままだとhttp://<あなたのページ>/cron/senyaを誰かがブラウザで叩くたびに実行されてしまうので、security-constraintタグで管理者権限でしか実行できないようにしておく。
<servlet> <servlet-name>senyaBot</servlet-name> <servlet-class>hoge.fuga.SenyaBot</servlet-class> </servlet> <servlet-mapping> <servlet-name>senyaBot</servlet-name> <url-pattern>/cron/senya</url-pattern> </servlet-mapping> <security-constraint> <web-resource-collection>/cron/*</web-resource-collection> <auth-constraint> <role-name>admin</role-name> </auth-constraint> </security-constraint>
設定確認
アップロードしたらWebの管理画面で[Main]->[Cron Jobs]を確認し、こんな感じの表示になっていたらOK。ちゃんと動いていれば定期的に投稿されてるはず。
Cron Job Schedule/Last Run/Last Status (All times are UTC) /cron/senya Love Senya every 30 mins (Asia/Tokyo) 2011/04/03 16:15:21 on time Success
おしまい。