Github Actions + Pythonで定期的にTwitterのユーザー名を変更する

#はじめに
この記事は[うじまる](https://twitter.com/uzimaru0000)さんの[uzimaru0000/apex_rank_status](https://github.com/uzimaru0000/apex_rank_status)をPythonで書かせていただいたものを記事にしたものです
この記事では[前回の記事](https://qiita.com/hayapo/items/2ade5e149f98ec19afc1)と同様にTRACKER NETWORKのAPIを叩いてApex Legendsのランクポイントを取得し、それをTwitterのユーザー名に反映させます
ランクポイント関連のコードは記事の本質とは異なっているため、コードだけを載せるだけにします
また、__リポジトリを作成している__ことを前提に説明します

このコードの[リポジトリ](https://github.com/hayapo/apex_rank_python)
#参考
[uzimaru0000/apex_rank_status](https://github.com/uzimaru0000/apex_rank_status)

#目次
 - [Twitter APIで名前を変更する](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#twitter-api%E3%81%A7%E5%90%8D%E5%89%8D%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)
    - [Twitter APIの申請](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#twitter-api%E3%81%AE%E7%94%B3%E8%AB%8B)
    - [環境変数](https://qiita.com/drafts/items/1e6f5f1be47c7ea5ddfa/#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0)
    - [使用するライブラリ](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#%E4%BD%BF%E7%94%A8%E3%81%99%E3%82%8B%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA)
    - [ランクポイントを取得する](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#%E3%83%A9%E3%83%B3%E3%82%AF%E3%83%9D%E3%82%A4%E3%83%B3%E3%83%88%E3%82%92%E5%8F%96%E5%BE%97%E3%81%99%E3%82%8B)
    - [ユーザー名を作成する](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E5%90%8D%E3%82%92%E4%BD%9C%E6%88%90%E3%81%99%E3%82%8B)
    - [Twitter APIでユーザー名を変更する](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#twitter-api%E3%81%A7%E3%83%A6%E3%83%BC%E3%82%B6%E3%83%BC%E5%90%8D%E3%82%92%E5%A4%89%E6%9B%B4%E3%81%99%E3%82%8B)

 - [Github Actions](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#github-actions)
    - [環境変数の設定](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%81%AE%E8%A8%AD%E5%AE%9A)
    - [ActionとWorkflow](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#action%E3%81%A8workflow)
        - [Workflowの構造](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#workflow%E3%81%AE%E6%A7%8B%E9%80%A0)
    - [Worflowの作成](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#workflow%E3%81%AE%E4%BD%9C%E6%88%90)
        - [スケジュールの設定](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#%E3%82%B9%E3%82%B1%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A)
        - [環境変数を読み込む](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%80)
        - [リポジトリのチェックアウトとセットアップ](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#%E3%83%AA%E3%83%9D%E3%82%B8%E3%83%88%E3%83%AA%E3%81%AE%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%82%A2%E3%82%A6%E3%83%88%E3%81%A8%E3%82%BB%E3%83%83%E3%83%88%E3%82%A2%E3%83%83%E3%83%97)
        - [Pythonファイルの実行](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#python%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%81%AE%E5%AE%9F%E8%A1%8C)
        - [YAMLコード全体](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#yaml%E3%82%B3%E3%83%BC%E3%83%89%E5%85%A8%E4%BD%93)
 - [成功してるか確認](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#%E6%88%90%E5%8A%9F%E3%81%97%E3%81%A6%E3%82%8B%E3%81%8B%E7%A2%BA%E8%AA%8D)
    - [GithubのActionsを見てみる](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#github%E3%81%AEactions%E3%82%92%E8%A6%8B%E3%81%A6%E3%81%BF%E3%82%8B)
    - [Twitterの名前](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#twitter%E3%81%AE%E5%90%8D%E5%89%8D)
 
#Twitter APIで名前を変更する
##Twitter APIの申請
この記事を参考にしてください
[2020年度版 Twitter API利用申請の例文からAPIキーの取得まで詳しく解説](https://www.itti.jp/web-direction/how-to-apply-for-twitter-api/)
API申請が通ったら、API KEYとアクセストークンを控えておきます

##環境変数
今回はGithub Actionsを使用しているので、リポジトリに環境変数を設定して、それを読み込むようにします
以下の形式で環境変数を設定、使用します

|            名前            |                  中身                  |
| :------------------------: | :--------------------------------------------: |
|          API_KEY           |                TwitterのAPI Key                 |
|       API_SECRET_KEY       |             TwitterのAPI Secret Key             |
|        ACCESS_TOKEN        |              TwitterのAccess Token              |
|    ACCESS_TOKEN_SECRET     |          TwitterのAccess Token Secret           |
|        TRN_API_KEY         |                  TRNのApi Key                   |
|    APEX_USER_IDENTIFIER    |                 Apexのユーザ名                |
| TWITTER_USER_NAME_TEMPLATE | Twitterのユーザー名テンプレート (ex: "hayapo{}") |

##使用するライブラリ
PythonのTwitterのラッパーであるpython-twitterを使用します

```python
import twitter
```
使用する際は[ドキュメント](https://python-twitter.readthedocs.io/en/latest/)を参照すると良し

##ランクポイントを取得する
この説明は[前回の記事](https://qiita.com/hayapo/items/2ade5e149f98ec19afc1)が詳しいです
ここではコードだけ載せます

```python
import requests, json, os
from pprint import pprint
url = "https://public-api.tracker.gg/v2/apex/standard/profile/origin/SIN_HA_JECHT_DA"
header = {"TRN-Api-Key":os.environ['TRN_API_KEY']}#環境変数から読み込むようにしてる

res = requests.get(url, headers=header).json()
```

[uzimaru0000/apex_rank_status](https://github.com/uzimaru0000/apex_rank_status)ではランクポイントからランクに応じた絵文字を名前に付与しています。この記事でも、それを真似したいと思います。

```python:main.py
rank_status = res["data"]["segments"][0]["stats"]["rankScore"]
rank_emoji = apex.set_rankname(rank_status)
rank_point = math.floor(res["data"]["segments"][0]["stats"]["rankScore"]["value"])
```

```python:apex.py
import emoji

Apex_rank = {\
    'Bronze' : emoji.emojize(':3rd_place_medal:'),\
    'Silver' : emoji.emojize(':2rd_place_medal:'),\
    'Gold' : emoji.emojize(':1rd_place_medal:'),\
    'Platinum' : emoji.emojize(':trophy:'),\
    'Diamond' : emoji.emojize(':gem_stone:'),\
    'Master' :  emoji.emojize(':atom_symbol:'),\
    'Predator' : emoji.emojize(':ogre:')\
    }

def set_rankname(rank_status):
    if 0 <= rank_status['value']  < 1200:
        return Apex_rank['Bronze'] #🥉
    elif 1200 <= rank_status['value'] < 2800:
        return Apex_rank['Silver'] #🥈
    elif 2800 <= rank_status['value'] < 4800:
        return Apex_rank['Gold'] #🥇
    elif 4800 <= rank_status['value'] < 7200:
        return Apex_rank['Platinum'] #🏆
    elif 7200 <= rank_status['value'] < 10000:
        return Apex_rank['Diamond']  #💎
    elif 10000 <= rank_status['value']:
        if rank_status['rank'] is not None:
            if rank_status['rank'] <= 750:
                return Apex_rank['Predator'] #👹
            else:
                return Apex_rank['Master'] #⚛️
        else:
            return Apex_rank['Master'] #⚛️
    else:
        return emoji.emojize(':zzz:')
```
##ユーザー名を作成する
上記のコードで、ランクポイントを取得し、ランクに応じた絵文字をセットしました

次に、環境変数の`TWITTER_USER_NAME_TEMPLATE`に絵文字とランクポイントを埋め込みます

```python:main.py
name = env.twitter_user_name_template.replace('{}','{}{}'.format(rank_emoji, str(rank_point)))
```
これでユーザー名の作成は完了です

##Twitter APIでユーザー名を変更する
python-twitterを使用したユーザ名の変更は簡単で、```UpdateProfile```モジュールの**name**の部分に変更したい文字列を指定してあげるだけでいいです

```python:main.py
#apiオブジェクトの作成
api = twitter.Api(consumer_key=env.CK, consumer_secret=env.CS, access_token_key=env.AT, access_token_secret=env.AS)
#UpdateProfileで名前変更
api.UpdateProfile(name=name)
```
これでAPIを使用して名前を変更するコードができました

#Github Actions
次にGithub Actionsにデプロイする方法を説明します

##環境変数の設定
[環境変数](https://qiita.com/items/1e6f5f1be47c7ea5ddfa/#%E7%92%B0%E5%A2%83%E5%A4%89%E6%95%B0)で説明した通りに環境変数を設定します
環境変数を公開したくないので、Secretsを使用して安全に環境変数を使用できます
**Settings**の**Sectrets**に移動し、右上の**New Repository secret**ボタンで環境変数を設定します

こんな感じになったらOK
![スクリーンショット 2021-02-13 234918.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439660/41fa066e-6bd6-b507-7ffe-7288e825af9b.png)

##ActionとWorkflow
Github Actionsでは`.github/workflow`においた`YAML`ファイルで実行したい処理とその条件を定義するだけで簡単にプロジェクトをデプロイできます
環境変数やPythonファイルの実行などの個々のコマンドを**Action**、Actionの流れなどをまとめたものが**Workflow**という認識で大丈夫だと思います
WorkflowはWorkflow構文と言うもので記述します
構文については[公式のドキュメント](https://docs.github.com/ja/actions/reference/workflow-syntax-for-github-actions)を参照してください

###Workflowの構造
Workflowはこのような階層構造になっています

```
Workflow
  └ jobs
    └ jobの名前
      └ steps
        └ Action #個々のアクション
```

##Workflowの作成
Workflowを作成します
`.github/workflow`ディレクトリを作成、そこに`cron.yml`を作成します
以下のコードは`cron.yml`に記述するものです
説明のためまとまったコードごとに分けていますが、最後にまとめたコードを貼っています
###スケジュールの設定
定期的に実行させるためにcrontabコマンドを使用してスケジュールを設定します
Workflowでcrontabコマンドを使うには、`job`と同じインデントレベルにおいて`on`構文で使用します
スケジュールは`分 時 日 月 曜日`で指定します

```yaml
on:
  schedule:
    - cron: '*/15 * * * *'
```

このようにすることで15分ごとにWorkflowが実行されます

###環境変数を読み込む

```yaml
jobs:
  build:
   env:
     API_KEY: ${{ secrets.API_KEY }}
     API_SECRET_KEY: ${{ secrets.API_SECRET_KEY }}
     ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
     ACCESS_TOKEN_SECRET: ${{ secrets.ACCESS_TOKEN_SECRET }}
     TRN_API_KEY: ${{ secrets.TRN_API_KEY }}
     APEX_USER_IDENTIFIER: ${{ secrets.APEX_USER_IDENTIFIER }}
     TWITTER_USER_NAME_TEMPLATE: ${{ secrets.TWITTER_USER_NAME_TEMPLATE }}
```

###リポジトリのチェックアウトとセットアップ
まずリポジトリをチェックアウし、Pythonをインストールします
バージョンを`3.8.7`、アーキテクチャを`x64`に設定しました
今回は外部ライブラリを使用するため`pip`をインストールし、`requirements.txt`の内容をインストールするようにしています
毎回、PyPIにアクセスして依存関係をインストールするのはかっこ悪いので、[actions/cache@v1](https://github.com/actions/cache)を用いて依存関係をキャッシュします

```yaml
jobs:
  build:
   steps:
        #チェックアウト
      - uses: actions/checkout@v2

        #Pythonのセットアップ
      - name: Set up Python
        uses: actions/setup-python@v1
        with:
          python-version: '3.8.7'
          architecture: x64

        #pipのキャッシュ作成
      - name: Cache pip 
        uses: actions/cache@v1
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
          restore-keys: |
            ${{ runner.os }}-pip-

        #pipのインストールと依存関係のインストール
      - name: pip Install
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt
```

###Pythonファイルの実行
あとは実行するだけです

```yaml
jobs:
  build:
   steps:
        #実行
      - name: Run main.py
        run: python main.py
```

###YAMLコード全体

```yaml
name: cron

on:
  schedule:
    - cron: '*/15 * * * *'

jobs:
  build:
    runs-on: ubuntu-latest

    env:
      API_KEY: ${{ secrets.API_KEY }}
      API_SECRET_KEY: ${{ secrets.API_SECRET_KEY }}
      ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }}
      ACCESS_TOKEN_SECRET: ${{ secrets.ACCESS_TOKEN_SECRET }}
      TRN_API_KEY: ${{ secrets.TRN_API_KEY }}
      APEX_USER_IDENTIFIER: ${{ secrets.APEX_USER_IDENTIFIER }}
      TWITTER_USER_NAME_TEMPLATE: ${{ secrets.TWITTER_USER_NAME_TEMPLATE }}

    steps:
      - uses: actions/checkout@v2

      - name: Set up Python
        uses: actions/setup-python@v1
        with:
          python-version: '3.8.7'
          architecture: x64
      
      - name: Cache pip
        uses: actions/cache@v1
        with:
          path: ~/.cache/pip
          key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }}
          restore-keys: |
            ${{ runner.os }}-pip-
      
      - name: pip Install
        run: |
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Run main.py
        run: python main.py
```

#成功してるか確認
##GithubのActionsを見てみる
![スクリーンショット 2021-02-14 012630.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439660/fc598288-5a1b-fcff-0cf7-71af1699b746.png)
ちゃんと出来てる:relaxed:

##Twitterの名前
![スクリーンショット 2021-02-14 012928.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439660/c7f0ed3d-be56-b735-add9-330fcab66dff.png)
できてる:relaxed:

#終わり