LINE Bot&Youtube API／ヨガレッスンに行けなくても、皆でおうちレッスンできるBot

 # 背景
大好きなヨガの先生のYoutube動画が送られてくるLINE Botを、ヨガクラスのみんなでシェアしたら、仕事でレッスン行けなくても家でレッスンしよう、送られてきたらそれぞれ家でやろう、って気になれそう！と思って作りました。
家だとだらけてやらないんですよね・・・でもクラスのみんなも同じBot見てると思うとモチベーション上がる。
 # 環境
node version v17.6.0
npm 8.5.1
 # まずはYoutubeでAPIキー取得
Googleのアカウントさえ持っていればすぐできる。
私が参考にしたのはこちらの方の記事↓
https://qiita.com/shinkai_/items/10a400c25de270cb02e4

無事取得できたので、今度はいよいよコード・・・・ふう・・・

 # まず、YouTubeからAPI情報をちゃんと拾えるか確認

```js

const axios = require('axios');

const handleEvent = async (event) => {

let response;
try {
    const YoutubeAPIKey = '××××××××××××'
  response = await axios.get('https://www.googleapis.com/youtube/v3/search?type=video&part=snippet&q=' + encodeURIComponent('宮城由香') + '&key=' + YoutubeAPIKey);
  console.log(response.data.items[0]);
} catch (error) {
  console.error(error);
}
}

handleEvent()

```


ターミナル無事作動。
さて次は、LINE Botでプッシュメッセージを出したい。
 # プッシュメッセージのコード

```js
'use strict';
const axios = require('axios');
const line = require('@line/bot-sdk');

const config = {
    channelSecret: 'XXXXXX',
    channelAccessToken: XXXXX
};
const client = new line.Client(config);

const main = async () => {
    const url = "XXXXXX"

    const response = await axios.get(url);
    const messages = [{
        type: 'text',
        text: response.data[0].q
    },

    {
        type: 'text',
        text: response.data[0].a
    }];
    try {
        const res = await client.broadcast(messages);
        console.log(res);       
    } catch (error) {
        console.log(`エラー: ${error.statusMessage}`);
        console.log(error.originalError.response.data);
    }
}

main();

```

これをベースに、さっきのAPIから拾うコードをヨガの先生の動画URLだけを拾う指示を出して合体させてればいいはず・・・きっとそれでいいはず・・・

ちなみにYoutube APIのURLにあたるのは、`channelId`。
これを拾ってね！とコード上で指示を出せば、ヨガの先生の動画のURLがBotに来るはず。


 # コードを合体。LINE Botよ動け！#1 動いたけど思惑と違った
そして出来上がったのがこのコード。
さてうまくいくか・・・

```js
'use strict';
const axios = require('axios');
const line = require('@line/bot-sdk');

// Messaging APIを利用するための鍵を設定します。
const config = {
    channelSecret: '×××××××',
    channelAccessToken: '×××××××'
};
const client = new line.Client(config);
//
// const handleEvent = async (event) => {

//     let response;
//             //YoutubeAPIKey取得
//         const YoutubeAPIKey = '×××××××'
//       response = await axios.get('https://www.googleapis.com/youtube/v3/search?type=video&part=snippet&q=' + encodeURIComponent('宮城由香') + '&key=' + YoutubeAPIKey);
//       console.log(response.data.items[0]);
// }
    
// handleEvent()

//
const main = async () => {
    let response;
            //YoutubeAPIKey取得
        const YoutubeAPIKey = '×××××××'
      response = await axios.get('https://www.googleapis.com/youtube/v3/search?type=video&part=snippet&q=' + encodeURIComponent('宮城由香') + '&key=' + YoutubeAPIKey);
      console.log(response.data.items[0]);
    const messages = [{
        type: 'text',
        text: response.data.items[0].snippet.channelId
    }];

    //https://www.youtube.com/watch?v=
try {
    const res = await client.broadcast(messages);
    console.log(res);        
} catch (error) {
    console.log(`エラー: ${error.statusMessage}`);
    console.log(error.originalError.response.data);
}
}

main();
```
動いた！！！が、私が欲しいのはURLリンク！
テキストで来てしまった。
（でもコードはテキストが来るように書いてしまっているので、ある意味正しい）
 # 実際のBotの様子 #1
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">LINE BotにURL出したかったのにテキスト出しちゃった。でもコードは正しい。<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/API?src=hash&amp;ref_src=twsrc%5Etfw">#API</a> <a href="https://twitter.com/hashtag/LINEMessagingAPI?src=hash&amp;ref_src=twsrc%5Etfw">#LINEMessagingAPI</a> <a href="https://twitter.com/hashtag/LINEDC?src=hash&amp;ref_src=twsrc%5Etfw">#LINEDC</a> <a href="https://twitter.com/hashtag/LINEbot?src=hash&amp;ref_src=twsrc%5Etfw">#LINEbot</a> <a href="https://twitter.com/hashtag/YouTube?src=hash&amp;ref_src=twsrc%5Etfw">#YouTube</a> <a href="https://t.co/ynAaAEo7Ce">pic.twitter.com/ynAaAEo7Ce</a></p>&mdash; __7ENDO__ (@__7ENDO__) <a href="https://twitter.com/__7ENDO__/status/1509135746774728708?ref_src=twsrc%5Etfw">March 30, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

 # LINE Botよ動け！#2 YouTube動画URLをBotに送りたい
