Github Actionsを使ってYoutubeの再生回数を自動採取＆ログ作成をやってみたら苦労した話

## はじめに 

YoutubeのAPIを使って動画の再生回数を取得できてうれしくなって、最初は取得するたびにCSVファイルにしてたけど、データ集まるにつれこいつらを自動的にまとめられんものかと考え始めました。
しかしただ単純にCSVにデータを追加するのもツマラナイし、対象の動画が複数あるのでCSVにするにはどうするべきかと考えていた中で、コロナで大騒ぎしてたときの感染者数や、その他オープンデータとして国、都道府県、自治体から公開されてたjsonファイルでログに残すのがいいんじゃないかと考えました。

表題に「苦労した話」とありますが、その原因は私が初心者でGithub界隈の知識が非常に薄いためだったってことで、これから書く内容に辿り着くまでの試行錯誤はそのせいだと最初に書いておきます。そんな試行錯誤を並べると長くなるから今回は割愛しとりますけど。

## jsonファイルについては別記
よくわからないまま始めたjsonファイルの作成ですが、データの追記が簡単で利用時には便利なフォーマット（スキーマ？）をひねり出すのに一苦労したんですが、これについてはまた別の機会に書きたいと思ってます。
今回はそれで作ったファイルをGithub Actionsをつかってリポジトリにpushすることが目的なのです。

## とりあえずGithub Actionsを動かしてみる
Github Actions(以下、Actions)は様々なきっかけで自動的に処理を実行してくれるGithubが無料で提供するサービスですが、詳しいことは各自ググってください。

そのActionsを実行させるにはymlファイルが必要ですので作りましょう。

ファイルの保存場所は
```
リポジトリ/.github/workflows/
```
です。

まずは私が作ったymlファイルを載せときます。

```
# ワークフロー名
name: youtube_data_get

# 発火タイミング
on:
  schedule:
    - cron: '45 13 * * *'
  workflow_dispatch:
jobs:
  build:
    # Ubuntuの最新版環境内で処理
    runs-on: ubuntu-latest

    # 実行する処理＆コマンド指定
    steps:
      - uses: actions/checkout@v3
      - name: Set up Python 3.11
        uses: actions/setup-python@v3
        with:
          python-version: 3.11
      - name: Install dependencies
        run: |
          # pip更新
          python -m pip install --upgrade pip
          # 必要なパッケージインストール
          pip install requests
          pip install google_api_python_client
      - name: Run script
        env:
          youtube_key : ${{ secrets.youtube_key }}
        run: |
          # pythonコードの実行
          python youtube_data_get.py
          # githubリポジトリへファイルをpushする
          git config --global user.email "abcd@efg.com"
          git config --global user.name "washi_washi"
          git add data.json
          git commit -m "json commit"
          git push
```

色々と書いてあるけれど、今回やりたかったことのポイントは

      - name: Run script
        env:
          youtube_key : ${{ secrets.youtube_key }}
        run: |
          # pythonコードの実行
          python youtube_data_get.py
          # githubリポジトリへファイルをpushする
          git config --global user.email "abcd@efg.com"
          git config --global user.name "washi_washi"
          git add data.json
          git commit -m "json commit"
          git push

の部分です。

        env:
          youtube_key : ${{ secrets.youtube_key }}
は、pythonで書いたスクリプト内で、YoutubeのAPIを使うための自分のキー情報をこのレジストリの秘密の環境変数に設定しているので、そいつを参照している部分です。

${{ secrets.youtube_key }} の 'youtube_key'が環境変数に設定した秘密キーの名前です。

以降は実際には処理を実行している部分です。
```
        run: |
          # pythonコードの実行
          python youtube_data_get.py
          # githubリポジトリへファイルをpushする
          git config --global user.email "abcd@efg.com"
          git config --global user.name "washi_washi"
          git add data.json
          git commit -m "json commit"
          git push
```
```
python youtube_data_get.py
```
ここで youtube_data_get.py　という名前をつけたpythonスクリプトを実行させてます。さっきの環境変数はこいつの中で参照しています。
```
api_key = os.environ['youtube_key']
```
os.environ['youtube_key']　の 'youtube_key' は先にyml内で取得した環境変数をセットした変数名です。secretsな環境変数は暗号化されていて、処理中その他で内容を確認することができませんのでパブリック指定のリポジトリでも安心して扱えます。
（ためしにPrintしていましたが、***とのみ表示されました）

で、それ以下に並んでいるgitがリポジトリにファイルをpushする一連の処理です。

```
          git config --global user.email "abcd@efg.com"
          git config --global user.name "washi_washi"
```
ここで自分の身分を明かすっぽいです。Github登録時に設定した自分のメールアドレスと名前を書いといてください。
```
          git add data.json
          git commit -m "json commit"
          git push
```

