【Python】Herokuを使って無料でTwitterBotを作成してみた

#はじめに
アフィリエイターをやっていた頃は、
[Twittbot](https://twittbot.net/)というサービスを使って、Botを量産していたが、
エンジニアになって、自分でもTwitterのBotを作ってみたいなあと思い、挑戦してみました！


#TL;DR
- `Heroku`登録
- `Twitter API`へ申請し、アクセスキー&シークレットを取得
- `git`と`heroku CLI`のインストール
- `Python`パッケージの用意
- `Heroku`にアプリケーションを`Push`&`Build`
- `Heroku`のリポジトリに環境変数の内容をエクスポート
- `Heroku Scheduler`を設定
- 動作確認


#`Heroku`とは
https://jp.heroku.com/what

>Heroku はアプリの構築、提供、監視、スケールに役立つクラウドプラットフォームで、アイデアを出してから運用を開始するまでのプロセスを迅速に進めることが可能です。また、インフラストラクチャの管理の問題からも解放されます。

[Salesforce](https://www.salesforce.com/jp/)が提供するPaaS（Platform as a Service）とのことで、
ざっくりと**アプリケーションを実行するための環境を提供してくれて、アプリ公開に必要な手順を代行してくれるサービス**です。

データベースサーバーや、アプリケーションサーバーなどの環境を簡単に利用できるメリット◎

####無料枠の範囲内であれば、お金はかからないので便利。

#`Heroku`へ登録
こちらから登録できます。
必要情報を記入したら、`[Create Account]`しましょう〜
**登録後に他要素認証、例えば、`Google Authenticator`アプリを使用してログインするなどアカウントの保護をしておくといい**と思います。

https://signup.heroku.com/login

![FireShot Capture 284 - Heroku - Sign up - signup.heroku.com.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/ed24e56d-71a6-a505-8ae3-b8aa9135b950.jpeg)



#`Twitter API`の申請について
Twitter APIを利用するための、「アクセスキー&シークレット」を取得する方法はこちらを参考ください。

https://qiita.com/ichi_zamurai/items/b129b23f048e4ce76b97


#`git`と`heroku CLI`のインストール

###`Homebrew`を事前にインストール
`git`と`heroku CLI`で使います。

```bash
# Reference: https://brew.sh/
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
###`git`のインストール
```bash
# Reference: https://git-scm.com/download/mac
$ brew install git
$ git --version # インストール確認
```
※`Xcode Command Line Tools`がインストールされていなければ、インストールするよう促してくれます。

###`heroku CLI`のインストール
```bash
# Reference: https://devcenter.heroku.com/ja/articles/heroku-cli#download-and-install
$ brew tap heroku/brew && brew install heroku
$ heroku -v # インストール確認
```

#`Python`パッケージの用意
##ディレクトリ構成
```
.
├── .env
├── app
│   ├── post_tweet.py
│   └── settings.py
├── requirements.txt
└── runtime.txt
```
##プログラムコード
###`runtime.txt`
実行環境として、`Python + バージョン`を書きます。

```
python-3.9.4
```

###`requirements.txt`
Twitterつぶやき用に、`tweepy`を使います。
Twitter APIのアクセスキー＆シークレットを`.env`から取得するので、`python-dotenv`を使います。

```
python-dotenv==0.17.1
tweepy==3.10.0
```
###`settings.py`
`.env`ファイルから定数に値セット

```python:settings.py
# coding: UTF-8
import os
from os.path import join, dirname
from dotenv import load_dotenv

dotenv_path = join(dirname(__file__), '.env')
load_dotenv(dotenv_path)

# Twitter API
API_KEY = os.environ.get("API_KEY")
API_SECRET_KEY = os.environ.get("API_SECRET_KEY")
ACCESS_TOKEN = os.environ.get("ACCESS_TOKEN")
ACCESS_TOKEN_SECRET = os.environ.get("ACCESS_TOKEN_SECRET")
```
###`post_tweet.py`
`Auth`情報を取得し、`api`インスタンス作成。ツイート！

```python:post_tweet.py
# -*- coding: utf-8 -*-
import tweepy
import settings

if __name__ == '__main__':
    # Auth: Set Keys & Secrets for Twitter API
    auth = tweepy.OAuthHandler(settings.API_KEY, settings.API_SECRET_KEY)
    auth.set_access_token(settings.ACCESS_TOKEN, settings.ACCESS_TOKEN_SECRET)

    # Generate Api Instance
    api = tweepy.API(auth)

    api.update_status('Twitterつぶやき投稿!!')
```

#`Heroku`でアプリ作成 & `Push`するまで
##`GUI`バージョンの手順

###`[Create New App]`
![スクリーンショット 2021-05-26 16.12.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/a1f37c82-f50c-4a94-1a0c-1b924a668d48.png)

###アプリの情報を入力
![スクリーンショット 2021-05-26 16.13.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/eacc988d-721d-9aa8-7a14-78e47e0ddbcb.png)

###作成したアプリの`Settings`で`Heroku git URL`を取得
`push`先として使えます。
![スクリーンショット 2021-05-26 16.14.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/ba86f549-4116-c97e-2be4-ec63b91f97b4.png)

###`Git Client`でローカルフォルダをGit管理にして、リモートリポジトリと連携
※[Git Fork](https://git-fork.com/)使ってます。

####`File`タブから選択
![スクリーンショット 2021-05-26 16.22.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/37caebd1-e8ae-edce-3ed7-26cfb237a793.png)

####`> Remote`で右クリック
![スクリーンショット 2021-05-26 16.26.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/667cb6ee-39d4-c23b-3897-3c2daa6327e5.png)

####`Test Connection`するといいですねぇ
![スクリーンショット 2021-05-26 16.28.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/0506ec42-38a7-2536-6a0a-c5abdc726dd0.png)

##`Heroku CLI`バージョンの手順
**※`.env`ファイルをプッシュしないように気をつけてください。**

```bash
$ cd /Users/username/src/app # Git管理したいディレクトリに移動 ※usernameとappは任意
$ heroku login # herokuにログイン
heroku: Press any key to open up the browser to login or q to exit: # ブラウザが立ち上がる

$ heroku create app # アプリ作成
Creating app...done
https://app.herokuapp.com/ | https://git.heroku.com/app.git # リモートリポジトリ情報

$ git init # /Users/username/src/appをgit管理
$ git remote add origin https://git.heroku.com/app.git # リモートにorigin追加
$ git add . # /Users/username/src/appをステージに追加
$ git commit -m "app first commit" # ローカルでcommit(コメント付き)
$ git push origin master # originにローカルmasterブランチをpush
```

#`Heroku`のリポジトリに環境変数の内容をエクスポート
`.env`ファイルを用意したら

```bash
$ heroku config:push # 環境変数をHerokuに反映
```
**※デフォルトでは、すでにHerokuに設定した環境変数名と`.env`に書いた環境変数名が同じなら、`Heroku`側の環境変数の値は上書きされない。上書きする場合は`--overwrite`オプションつける。**


#`Heroku Scheduler`を設定
##事前に`Billing`にクレジットカード情報を登録
`Home > Account settings > Billing`
![スクリーンショット 2021-05-26 16.51.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/af2cb8fa-52e4-c37f-739b-93256f07fb08.png)


##`Heroku Scheduler`の`Add-On`を追加
![スクリーンショット 2021-05-26 16.54.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/00fdccbd-5b46-d26e-fb7b-a1b5d624f5c3.png)

####コマンド
```bash
$ heroku addons:add scheduler:standard --app app # アプリ名をappに
```

##`Heroku Scheduler`の設定
すごくシンプルです。
`[Add Job]`を押して、キャプチャのように設定。
コマンドは、`app`ディレクトリに移動させてから、`post_tweet.py`を実行。
自分は１時間おきにしました。
![スクリーンショット 2021-05-26 16.56.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1075243/6309c6e1-7d67-5e17-cd1a-76ceebc1f60d.png)

ただ、かゆいところに手が届かないな〜10分と１時間と１日おきっていう、ざっくり感・・・w


###改善策
実際、`python-crontab`なんかを使えば、`Heroku`のスケジューラーの`Add-On`を使わなくてもできそうだし、
別の方法では、`Procfile`を作成して、その中に`clock: cd ./app && python post_tweet.py`という記述してルートディレクトリに`Procfile`をPush。`heroku clock=1`みたいに指定して実行すれば、`cronjob`を設定できるみたいだ。

そうすれば、もっと細かく定期実行の間隔をコントロールできるようになるから、
今後、制御してみたいと思います〜。

####▼`Heroku x Cronjob`の参考

https://saqibameen.com/deploy-python-cron-job-scripts-on-heroku/


#ハマったポイント
- `homebrew`が古くなっていて、アップデートしたところ、芋づる式で、`GNU Compiler Collection`のインストール、`Xcode Command Line Tools`のアップデートなどが走り、意外とスムーズには行かなかった。
    - terminalに出力される情報の確認が大切だった。
- `runtime.txt`と`requirements.txt`をルート（ディレクトリのトップ）に置いておかないと、`push`後に走る`heroku`のビルドでエラーが出た。
- いつもGitクライアントをメインで使っているので、ターミナルでコマンドで`git commit`したら、`.env`ファイルも間違ってコミットしてしまい、一回`git rm`する必要があった。
    - 後処理が若干面倒だった。
- `Scheduler`でコマンド指定した時に、リポジトリのルートディレクトリから`cd ./app`してからじゃないと、自分の記述した`Python`ファイルの相対パス的に実行ができなかった。
    - 実行したい`Python`ファイルをルートに置くか、`cd ./app`の選択肢
    - `python ./app/post_tweet.py`は`import`の参照エラーが起こった。
        - なかなか`python`の参照はむずい。という結論

#まとめと感想
初めて、`Heroku`と聞いた時に、なにそれヘロヘロやんって思ったけど、

>Herokuの名称は、「heroic（英雄的な）」と「haiku（俳句）」からなるかばん語である。 日本語の名詞を含めているのは、Rubyの開発者のまつもとゆきひろに敬意を示してのことである。
参照元：[wikipedia](https://ja.wikipedia.org/wiki/Heroku)

らしい。俳句、、、TwitterのBot量産しろってか？！wwwwwww

また、`Heroku`自体が、Gitリポジトリだったのが、正直驚いた。
アップしたアプリケーションを定期実行したり、他の用途にも使ったり、可能性は無限大であることを知りました。

いや〜奥が深そうなので、もうすこし`Heroic`な`Haiku`の世界に飛び込んでみたいところですねえ！

ちなみに、今回作った`Twitter BOT`は、本田圭佑っぽいつぶやきをするBOTですwww
本田AIが圭佑ばりにツイートし続けますwww

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">悔しくてしょうがなかった。それが夢ってやつです。</p>&mdash; 本田圭佑っぽいBot (@k_honda_bot89) <a href="https://twitter.com/k_honda_bot89/status/1396846250742489089?ref_src=twsrc%5Etfw">May 24, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



参考までにwww

https://qiita.com/ichi_zamurai/items/60d2480edcb68a76aeb6

以上、ありがとうございました！