かなで技術日誌

プログラミングやエンジニアリング周りについて

主なアウトプットはScrapboxObsidianにまとめてます。

twitterのアイコンをリプライで変更→Herokuにデプロイ

github.com

OS:Mac OS
Python3.6.5

参考
pythonのコードは
kivantium.hateblo.jp

Herokuへのデプロイは
hwhw.hatenablog.com
Railsだけど、デプロイの説明だけならこちらの方がより丁寧ではある。アプリ作成時に名前を指定しないと勝手によく分からない名前をつけられるので
HerokuにRailsアプリをデプロイする手順

Herokuのコマンドもよく知らなかったので調べました
vdeep.net
ただアプリの削除が上のurlに載っているコマンドだとどうしても出来なくて
simpledancer.hatenablog.com
こっちだと削除出来た


コードに関しては既にほぼ完成されていたので、あとはデプロイと、デプロイするためにちょこちょこコードを修正したぐらいです。

まず
Twitter Application Management
でconsumer keyとconsumer secretを取得します。
Name, Description, Websiteを入力します。
この時Websiteはlocalhostだと取得出来ず、実際にあるurlを入力しないといけないようです。
今回はとりあえずこのブログのurlを入力しました。


次は取得したconsumer keyとconsumer secretを使ってaccess tokenとaccess token secretを以下のコードで取得します。

import tweepy

consumer_key = "CONSUMER_KEY"
consumer_secret = "CONSUMER_SECRET"
auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
print("Access:", auth.get_authorization_url())
verifier = input('Verifier:')
auth.get_access_token(verifier)
print("Access Token:", auth.access_token)
print("Access Token Secret:", auth.access_token_secret)

途中で表示されるurlに飛んでPINが表示されるので、それをinputで入力することでaccess tokenとaccess token secretが取得出来ます。

取得したところでリプライから画像を保存するコード

import os
import tweepy
import urllib.request
import datetime


def get_oauth():
    consumer_key = os.environ["CONSUMER_KEY"]
    consumer_secret = os.environ["CONSUMER_SECRET"]
    access_key = os.environ["ACCESS_TOKEN_KEY"]
    access_secret = os.environ["ACCESS_TOKEN_SECRET"]
    auth = tweepy.OAuthHandler(consumer_key, consumer_secret)
    auth.set_access_token(access_key, access_secret)
    return auth


class StreamListener(tweepy.StreamListener):
    def on_status(self, status):
        if status.in_reply_to_screen_name == 'py_kanade':
            print(status.author.screen_name)
            if 'media' in status.entities:
                medias = status.entities['media']
                m = medias[0]
                media_url = m['media_url']
                try:
                    urllib.request.urlretrieve(media_url, 'icon.jpg')
                except IOError:
                    print("保存に失敗しました")
                now = datetime.datetime.now()
                time = now.strftime("%H:%M:%S")
                message = '@' + status.author.screen_name + ' アイコンを変更しました(' + time + ')'
                try:
                    api.update_profile_image('icon.jpg')
                    api.update_status(status=message, in_reply_to_status_id=status.id)
                except tweepy.error.TweepError as e:
                    print("error response code: " + str(e.response.status))
                    print("error message: " + str(e.response.reason))


auth = get_oauth()
api = tweepy.API(auth)
stream = tweepy.Stream(auth, StreamListener(), secure=True)
stream.userstream()

コードはデプロイ前提になっていますが、普通にローカルで試しに動かすぐらいなら、os.environ["KEY"]のところにAPI keyを書いてもおkです。


ではHerokuにデプロイします。

必要なものは上のpythonファイルの他に
index.py
Procfile
requirements.txt
runtime.txt

が必要になります。

index.pyは、どうもこれが無いといけないぽい。
botをデプロイしている人もこんな感じのダミープログラムを入れているので、今はそういうものだと思っている。

import os
from bottle import route, run

@route("/")
def hello_world():
        return "hello world"

run(host="0.0.0.0", port=int(os.environ.get("PORT",5000)))

Procfileは実際に動かすファイルを指定する

web: python edit_icon.py

vimで作りましょう。

requirements.txtは必要なライブラリをまとめて記述したもの
ターミナルで

pip freeze > requirement.txt

で作成可能

bottle==0.12.13
certifi==2018.4.16
chardet==3.0.4
idna==2.6
oauthlib==2.1.0
PySocks==1.6.8
requests==2.18.4
requests-oauthlib==0.8.0
six==1.11.0
tweepy==3.6.0
urllib3==1.22

runtime.txtはpythonのバージョンを記述します。

python-3.6.5

Herokuは3.6.5に対応してないというのを(5月初めぐらいの書き込み)を見ましたが、とりあえず動いてはいます。

これらを準備して、デプロイに取り掛かります。

ここで、もしGitHubにpushするのであれば、GitHubに上げてからの方が楽でした。
HerokuはGitHubリポジトリに接続してAutomatic deployができるのですが、今回は知らなかったためHerokuにデプロイして→GitHubにpush→Herokuに接続というめんどくさいことをしました。


なおHerokuへデプロイするために、twitterAPIキーをプログラムに直接書くのはセキュリティの観点から望ましくないので、Herokuで環境変数に設定する必要があります。

heroku config:set CONSUMER_KEY=XXX CONSUMER_SECRET=XXX ACCESS_TOKEN_KEY=XXX ACCESS_TOKEN_SECRET=XXX

XXXのところに取得したkeyを入力してください。クォーテーションは不要です。
後から環境変数を確認できるコマンドもあるけど忘れた。。。

試しにローカルで動かしてみます

heroku run python edit_icon.py




こんな感じで無事アイコンが変更されました。
やっぱり兼元灯里ちゃんは可愛いです。(知らない人は「のーぶるわーくす」で検索)

ただ、ここで一つ問題としてHerokuは10分ごとにしか起動しないようで、そうなるとこれをデプロイした意味とは・・・
もっと短い時間感覚でデプロイするにはどうしたらいいんでしょうか。。。
AWSとかでできるのか分からないですが、真に自動化出来ている訳では無いので、引き続き調べてみたいと思います。