TwitchAPIとGASで配信通知bot作ってみた

こんにちは。
Twitchの配信のゲームカテゴリー単位の配信通知を受け取る方法が欲しくなり、自分にピッタリしたのがなさそうなので自作することにしました。
その時のメモを書いていきます。

# やったこと。
大まかにやってみたのは以下のことです。

+ Twitch Developers にアプリケーション登録
    + client id 取得
    + token取得
+ API動作確認
+ discordのwebhook取得
+ GASでガスガス書いていく
+ GASのトリガー設定

これらに興味があれば参考になるかと思います。

# Twitch Developers にアプリケーション登録
まずはAPI叩いて遊ぶための client id と token 取得します。
そのためにまずはログインして登録して、という作業をします。

ログインの場所→ [https://dev.twitch.tv/login](https://dev.twitch.tv/login) 

## client id 取得
認証やらなんやらを済ませたら、ここ（下画像参照）からアプリケーション登録をおこない、client id を取得します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282077/9477eddb-8425-80a5-954f-2011a2f6fb59.png)

登録時、とりあえずリダイレクトURLは http://localhost にしておきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282077/b80de93f-09c2-98b0-b7c8-7b73ed1335a8.png)

登録時、何度かエラーが出たのですが、アプリ名が被ってたのか妙に長かったからなのか・・・何度か名前を変えてトライしたら登録できました。
成功すると、client id が発行されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282077/7dca41a8-641c-880d-3c62-9199c6449a41.png)


## token取得
次に、tokenを取得します。

```
https://id.twitch.tv/oauth2/authorize?client_id=(取得したclitent id)&redirect_uri=http://localhost&response_type=token&scope=bits:read
```

途中色々アラートとか出ますが、最終的に、ブラウザのURLにトークンが出てきます。
ここの、**token=XXXXX&なんちゃら** の、token=以降&の手前をメモ保存しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282077/899c3e19-f031-87af-d4ec-c2e1b3fa591a.png)

# API動作確認
早速試してみます。

```terminal:コマンド
curl -X GET https://api.twitch.tv/helix/games?name=NieR%3A%20Automata -H 'Client-ID: (取得したclitent id)' -H 'Authorization: Bearer (取得したtoken)' 
```

```json:結果
{"data":[{"id":"494162","name":"NieR: Automata","box_art_url":"https://static-cdn.jtvnw.net/ttv-boxart/./NieR:%20Automata-{width}x{height}.jpg"}]}
```

とりあえずこれで、欲しいゲームのgame id を取得していきます。

また、以下の要領で、配信リスト取得テストもしてみます。

```terminal:コマンド
curl -X GET https://api.twitch.tv/helix/streams?game_id=494162 -H 'Client-ID: (取得したclitent id)' -H 'Authorization: Bearer (取得したtoken)
```

``` json:ざっくり結果
{
    "data": [
        {
            "id": "1111111111",
            "user_id": "000000",
            "user_login": "userid",
            "user_name": "username",
            "game_id": "494162",
            "game_name": "NieR: Automata",
            "type": "live",
            "title": "Live Title",
            "viewer_count": 13,
            "started_at": "2021-10-22T00:00:00Z",
            "language": "en",
            "thumbnail_url": "",
            "tag_ids": [
                "6ea6bca4-4712-4ab9-a906-e3336a9d8039",
                "d0976a7e-26a7-4a48-9225-c522808540f2"
            ],
            "is_mature": false
        },
    ],
    "pagination": {
        "cursor": "NAGAIYO...."
    }
}
```

# discordのwebhook取得
取得もとの目処がついたので、通知先の段取りとして、discordのwebhookを取得します。
discordのチャンネルから**チャンネルの編集**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282077/a7ceac0e-a5cf-82d5-b5d3-d66bb2136c2e.png)

連携サービス→ウェブフックを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282077/b3012357-b10c-0b70-9118-d2e71042f7d1.png)

