去る3月11日、東北関東大地震が発生しました。現在もその影響を受けている地域が数あります。
被災者の方々には心からお見舞い申し上げます。
地震発生当初、都内にいた私は4時間かけて浦安市の自宅まで徒歩で帰りました。大地震が来た際には、そういうこともありえると考えたことはありましたが、まさか、現実になるとは。そして、浦安市内に入ると、そこには予想もしなかった光景がありました。
地盤の液状化です。
状況はこちらを参考にしていただければと思います。
地震・断水日誌の写真 3|M-Sea日誌
なんとか自宅までたどり着いた、翌朝、Twitterのタイムラインを見ていると、IT系、または、インターネットサービス業各社が被災地の支援を率先していることを知りました。
私にも何かできることはないか?
数日模索していました。
で、出た結論は、
プログラムを書くこと。
いろいろ考えましたが、やっぱりこれしかできないのです。
そこで、一番身近なところで、私も居住している地域のために何かしたいと考えました。浦安市には外国の方もたくさん居住されています。状況がなかなか把握できない方もいらっしゃいました。
プログラムは、浦安市公式Twitterアカウント@urayasu_kohoのツイートを英訳するボット、@urayasu_kohobotです(翻訳ばかりで能がないですが・・・)。
Google App Engine – Google Codeを利用しています(以降GAEとします)。GAEの開発環境には、
- Javaランタイム環境
- Pythonランタイム環境
があります。今回はPythonランタイム環境を使用しました。
開発には、こちらを参考にさせていただきました。
GAEでTwitter botを作った – すぎゃーんメモ
この環境に不慣れであること、急ぎで作ったこともあり、ちょっと雑なソースになっているかもしれませんが、ソースコードは以下の通りです。
・/bot/bot.py
import logging import os import oauth import re import urllib from google.appengine.ext.webapp import template from google.appengine.ext.webapp import RequestHandler from google.appengine.ext.webapp import WSGIApplication from google.appengine.ext.webapp.util import run_wsgi_app from google.appengine.api import urlfetch from google.appengine.api import memcache from django.utils import simplejson class TwitterHandler(RequestHandler): def __init__(self): twit = TwitBot() self.action = { 'timeline' :twit.timeline, 'update' :twit.update } def get(self): action = self.action.get(self.request.get('action')) if action: logging.debug(action) action() template_values = { 'actions' :sorted(self.action.keys()), 'done' :self.request.get('action'), 'path' :self.request.path, } path = os.path.join(os.path.dirname(__file__), 'template.html') self.response.out.write(template.render(path, template_values)) class TwitBot: def __init__(self): self.client = oauth.TwitterClient( '********************************', '***************************************', None) def timeline(self): url = 'http://api.twitter.com/1/statuses/user_timeline.json' params = { 'screen_name' :'urayasu_koho', } logging.debug(memcache.get('id')) if memcache.get('id') != None : params['since_id'] = memcache.get('id') result = self.client.make_request( url, token = '************************************************************', secret = '****************************************', additional_params = params, protected = True, method = urlfetch.GET) logging.debug(result.status_code) if result.status_code == 200: statuses = simplejson.loads(result.content) statuses.reverse() for status in statuses: self.translate(status = re.sub('#urayasu', '', status['text'])) memcache.set('id', status['id']) def update(self, status = None): if status != None: url = 'http://api.twitter.com/1/statuses/update.json' if len(status) > 140: status = status[0:139] params = { 'status' : status.encode('utf-8'), 'count' :20 } result = self.client.make_request( url, token = '************************************************************'', secret = '****************************************'', additional_params = params, protected = True, method = urlfetch.POST) logging.debug(result.status_code) logging.debug(result.content) def translate(self, status = None): if status != None: logging.debug(status) url = 'http://ajax.googleapis.com/ajax/services/language/translate' opt = 'v=1.0&'+urllib.urlencode({'q':status.encode('utf-8')})+'&format=text&langpair=ja|en' result = urllib.urlopen(url, opt) translated = simplejson.loads(result.read()) if translated['responseStatus'] == 200: self.update(status = translated['responseData']['translatedText']) def main(): logging.getLogger().setLevel(logging.DEBUG) application = WSGIApplication([ ('/bot/', TwitterHandler),], debug = False) run_wsgi_app(application) if __name__ == '__main__': main()
・app.yaml
application: example.com version: 1 runtime: python api_version: 1 handlers: 〜中略〜 - url: /bot/.* script: bot/bot.py login: admin
・cron.yaml
cron: - description: update timeline url: /bot/?action=timeline schedule: every 1 minutes
説明不足で申し訳ありません。Google App Engineについての記事は、後日、何か書きたいと思います。
このボットについては、、、あまり、利用頻度も高くないとも思いますし、単なる自己満足かもしれません。ですが、少しでも何かの役に立てれば、という思いを込めて作成しました。
今、私にできること。
これが私の結論です。
urayasu_kohobot (urayasu_kohobot) on Twitter