先に実行されたyoutube_data_get.pyではパスの指定がよく分からなかったから、いちばんカンタンなルートにjsonファイルを書き出すようにしています。
自分の身分を明かしたら、gitコマンドで続いてルートに作成済みのファイル（この場合はdata.json）を add　して、次に commitして、最後に push　とそのまま書けば、Actionsを実行したリポジトリのルートにdata.jsonがpushされているはずです。
（commit -m の後ろはコメントなので何でもヨイです）

ymlファイルの上の方には、時間になれば自動実行するような記述もありますが、この時間指定はUTCであること、30分程度遅れるのは当たり前な指定した時間通りに動いた試しがないこと（無料ユーザだから？）などありますので、やってみたい人は調べてみてください。私がそれについて前に書いた記事のリンクを貼っときますね。

https://qiita.com/tonytani37/items/3e82e89c7cdfd1353d01

## 忘れがちで重要な事

gitコマンドでpushするにはworkflowでリポジトリへアクセスする場合の許可を読み込みと書き込みの両方許可しとかなければなりません。初期値は読み込みのみ許可（のハズ）です。

![スクリーンショット 2023-09-24 1.58.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/5ac846ad-d98b-d9a1-9a7e-271764412613.png)
ActionsのGeneralを選択すると出てくるページの下の方、Workflow permissionのRead and write permissionsを選択して、その下にあるSaveボタンを忘れずにクリックしておいてください。

それからもう一個、作成してpushされたjsonファイルをurlから参照して処理する別のスクリプトをGoogle Colabo上で書いてみた時、リポジトリがprivateの場合、ファイルが更新されるたびに参照用URLが変更されるってことがわかりました。リポジトリがpublicの場合は固定されるのでそのような事はありません。

ならばリポジトリをpublicにするしかない、でもそうするとYoutube　API用のキーが丸見えになってしまう。（そういった情報が含まれるリポジトリをpublicにすると、Google先生から「あぶないよ」っていうメールが来ますし。

そんなことを悩んでるうちに、環境変数が使えまいかとググったら使えることが判明したので一安心。で、上に書いたような環境変数を参照させることで、pubulicにしてもその内容を見ることはできなくなったのでした。


![スクリーンショット 2023-09-24 1.57.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1739706/e859259f-9bbf-e5d9-e183-f5468a79dd71.png)

settingのSecrets and variablesのActionsを選択すると出てくる画面です。
例では YOUTUBE_KEYという名前でAPIキーを登録しています。Secretsは一度登録すると後で確認することができません。

## さいごに
Actionsについては、Twitter botを作ったときに多少触ってみたけれど、写経したあとに多少手直ししただけで、その内容をあまり詳しく理解していませんでした。

で、今回はその時のymlファイルをもとに、どうやってリポジトリにpush出来るかの試行錯誤した結果です。
いろんな方がいろんなやり方で同じことを実現されていましたが、ググったりchatGTPったり、Bardったりしながら、失敗を重ねつつなんとかカッコがついたカンジですね。
Github Actionsはworkflowの実行が失敗すると「失敗してるよー」っていう注意喚起なメールが届くのですが、一時期それだけで何十通も届いたりして驚いたりもしましたけど。

Actionsを制御するymlファイルの構造自体はそれほど難しくはなくて、dockerみたく（実際にコンテナを立ち上げてるんじゃないかな）ubuntuの環境上に構築したpython環境に関連ライブラリをインストールしたあと普通にpythonのスクリプトを動かすだけですので、流れややってることは見ればわかります。その立ち上げたActionsの環境は実行完了後には(ymlファイルの最後まで処理が完了したら）消えてなくなりますので、その中で作られたファイルもそのタイミングで消えてしまうわけです。それをなんとか消えない前にリポジトリにpushするにはどうするか色々と考えた結果書いたのがが今回のymlファイルでした。

最初はpythonスクリプトのなかで処理出来ないかとか、なんならgithubは止めてGCP Strageにアップしようかとか、そうすると認証とかまた色々とめんどくさいな、とか様々なアイディアが浮かんでは消えていきました。
そんななかAIくんたちが教えてくれたgitコマンドがymlファイルに書いてみたら果たして動くのかどうか？

まあよくわからんけどやってみたら一発で上手く行ってラッキーでした。Actionsが正常終了したあと、開いたリポジトリにjsonファイルを見つけたときには思わず手を叩いて喜びました。

やりたいことに関してなかなかまとまった資料が見つからず、GithubのGUI画面は英語の説明ばかりでなんだかよくわからないなりにもGoogle先生(Bardも含む）とBing先生たちに助けられ、数多の先人が残した知恵を拝借しつつ、断片をかき集めた結果としてなんとかなりました。

これから同じようなことをちょっとやってみようかななんて思ってる人たちの、特に私と同じ初心者の皆さんのやりたいことが実現出来るまでの苦労を少しでも軽減できればそれに勝るシアワセはございません。

読みづらい文章はいつもの事で、どうもすみません。