Slackへ定期的にYouTube動画をpostするSlack AppをGASでつくった記録
はじめに
最近個人用Slackチャンネル作ったはいいが特に投稿もなくて寂しいので勝手にいい感じのYouTube動画をおすすめしてくれるようなSlack Appを作りました。半ば個人的な備忘録になります。Slackへ定期的にYouTube動画をpostするSlack AppをGASで作りたい人には参考になるかもしれません。
コードだけ見たい場合はこちら。
GASでコード管理
GASの定期実行トリガーが使いたかったので、今回はGASで開発してみます。
本筋とはあまり関係ありませんが、GASのコードをWebエディタ以外で管理できるclaspというツールがリリースされていました。
今回はwindowsにclaspを入れ、clasp pull
およびclasp push
できる環境を整えましたが、デバッグするたびにclasp push
するのがめんどいのでローカルで開発する気にはあまりなりません。ソースをGit管理するときに使うとよさそうです。
使い方はこのあたりを参考にしました。
GASでyoutube APIを使うまで
今回はYouTube Data API (v3)を使うのですが、GASであれば割合簡単に導入することができます。
GASのメニューからリソース
> Googleの拡張サービス
で有効化するライブラリを選択できるので、この中からYouTube Data APIをv3で有効にしましょう。
画像ではなぜかON/OFFスイッチが崩れているんですが気にしません。また、モーダル下部に書かれている通り、Google Cloud Platform APIダッシュボードでも該当のAPIを有効にしておきます。
これでYouTube Data APIをGASから簡単に扱えるようになりました。今回は関連動画の検索を行うためにこんな感じで呼び出しています。
var results = YouTube.Search.list("id,snippet",{ type: "video", relatedToVideoId: videoId, maxResults: 5, });
参考にした記事はこちら。
SlackのIncoming Webhooksで定期実行
Slackにpostする処理
BotからSlackにpostさせるため、新規にSlack Appを作成し、GASからIncoming Webhooksに対してリクエストを送るようにします。
Slack API: Applications | SlackからCreate New App
で新しいAppを作成しましょう。
作成したらAppの設定ページからIncoming WebhooksをActivateし、Add New Webhook to Workspace
を押してチャンネルを選択すると、該当のチャンネルにpostするWebhookが生成されます。
これを利用して、Slackにpostする関数を作りました。
function sendSlack(message) { var postData = { "text": message }; var payload = JSON.stringify(postData); var options = { "method": "post", "contentType": "application/json", "payload": payload }; UrlFetchApp.fetch(endPoint, options); }
ちなみにWebhookのエンドポイントはコードの中に直接書きたくないので、ユーザープロパティを利用して呼び出しています。GitHubのコードをそのまま使う場合はユーザープロパティTUBE_NOTIFIER_ENDPOINT
に先程生成したURLを入れておいてください。
Slackからチャンネルの投稿を取得する処理
今回のAppはおすすめ動画を選定する基準として、チャンネルで直近postされたYouTube動画のURLをもとに、その関連動画を検索してpostします。これにより、関連する動画を延々と見ていったり、関連動画が気に入らなかったら手動で別の動画のURLをpostすることでおすすめする動画の方向を修正したりできるという算段です。
ただ、これを実現するためにはSlackからチャンネルの投稿を取得するAPIを利用する必要があります。これは現在Botアカウントからは利用できないようで、Bot User token
ではなくUser token
が必要です。
Legacy tokens | Slackからトークンを生成し、これを利用します。
先ほどと同様にユーザープロパティのTUBE_NOTIFIER_TOKEN
にトークンを格納し、getLastVideoId
関数を作成しました。
function getLastVideoId() { var url = "https://slack.com/api/channels.history?token=" + token + "&channel=" + channel; var result = JSON.parse(UrlFetchApp.fetch(url)); for (var i = 0; i < result.messages.length; i++) { var item = result.messages[i]; var match = item.text.match(/^<https:\/\/www\.youtube\.com\/watch\?v=(.*)>$/); if (match) { return match[1]; } } }
あとは[編集]メニューから定期的に発火するトリガーをセットすれば、今回の目的となる定期的にYouTube動画をpostするSlack Appの完成です。
Slash CommandsとGASのエンドポイント取得
しばらくこいつを稼働させていましたが、定期実行は意外と歯がゆい場面が多いです。短めに設定するとSlackを見ていないときにpostが溜まっていてげんなりしますし、かと言って長めに設定するといざ聞きたいときにまったくおすすめしてくれません。
考えた末、Slash Commandを設定して任意のタイミングでもおすすめしてくれるようにしよう、ということになりました。
Slash Command用エンドポイント作成
Slash Commandを設定する際は、コマンド実行時にエンドポイントを設定します。SlackからSlash Commandが呼び出されると、設定したエンドポイントにPOSTリクエストが送られるようになります。
GASの関数を外部から実行可能なAPIとして公開するためには、[公開]メニューから、[実行可能APIとして導入]および[ウェブアプリケーションとして導入]をしてやる必要があります。
エンドポイントにPOSTリクエストを送信した場合、doPost()
という関数がはじめに呼ばれるので、適切な関数の名称を変更して公開しましょう。
あとはSlash Command設定画面でAPIを呼び出してやれば完成です。簡単ですね。
おわりに
こんなことしなくても別タブでYouTube開いておけばいい気がしてきました。