====== Google App Engineで手軽にTwitterアプリを作成!(OAuthにも対応!) - AppEngine-Twitter ====== 更新履歴とコメントは[[http://0-oo.net/log/category/python-box/google-app-engine-twitter/|AppEngine-Twitter Archive - ゼロと無限の間のログ]]へどうぞ。 {{:python-box:tweeter_48x48.png|}} Google App EngineでTwitter APIを操作するライブラリを作ってみた。\\ 車輪の再発明ではなく、趣味の車輪作り。 バージョン0.3.0からはTwitter Search APIの廃止に対応して、検索もOAuthを使ってTwitter REST API 1.1を使うように変更した。 ===== ライセンス ===== [[http://0-oo.net/pryn/MIT_license.txt|MITライセンス]]で。 ===== デモ(動作サンプル) ===== ==== その1. RT(ReTweet)の多いつぶやきを報告するBot ==== [[http://twitter.com/RT_report|@RT_report]] ==== その2. 地名を告げるとその近くにいるTwitterユーザーの名前を教えてくれるBot ==== [[http://twitter.com/who_is_near|@who_is_near]] ※検索がまだTwitter REST API 1.1に対応させてないので今は動かない(はず) === 使用例 === @who_is_near 六本木 試しにつぶやくには、Twitterにログイン後に[[http://twitter.com/?status=%40who_is_near%20%E5%85%AD%E6%9C%AC%E6%9C%A8|ここをクリック]] ==== その3. 出発地点と目的地を告げると、乗換(ルート)案内のGoogleマップを表示してくれるBot ==== [[http://twitter.com/norikae_map|@norikae_map]] === 使用例 1. 移動方法を指定しないと、電車でのルート検索・乗り換え案内になる === @norikae_map 東京 大阪 試しにつぶやくには、Twitterにログイン後に[[http://twitter.com/?status=%40norikae_map%20%E6%9D%B1%E4%BA%AC%20%E5%A4%A7%E9%98%AA|ここをクリック]] === 使用例 2. 車でのルートの案内 === @norikae_map 木更津駅 羽田空港駅 車 試しにつぶやくには、Twitterにログイン後に[[http://twitter.com/?status=%40norikae_map%20%E6%9C%A8%E6%9B%B4%E6%B4%A5%E9%A7%85%20%E7%BE%BD%E7%94%B0%E7%A9%BA%E6%B8%AF%E9%A7%85%20%E8%BB%8A|ここをクリック]] === 使用例 3. 歩きでのルートの案内 === @norikae_map 霞が関 霞が関 歩き 試しにつぶやくには、Twitterにログイン後に[[http://twitter.com/?status=%40norikae_map%20%E9%9C%9E%E3%81%8C%E9%96%A2%20%E9%9C%9E%E3%81%8C%E9%96%A2%20%E6%AD%A9%E3%81%8D|ここをクリック]] ==== その4. Twitter APIでOAuth認証してつぶやいたりフォローしたりするデモ ==== [[python-box/appengine-oauth|AppEngine Oauth]]のデモその4を参照。 ===== AppEngine-Twitterのソースコード ===== #!/usr/bin/env python # -*- coding: utf-8 -*- ''' AppEngine-Twitter Twitter API wrapper for applications on Google App Engine See: http://0-oo.net/sbox/python-box/appengine-twitter License: http://0-oo.net/pryn/MIT_license.txt (The MIT license) See also: https://dev.twitter.com/docs/api https://developers.google.com/appengine/docs/python/urlfetch/?hl=ja ''' __author__ = 'dgbadmin@gmail.com' __version__ = '0.4.0' import json import urllib from appengine_oauth import AppEngineOAuth from google.appengine.api import urlfetch class AppEngineTwitter(object): def __init__(self): self._api_url = 'https://api.twitter.com/1.1/' self._oauth_url = 'https://api.twitter.com/oauth/' self._oauth = None self._tw_name = '' def update(self, message): ''' Post a tweet Sucess => Retrun 200 / Fialed => Return other HTTP status ''' return self._post('statuses/update.json', {'status': message}) def retweet(self, tweet_id): ''' ReTweet a tweet Sucess => Retrun 200 / Fialed => Return other HTTP status ''' return self._post('statuses/retweet/' + tweet_id + '.json', {}) def follow(self, target_name): ''' Sucess => Return 200 / Already following => Return 403 / Fialed => Return other HTTP status ''' return self._post('friendships/create.json', {'screen_name': target_name}) def is_following(self, target_name): ''' Yes => Return True / No => Return False / Fialed => Return HTTP status except 200 ''' if self._tw_name == '': self.verify() user_info = json.loads(self.last_response.content) self._tw_name = user_info['screen_name'] status = self._get('friendships/exists.json', {'user_a': self._tw_name, 'user_b': target_name}) if status == 200: return (self.last_response.content == 'true') else: return status def verify(self): ''' Verify user_name and password, and get user info Sucess => Return 200 / Fialed => Return other HTTP status ''' return self._get('account/verify_credentials.json', {}) def search(self, keyword, params={}): ''' Sucess => Return Array of dict / Fialed => raise an Exception ''' params['q'] = keyword status = self._get('search/tweets.json', params) if status == 200: return json.loads(self.last_response.content)['statuses'] else: raise Exception('Error: HTTP Status is ' + str(status)) # OAuth methods # (See http://0-oo.net/sbox/python-box/appengine-oauth ) def set_oauth(self, key, secret, acs_token='', acs_token_secret=''): ''' Set OAuth parameters ''' self._oauth = AppEngineOAuth(key, secret, acs_token, acs_token_secret) def prepare_oauth_login(self): ''' Get request token, request token secret and login URL ''' dic = self._oauth.prepare_login(self._oauth_url + 'request_token') dic['url'] = self._oauth_url + 'authorize?' + dic['params'] return dic def exchange_oauth_tokens(self, req_token, req_token_secret): ''' Exchange request token for access token ''' return self._oauth.exchange_tokens(self._oauth_url + 'access_token', req_token, req_token_secret) # Private methods def _post(self, path, params): url = self._api_url + path params = self._oauth.get_oauth_params(url, params, 'POST') res = urlfetch.fetch(url=url, payload=urllib.urlencode(params), method='POST') self.last_response = res return res.status_code def _get(self, path, params): url = self._api_url + path if self._oauth != None: params = self._oauth.get_oauth_params(url, params, 'GET') url += '?' + urllib.urlencode(params) res = urlfetch.fetch(url=url, method='GET') self.last_response = res return res.status_code