株式会社ライブキャストロゴ 株式会社ライブキャスト

去る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