GAE/Python で Twitter bot を作る(後編)
準備編 の続きは明日書くとか言っときながら、間が空いてしまいましたが後編を。
残るは肝心のハンドラ部分を実装していきます。
views.py の作成
main.py で指定したように、
- /:TOP画面。ハンドラは MainHandler
- /ssbbot/mumble/update/:cron がここを叩いて更新処理を走らせる。ハンドラは BotHandler
という感じで views.py を実装して行きましょう。
#!/usr/bin/env python # -*- coding:utf-8 -*- import logging from google.appengine.ext import webapp import twitter import ssb import bitly from models import MumbleModel def my_twitter_api_init(self, username=None, password=None, input_encoding=None, request_headers=None): """Monkey patche for twitter.Api.__init__ method. Just change _cache do not use FS cache. """ import urllib2 from twitter import Api self._cache = None self._urllib = urllib2 self._cache_timeout = Api.DEFAULT_CACHE_TIMEOUT self._InitializeRequestHeaders(request_headers) self._InitializeUserAgent() self._InitializeDefaultParameters() self._input_encoding = input_encoding self.SetCredentials(username, password) twitter.Api.__init__ = my_twitter_api_init class MainHandler(webapp.RequestHandler): def get(self): """ """ self.response.out.write("Stack Stock Books つぶやき Bot") class BotHandler(webapp.RequestHandler): """Bot 更新用ハンドラ""" def get(self): """ """ # 最新の SSB つぶやき取得 ssbapi = ssb.Api() mumble = ssbapi.get_mumbles(include_books=False)[0] logging.debug("mumble: %s", mumble) key_name = MumbleModel.key_format % dict(mumble_id=mumble.mumble_id) mm = MumbleModel.get_by_key_name(key_name) if mm is not None and mm.time >= mumble.time: # 更新情報なし logging.info("No update: mumble_id: %s", mumble.mumble_id) self.response.out.write("No update") return # 書籍情報取得 book = ssbapi.get_book(mumble.book_id) mumble.book = book # 投稿文言生成 twitterapi = twitter.Api(username="TWITTER_USER", password="TWITTER_PWD") user = ssbapi.get_user(mumble.user_id) status = self._mumble_string(user, mumble) if len(status) > 140: status = status[:139] + u'\u2026' # Twitter 更新 result = twitterapi.PostUpdate(status) logging.info("status: %s\nresult: %s", status, result) # 更新情報を登録 mm = MumbleModel(key_name=key_name, mumble_id=mumble.mumble_id, time=mumble.time) mm.put() self.response.out.write("OK") def _mumble_string(self, user, mumble): url = mumble.uri api = bitly.Api() api.set_account("BITLY_LOGIN", "BITLY_APIKEY") try: url = api.shorten(url) except bitly.BitlyResponseError: pass return u"%(url)s %(nick)s『%(title)s』%(body)s" \ % dict(nick=user.nick, title=mumble.book.title, body=mumble.body, url=url)
BotHandler では、
- Stack Stock Books から最新のつぶやき取得
- Datastore に保存した前回のつぶやき情報と比較。更新が無ければ終了。
- 新しい情報ならば、Twitter への投稿文言生成。URL は bit.ly API を利用して短縮。
- 文言が140文字を越えていたら、139文字+'…' として切り詰め処理。
- Twitter へ投稿
- Datastore に最新つぶやき情報を登録
という処理をしています。