映画『サマーウォーズ』の小磯健二のように、誕生日から曜日を計算して教えてくれるtwitterのbotを作った

koiso kenji (@koiso_bot) | Twitter

  • yyyy/mm/dd の形式でreplyすると、その日の曜日を教えてくれる
  • それ以外の形式はすべて無視
  • 1分間隔で10Postまで返答する それ以上は古いものから切り捨て




Python,Twitter,GAE,webアプリ すべてが初心者マークですが、初心者なりにいろいろ考えて作ったので時系列にまとめておく。




なぜ小磯?

昨日の勉強会の時点で、botに定期的に発言させるというところまでは進んでいたので、次はreplyに対して何か返答してくれるbotを作りたいと思った。
そこで思いだしたのが映画『サマーウォーズ』で、主人公の健二が誕生日からその日の曜日を計算で言い当てるシーン。
決まった形式を受け取って、リアクションを返すという意味で、今回の自分の趣旨にぴったりだった。




計算部分のロジックを考える

とりあえず既存の知識だけでなんとかなりそうな計算のロジックを考えた。
式は以下をそのままパク・・・参考にした。


   生年月日で曜日を求める方法 - 映画サマーウォーズでやっていた生年月日で... - Yahoo!知恵袋

# 曜日を準備
week = { 1:'日', 2:'月', 3:'火', 4:'水', 5:'木', 6:'金', 0:'土' }

 〜 略 〜

# 日付を取り出し分割
date = tweet['text'].encode('utf-8').split()[1]
split_date = date.split('/')

# 曜日の計算
h = int(split_date[0][:-2])
y = int(split_date[0][-2:])
m = int(split_date[1])
d = int(split_date[2])
w = y + y / 4 + h / 4 - 2 * h + 13 * ( m + 1 ) / 5 + d
key = w%7

koiso_tweet = '@%s %s曜日ですっ、%sは%s曜日です 当たってます?' 
    % ( re_name, week[key], date, week[key] )


いまさら思ったけど、日付から曜日を簡単に求められるパッケージ(?)とかあったりして。




自分へのreplyを取得する方法を考える

はっきり言って何もわからない、とりあえずtwython.pyの中身を眺めてみる。
もしやreplyと付くそれっぽいメソッドがあるのでは?!と思い検索してみる。
みつからない。


githubにサンプルコードがあると教えてもらった事を思い出す。


   twython/examples at 0d37e5be404f5aaf36ae88e999ef06ffc5e5ccf8 · ryanmcgrath/twython · GitHub


全部試してみてgetUserMentions()がreplyを拾うのに使えそうだと判断した。




同じ発言に対して2回以上replyしないようにする

githubのサンプルコードのようにcount指定だけだと同じ発言に対して2回以上返答してしまう可能性がありそうなので、その制御の処理を考え始める。
これが一番わからなかった。
一度つぶやきを返したものをどこかに記憶しておけばいいのか、でもそうなるとGAEのデータベースとか使うのかーとか、あーだこーだ思ったけれど、「自分が最後につぶやいたとき」を基準にそれ以降の自分へのreplyを対象にすればいいという事で落ち着いた。
つぶやきのデータ内に時系列を判断できるデータがあればそれができる。


getUserMentions()で受け取ったデータの中身を見ながら、使えそうな要素をさがしてみる。
日時っぽいものはあるけどそれをそのまま使えそうにないし、Twitter側でなんか用意してないのかと思って、そこで始めてTwitter側の仕様、つまりAPIがわかってないとダメということに気がつく。


   [観] Twitter API 仕様書 (勝手に日本語訳シリーズ)


引数でsince_idを渡してあげると、それ以降のタイムラインを取得してくれる。
そうかー、とここでidを使えば時系列を判断できるのだと理解した。

# 自分の最後のtweetのステータスidを取得
mytweet = api.getUserTimeline(count='1')
mytweet_id = mytweet[0]['id']

# 最後のtweet以降の自分へのreplyを取得
mymentions = api.getUserMentions(since_id=mytweet_id)


あとはそんなにひっかかるところもなく完成までこぎ着けた。
あ、一度cronが動かなくなってあせったけど。




まとめ

いろいろ紆余曲折したけれど、なんとか形になってよかったです。
TwitterAPIについてはもうちょっと確認が必要。
あとは、受け付けるつぶやきの形式に幅をもたせたり、何もないときでもたまーにつぶやいたりできるといいなあと思います。


GAEの制御についても調べたいし、まだまだやりたいこといっぱいあるなー。