僕はよくツイッターをするんですけど、たまにメンション無しで「すてにゃん」ってつぶやく人が居て、でも1000人以上フォローしてるとすべてを監視するのは中々大変です。Slackなら1日中監視してるのでそっちに流すことにしました。PyConにも参加したことだしせっかくなので普段書かないPythonでやってみました。
- Twitter Application Management でアプリを登録する
- REST API vs Streaming API
- tweepy
- Slackのincoming webhookの使い方
- herokuでデプロイ
Twitter Application Management でアプリを登録する
まずはTwitterの公式のとこでアプリの情報をいろいろと書いていってトークンなどを取得する必要があります。apps.twitter.com
何も難しいことをする必要はなく、アプリの名前、説明文、URLなどを入力すればおkです。
作成後、いくつかのタブが現れますが、僕はとりあえず Permissions って書いてある画面でアクセス権限を Read only にしました。今回はツイートを検索するだけなので。あとは Keys and Access Tokens ってタブであとで必要になってくるトークンが揃ってます。
REST API vs Streaming API
Twitterでアプリを作る場合考えないといけないことの一つは、REST API と Streaming API のどちら(もしくは両方)を使うべきかです。それぞれ詳しいことは公式のドキュメントに書いてあります。dev.twitter.com
dev.twitter.com
基本的にどういうものかというと、REST APIのほうは例えばツイートを検索する際、検索をするたびに GET search/tweets などを叩く必要があるのに比べて、Streaming APIの場合はずっと繋がってるので新着ツイートなどはドシドシ流れてくるという感じです。今回僕はStreaming APIのほうを使いました。なぜならREST APIのほうは気をつけないと制限に引っかかってAPI叩けなくなったり、実装があまりきれいにならないかなと思ったからです。
これだけ見ると常にStreaming API使いたくなるけど、例えばWi-Fiがない場所でツイッターをするときずっとツイート読み込み続けてるとデータ使われまくるので困りますよね。そういう点も多分考慮するべきなんでしょう(Twitterクライアントとか作ったことないけど)。
tweepy
僕がやりたかったのはぱぱっとエゴサしてSlackに流すbotを作るだけなので、とりあえずいい感じのPython向けのTwitterライブラリーを探しました。tweepyとかpython-twitterとかあるらしくて、特に深い理由はないけどtweepyというのを使ってみました。
とりあえずドキュメントにある Hello Tweepyというのをやってみて、端末にTLが流れていく様子をみましょう
# tweepy.org ドキュメントのHello Tweepy より import tweepy # consumer_key等はapps.twitter.comからとってきたものを使う auth = tweepy.OAuthHandler(consumer_key, consumer_secret) auth.set_access_token(access_token, access_token_secret) api = tweepy.API(auth) public_tweets = api.home_timeline() for tweet in public_tweets: print tweet.text
tweepy.Streaming
Hello Tweepyの例ではREST APIを使っているので、Streaming APIの場合は以下のドキュメントを参照しましょう
Streaming With Tweepy — tweepy 3.3.0 documentation
大体ドキュメントに書いてありますが、基本的にはStreamListenerを継承するクラスを作って、そこで on_status あたりにツイートが流れてくるのでそれをオーバーライドして好きに色々すればいいってことですね。というわけで、Hello TweepyのようなことをStreaming APIでやるとこんな感じになると思います。
import tweepy # tweepy.StreamListener をオーバーライド class MyStreamListener(tweepy.StreamListener): def on_status(self, status): print(status.text) #端末に表示するのみ def on_error(self, status_code): if status_code == 420: return False def initialize(): # consumer_keyなどは自分のに設定してください auth = tweepy.OAuthHandler("consumer_key", "consumer_secret") auth.set_access_token("access_token", "access_token_secret") api = tweepy.API(auth) startStream(api.auth) def startStream(auth): myStreamListener = MyStreamListener() myStream = tweepy.Stream(auth = auth, listener=myStreamListener) myStream.userstream() #タイムラインを表示 # myStream.filter(track=["#cats"]) #検索がしたい場合 def main(): initialize() if __name__ == "__main__": main()
今回はエゴサが目的だったので上のコードでもコメントで書きましたが、Streamのfilterというのを使えば検索が簡単にできます。そうすればエゴサ結果が端末に表示されていきます。あとはSlackに流すだけです。
Slackのincoming webhookの使い方
incoming webhookってなんぞやって感じですが、ここに色々書いてあります。
Incoming Webhooks | Slack
なんか要するに、リアルタイムに外からのデータをSlackに流し込んでやるぞいって感じですね。今回の目的にぴったし。Slackの流したいチャンネルのとこで、Add a service integrationっていうのをポチッとして、incoming webhookを選択すればOK。
先ほどのincoming webhookのドキュメントの最後にcurlの例が書いてあるんですが(以下の通りです)
curl -X POST --data-urlencode 'payload={"text": "This is posted to <#general> and comes from *monkey-bot*.", "channel": "#general", "username": "monkey-bot", "icon_emoji": ":monkey_face:"}' https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX
だいたいこんなイメージでPOSTするだけでどうやら簡単にSlackに投稿できるらしいです。最後のhooks.slack.com/~~~のリンクはAdd a service integration→incoming webhookと選択したときに表示されるのでそれを使えばおkです。
で、Pythonでどうやんの?って思ったけど以下のように普通にできました。案外楽ちん
import json import requests def postToSlack(text): payload = { "channel": "#ego-search", "username": "ego-search-master", "icon_emoji": ":innocent:", "text": text } url = "https://hooks.slack.com/services/~~~~" payloadJson = json.dumps(payload) requests.post(url, data=payloadJson)
ってことで、先ほど端末にprintしてたのを、この関数を通せばSlackに流れるはずです。
herokuでデプロイ
herokuのことは結構前から知ってましたが、元々自分がWeb系じゃないってのもあって今まで触ったことがなかったです。ってことでアカウントを作って、以下の公式のドキュメントを読んでました
Getting Started with Python on Heroku | Heroku Dev Center
とりあえずわかったのはPythonの場合は他に Procfile と requirements.txt というのを用意すれば準備おkで、
- heroku create hogehoge
- git push heroku master
- heroku ps:scale worker=1
とするだけでデプロイされるという予想以上に簡単だということ。ここまで敷居が低いとは思ってませんでした。
あとは heroku ps でプロセスを確認したり、 heroku logs --tail でログを確認したりできました。
ってことでツイッターのエゴサ結果をSlackに流すやつができたので好きなだけ「すてにゃん」とつぶやいてください〜
(数日後、そこにはエゴサ回避をする人々の姿が)
[雑談] 雨の日はきらいですがいつも行くゲーセンが雨の日100円2クレというのをやってるのでプラマイゼロという気分です