0
Help us understand the problem. What are the problem?

posted at

updated at

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情報をちゃんと拾えるか確認


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でプッシュメッセージを出したい。

プッシュメッセージのコード

'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 動いたけど思惑と違った

そして出来上がったのがこのコード。
さてうまくいくか・・・

'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

LINE Botよ動け!#2 YouTube動画URLをBotに送りたい

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

'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

ヨガの先生のチャンネルから、ランダムに動画をBotに送りたい

どうやら、Math.randomメソッドとMath.floorメソッドというものが存在するらしい・・・なにこれ:baby:
読むと、画像とかはどうやらMath.randomメソッドの方が向いているらしい。じゃあ私はこっちね。
・・と調べまくったけどこれは時間切れ。今回はスキップ。

LINE Botを週に一回決まった曜日に送ってくるようにしたい

Actionsという処理をしなきゃいけないということで、

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分置きを1週間おきに書き換えなければならい。
しかし!!!ここにものすごく時間がかりタイムアップ・・・

躓いたところ

コードを合体させる時、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がコードの行数であることを知らなかった。
なのでどこがおかしいのかわからず、右往左往。
しかし教えてもらってやっとわかった!
みんな!最後の数字は、エラーの行数よー-っ!

おしまい

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
0
Help us understand the problem. What are the problem?