無料でTwitter Botを運用しよう【GitHub Actions編】

# はじめに
この記事は[長野高専 Advent Calender 2022](https://qiita.com/advent-calendar/2022/nnct) 5日目の記事です．序章なので軽めの内容を...
みなさん，TwitterのBotはどうやって運用していますか？本記事では，GitHub Actionsというのを活用すれば無料でBot運用ができるかもよ！というのを紹介したいと思います．

:::note  warn
Gitの操作，Twitter Botの作り方に関する説明は省略します
:::

# GitHub Actions とは？
> GitHub Actions は、ビルド、テスト、デプロイのパイプラインを自動化できる継続的インテグレーションと継続的デリバリー (CI/CD) のプラットフォームです。
> ― [Understanding GitHub Actions | GitHub](https://docs.github.com/ja/actions/learn-github-actions/understanding-github-actions)

？

GitHub Actionsは，各イベント(pushとかPRとか)が発生したタイミングでソースコードをビルドしたり，クラウドにデプロイしたりするワークフローを実行してくれるサービスです．
このワークフローは独自のYAMLファイルなどを用いて設定しますが，基本的にどのコマンドも用いることができるため，この仕様をうまいこと使用するとTwitter Botだって運用できちゃうわけです．

## 各イベントについて
GitHub Actionsでは様々なイベントが用意されています[^1]．

|||
|-|-|
|`push`|特定のブランチにpushされたとき|
|`pull_request`|特定のブランチに対してPRが完了したときなど|
|`schedule`|特定のスケジュールされた時間|

今回はこの`schedule`を用いて定期実行するBotを作っていきます．

# 宣伝
本記事の方法で運用しているBotです．

https://twitter.com/TLSpacha/status/1599417487816286214?s=20&t=87Ah3Kz2u6P5Y6TNg-tDnA

https://github.com/BonyChops/TLSpacha


# Botを作成する
ではまずBotを作成しましょう．このときのコツとして，DiscordのBotのように実行し続けるものではなく，**1回実行する際の処理を書く**ようにしましょう．

# Actionsを設定する
では、いよいよActionsを設定します。 
 Actionsを使うには、Workflowというものを設定する必要があります。  
`.github/workflow`というディレクトリ(作成してください)にYAMLファイルで実行するコマンド群を書き、これをWorkflowと呼びます。

以下は5分毎に実行するWorkflowの雛形です(もしくは，`test-run`ブランチにpushしても実行されます)。

```yml:.github/workflow/sample.yml
name: Sample Job
"on":
  push:
    branches:
      - test-run
  schedule:
    - cron: "*/5 * * * *"

jobs:
  run_follow_job:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      # ここから書く
```

## 環境を構築する
実行するためにはそのための環境が必要です。Ubuntuで実行する場合はだいたい揃っていますが、**バージョンが古い**です。適切なsetupアクションを呼び出して、最新の環境を使うようにしましょう。  
この記事では有名所だけ載せます。これ以外の言語を用いる際には「GitHub Actions {言語名}」等で調べてください

### Node.jsをセットアップ[^node]
Node.js バージョン`16`を使いセットアップする方法は次のとおりです．
```yaml
      - uses: actions/setup-node@v3
        with:
            node-version: 16
    - run: npm ci
```


### Pythonをセットアップ[^py]
Pythonバージョン`3.10`を使いセットアップする方法は次のとおりです．
```yaml
    - uses: actions/setup-python@v4
    with:
          python-version: "3.10"
    - name: Install dependencies
      run: |
          python -m pip install --upgrade pip
          pip install flake8 pytest
          if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
```

## 実行コマンドを記載する
では、いよいよBotを実行します！  
まず、実行に必要なコマンドをおさらいします。TLSpachaを例にすると、

```sh
node app
```

これをWorkflowに記載すると

```yml
- run: node app
```

のようになります。

```sh
node a
node b
```

のように、複数実行する必要がある場合は

```yml
- run: node a
- run: node b
```

のように記載しましょう。

### Secretsの設定
APIキーや認証情報など、表向きには出せない情報を公開せずにプログラムに流す仕組みがあります。それがSecretsです。

設定は，
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/60f045ab-121d-0ac3-df30-25049687616b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/1f9cb48a-5923-4961-f524-f6de60aa7f42.png)

ここで追加・編集します．追加するときは緑の[New repository secret]です．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/f8e3d07b-7a44-1d58-5952-7cc091cd39dd.png)



:::note

実際は、ここらへんの値を設定してください。
- `TWITTER_API_KEY`: APIキー
- `TWITTER_API_KEY_SECRET`: APIシークレット
- `TWITTER_ACCESS_TOKEN`: アクセストークン
- `TWITTER_ACCESS_TOKEN_SECRET`: アクセストークンシークレット
- `BOT_ID`: BotのID(必要であれば)
:::

```yml
- run: node app
env:
  TWITTER_API_KEY: ${{ secrets.TWITTER_API_KEY }}
  TWITTER_API_KEY_SECRET: ${{ secrets.TWITTER_API_KEY_SECRET }}
  TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
  TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
  BOT_ID: ${{ secrets.BOT_ID }}
```


## 完成
TLSpachaの例です。

```yml:.github/workflows/tweet.yml
name: Tweet Job
"on":
  push:
    branches:
      - test-run
  schedule:
    - cron: "0/5 * * * *"

jobs:
  run_tweet_job:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
        with:
          node-version: 16
      - run: sudo apt install -y fonts-noto-cjk
      - run: npm i
      - run: node app
        env:
          TWITTER_API_KEY: ${{ secrets.TWITTER_API_KEY }}
          TWITTER_API_KEY_SECRET: ${{ secrets.TWITTER_API_KEY_SECRET }}
          TWITTER_ACCESS_TOKEN: ${{ secrets.TWITTER_ACCESS_TOKEN }}
          TWITTER_ACCESS_TOKEN_SECRET: ${{ secrets.TWITTER_ACCESS_TOKEN_SECRET }}
          BOT_ID: ${{ secrets.BOT_ID }}
          DEFAULT_ICON: ${{ secrets.DEFAULT_ICON }}
```

[^node]: [Node.js のビルドとテスト](https://docs.github.com/ja/actions/automating-builds-and-tests/building-and-testing-nodejs)
[^py]: [Python のビルドとテスト | GitHub Docs](https://docs.github.com/ja/actions/automating-builds-and-tests/building-and-testing-python)

[^1]: [Events that trigger workflows | GitHub Actions](https://docs.github.com/ja/actions/using-workflows/events-that-trigger-workflows#schedule)