作成されたwebhookをコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282077/d52f76bc-6548-59c7-219f-690d356cdf1d.png)
この画面の「ウェブフックをコピー」ボタンを押すことで、webhookを取得できます。

# GASでガスガス
とりあえずこれで一通りの情報は揃ったので、GASにガスガス書いていきます。
雑ですが、こんな感じ。

```js:notification
var INTERVAL = 30; // トリガーの時間と大体同じくらいに。30分に1回程度
var CLIENTID = 'XXXXXXXXXXX';
var TOKEN= 'XXXXXXX';

function notification() {
  var gamelist = getGameList();
  for(i=0;i < gamelist.length;i++) {
    var res = sendHttpPost(gamelist[i][0]);
    var lives = JSON.parse(res.getContentText());
    for(var j = 0; j < lives["data"].length; j++){
      var live = lives["data"][j];
      if(live["type"] != "live") continue; // live配信じゃないのは見ない
      var d = new Date();
      d.setMinutes(d.getMinutes()- INTERVAL) ; // 多少のラグはもうみない（めんどくさい）
      var startedat = new Date(live["started_at"]);
      if(d.getTime() > startedat.getTime() ) continue;
      var fields = new Array();
      var fields= {
        'name': live["title"],
        'value': "category: " + gamelist[i][1]  + " streamer: " + live["user_name"],
        'inline': true
        };
       var posts ={
         "embeds": [ {
            "color": 7506394,
            "fields": new Array(fields)
            } ] ,
          "content": "https://www.twitch.tv/" + live["user_login"],
         };
      postDiscord(posts);
    }
  }
}
/**
 * discord にポスト
 */
function postDiscord(text) {
  var url = 'https://discord.com/api/webhooks/XXXXXXXXXXXX';// discordwebhook
  var params = {
    'method': 'POST',
    'headers': { 'Content-type': 'application/json' },
    'payload': JSON.stringify(text)
  };
  UrlFetchApp.fetch(url, params);
};

/**
 *  game list
 */
function getGameList(){// そのうちリスト増やす
  var ret= new Array();
  ret.push(Array(
      "494162",
      "NieR: Automata",
  ));
     return ret;
};
/** 
* Twitch category単位で配信中リストを取得
*/
function sendHttpPost(gameid){
  var endpoint = "https://api.twitch.tv/helix/streams?game_id="+gameid;
  console.log("endpoint::" + endpoint);
   var payload =
   {
     "game_id" : gameid
   };
  var headers =
  {
    'Client-ID': CLIENTID,
    'Authorization' : "Bearer "+ TOKEN
  }
   var options =
   {
     "method" : "get",
     "headers" : headers
   };
   var res = UrlFetchApp.fetch(endpoint, options);
   return res;
}

```

# GASのトリガーの設定
とりあえず、30分に1回ペースで実行してくれれば良いかな、ということで、時間主導型30分おきに設定しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/282077/9bea33f9-5d74-7261-f031-e2489b42c090.png)

# おわりに
## 感想
[Twitch API](https://dev.twitch.tv/docs/api/reference) には今回利用したもの以外も面白いものが多数用意されているので、欲しいものが良い感じで作れそうな感じです。

## 参考記事
以下の記事をもとにコードを実際に書いていきました。
大変感謝しております。ありがとうございます。

- [Twitch の配信開始を通知する Webhook を登録しそこから Twitter に流すやつ（非アプリ）](https://qiita.com/azumag/items/4575c8147585c329fdf5)
- [Twitch APIを利用してみよう](https://qiita.com/pasta04/items/750d71d41e5edd12932b)
- [Google Apps ScriptからHTTP POST](https://qiita.com/n0bisuke/items/a31a99232e50461eb00f)
- [Google Apps Script UrlFetchApp で Http Header を設定する](https://www.monotalk.xyz/blog/google-apps-script-urlfetchapp-%E3%81%A7-http-header-%E3%82%92%E8%A8%AD%E5%AE%9A%E3%81%99%E3%82%8B/)