どうすればURLになるのか。
調べたら、Youtubeの動画のすべてのURLの頭についているコレ↓
`https://www.youtube.com/watch?v=`
をコードにあたる部分（今回はchannelID）入れればよいらしい、ということが判明。
よしよし、おけー。


```js
'use strict';
const axios = require('axios');
const line = require('@line/bot-sdk');

// Messaging APIを利用するための鍵を設定します。
const config = {
    channelSecret: '×××××××',
    channelAccessToken: '×××××××'
};
const client = new line.Client(config);
//
// const handleEvent = async (event) => {

//     let response;
//             //YoutubeAPIKey取得
//         const YoutubeAPIKey = '×××××××'
//       response = await axios.get('https://www.googleapis.com/youtube/v3/search?type=video&part=snippet&q=' + encodeURIComponent('宮城由香') + '&key=' + YoutubeAPIKey);
//       console.log(response.data.items[0]);
// }
    
// handleEvent()

//
const main = async () => {
    let response;
            //YoutubeAPIKey取得
        const YoutubeAPIKey = '××××'
      response = await axios.get('https://www.googleapis.com/youtube/v3/search?type=video&part=snippet&q=' + encodeURIComponent('宮城由香') + '&key=' + YoutubeAPIKey);
      console.log(response.data.items[0]);
    const messages = [{
        type: 'text',
        text: `https://www.youtube.com/watch?v=DZ7sby9-Id8{response.data.items[0].snippet.channelId}`
    }];

    //`https://www.youtube.com/watch?v=fADXsTe05zs&t=25s${data.items[0].snippet.channelId}`
    //https://www.youtube.com/watch?v=
try {
    const res = await client.broadcast(messages);
    console.log(res);        
} catch (error) {
    console.log(`エラー: ${error.statusMessage}`);
    console.log(error.originalError.response.data);
}
}

main();
```
 # 実際のBotの様子 #2
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">URLきたあああ！！！ゆか先生ー－！<a href="https://twitter.com/hashtag/protoout?src=hash&amp;ref_src=twsrc%5Etfw">#protoout</a> <a href="https://twitter.com/hashtag/API?src=hash&amp;ref_src=twsrc%5Etfw">#API</a> <a href="https://twitter.com/hashtag/LINEMessagingAPI?src=hash&amp;ref_src=twsrc%5Etfw">#LINEMessagingAPI</a> <a href="https://twitter.com/hashtag/LINEDC?src=hash&amp;ref_src=twsrc%5Etfw">#LINEDC</a> <a href="https://twitter.com/hashtag/LINEbot?src=hash&amp;ref_src=twsrc%5Etfw">#LINEbot</a> <a href="https://twitter.com/hashtag/YouTube?src=hash&amp;ref_src=twsrc%5Etfw">#YouTube</a> <a href="https://t.co/3GJrN2vkr0">pic.twitter.com/3GJrN2vkr0</a></p>&mdash; __7ENDO__ (@__7ENDO__) <a href="https://twitter.com/__7ENDO__/status/1509142591237140480?ref_src=twsrc%5Etfw">March 30, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# ヨガの先生のチャンネルから、ランダムに動画をBotに送りたい
どうやら、Math.randomメソッドとMath.floorメソッドというものが存在するらしい・・・なにこれ:baby:？
読むと、画像とかはどうやらMath.randomメソッドの方が向いているらしい。じゃあ私はこっちね。
・・と調べまくったけどこれは時間切れ。今回はスキップ。

# LINE Botを週に一回決まった曜日に送ってくるようにしたい
Actionsという処理をしなきゃいけないということで、
```js
name: LINEにPushする

on:
  schedule:
  - cron:  '*/5 * * * *'
  # 5分ごと # ここだけ変更

jobs:
  build:

    # このジョブのために ubuntu サーバーを準備する
    # まっさらなサーバーなので、以下で Node.js 自体の準備や npm install を行う
    runs-on: ubuntu-latest

    # Node.js17.x系で実行
    strategy:
      matrix:
        node-version: [17.x]

    # 以下が実際のステップ
    steps:

    # この例では、v2 を使用することにより、チェックアウトアクションの安定版を確実に使用するようにしています
    - uses: actions/checkout@v2
    # Node.js 17.x のセットアップ
    - name: Use Node.js 17.x
      uses: actions/setup-node@v1
      with:
        node-version: '17.x'
    # package.json を参考にNode.jsモジュールのインストールがはじまる   
    - name: npm install command
      run: npm i
    # Node.js 自体の準備や npm install ができたので、いよいよ node actions.js でプログラムを実行
    # LINE Notify にメッセージが行く
    - name: LINE連携を実行
      run: node actions.js

```
この5分置きを１週間おきに書き換えなければならい。
しかし！！！ここにものすごく時間がかりタイムアップ・・・


# 躓いたところ
コードを合体させる時、responseを定義していなくて、
`eError: Cannot access 'response' before initialization`
というエラーがターミナルに出た。
なるほど、と、ここは慌てず
`let response;`
という宣言を入れてクリア。
が、今度は
`ReferenceError: response is not defined`
と。
この時私は、ターミナルのエラーの読み方をちゃんとわかっていなくて、
`ReferenceError: response is not definedat main (C:\Users\××××\OneDrive\スクトップ\01-line-bot\youtube4.js:31:15)`
この最後の31と15がコードの行数であることを知らなかった。
なのでどこがおかしいのかわからず、右往左往。
しかし教えてもらってやっとわかった！
みんな！最後の数字は、エラーの行数よー－っ！


おしまい