Slackのボット作成でGoogle Apps Script(以下、GAS)を利用することで、サーバ費が不要になり、無料でボット作成を行うことができます。 今回の記事では、Event Subscriptionsを用いて、Slackへの投稿をトリガーとして、GASでなにか処理を行うことを目指します。
Event Subscriptions
今回使用するEvent APIのEvent Subscriptionsは、Slackへの投稿やリアクションなどのコマンドがあった場合、用意したサーバなどにSlackからリクエストが飛んできて、ほぼリアルタイムに返信などその投稿などに対しての処理を行うことができます。
今回は、これのサーバ側をGASで行いたいと思います。
GAS側でサーバを用意しよう
Slackのアプリボットを作成する前にGAS側の一時的なプログラムを用意しちゃいます。
GASを開いて、以下のようなプログラムを書きましょう。
function doPost(e){ var params = JSON.parse(e.postData.getDataAsString()); return ContentService.createTextOutput(params.challenge); }
こちらをウェブアプリケーションとして公開しておきます。
ウェブアプリケーションとして公開する方法については以下の記事に詳細をまとめておきましたので、こちらを参考にしてみてください。
ここで公開されたURL(Current web app URLのところ)をメモしておきましょう。
ボットアプリを作成してみよう
まずはSlack上でアプリを作成してみたいと思います。 以下のリンクからSlackのアプリを作成することができます。
App NameとDevelopment Slack Workspaceを入力してCreate Appをクリックします。
今回はテキトーにごみという名前で作成しています。
作成すると以下のようなページが開かれると思います。
Add features and functionalityからEvent Subscriptionsを選択します。
Offになっていると思うので、Onにしましょう。
Onにすると以下のように入力項目が表示されるかと思います。
Request URLのところにGAS側で発行されたURLを入力します。
もし、入力が間違えていたり、上のプログラムが間違っていた場合に、例えば以下のようなエラーが表示されるかと思います。
Your request URL didn’t respond with the correct challenge value. Update your URL to receive a new request and value.
アプリボットを作成するときに、challengeパラメータをちゃんと返すようなAPIを作成しないとボットの作成ができないようです。
うまくいけば以下のように、Verifiedという文字が表示されるかと思います。
Subscribe to events on behalf of usersの項目にmessage.channelsを追加します。そして、右下のSave Changesをクリックします。
最後に左のサイドメニューのInstall Appをクリックして、アプリをインストールします。 以下のInstall App to Your TeamからInstall App to Workspaceをクリックするとインストールできます。
アクセスの許可の確認がでると思うので、許可を行います。
これで完了です。
アクセスを確認してみましょう。
GASのプログラムを以下のようにログを出力するように変更してみましょう。
function doPost(e){ var params = JSON.parse(e.postData.getDataAsString()); console.log(e.postData.getDataAsString()) return ContentService.createTextOutput(params.challenge); }
console.logでのログの確認については以下の記事にまとめてあるので参考にしてみてください。
このようにすることでStackdriver LoggingでSlackから飛んでくるリクエストのパラメータを確認することができます。
このSlackボットを利用した例
さて、ここの項目は参考程度に見ていただければと思うのですが、このAPIを応用して作成したボットの例を紹介したいと思います。
ざっくりとした概要
以前の記事で、Feedlyの人気の記事・ホットな話題の記事をSlackに投稿することで、情報のキャッチアップを素早く行う方法を紹介しました。
こちらのボットの投稿に対してスレッドで返信をしたら、その返信内容でTwitterでツイートしてくれる、というものです。
ツイートについては、以下の記事で紹介した方法を用いて即座にツイートさせることを実現しています。
例えば、以下のような投稿に返信をしてみます。
これに対して、即座にツイッターに投稿されます。
「COVID-19から回復した患者の長期的な肺損傷の可能性を特に懸念している」怖い
— ポンコツエンジニア (@PnktsN) 2020年3月27日
COVID-19が肺に与える影響をVRで--米病院がYouTube動画を公開https://t.co/8ohSU1YcGs
このように、今流行っているコロナウィルスのニュース記事に対して、スレッドで意見を書くとその内容をツイートしてくれてますね。
GASプログラム
今回作成したのは以下のようなソースコードになります。
function doPost(e) { console.log(e.postData.getDataAsString()) var data = JSON.parse(e.postData.getDataAsString()) console.log(data) console.log(data.api_app_id) var apiAppId = data.api_app_id; if (apiAppId != 'A0105T5L3SP') return; // api_app_id: 'A0105T5L3SP' console.log(data.event) var user = data.event.user; if (user != 'U6TJP8Q49') return; console.log(data.event.user) var threadTs = data.event.thread_ts; console.log(data.event.thread_ts) var channel = data.event.channel; console.log(channel) var text = data.event.text; console.log(text) var botData = getFromSlack(channel, threadTs); console.log(botData.messages[0].bot_id) var botId = botData.messages[0].bot_id if (botId != 'BL7HFTKQE') return; console.log(botData.messages[0].attachments[0].text) var botText = botData.messages[0].attachments[0].text; var reg = new RegExp("\<((https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+))\>"); // Logger.log(botText.replace(reg,"\n$1")); tweetByIftttMail(text + '\n\n' + botText.replace(reg,"\n$1")); var params = JSON.parse(e.postData.getDataAsString()); return ContentService.createTextOutput(params.challenge); } function getFromSlack(channel, threadTs) { var token = 'xoxp-0000000000-00000000000-000000000000-00000000000000000000000000000' var url = 'https://slack.com/api/channels.replies?token=' + token + '&channel=' + channel + '&thread_ts=' + threadTs; var response = JSON.parse(UrlFetchApp.fetch(url).getContentText()); Logger.log(response. messages[0]. attachments[0]) return response; return response. messages[0]. attachments[0] } function tweetByIftttMail(text) { MailApp.sendEmail('trigger@applet.ifttt.com', '件名', text) }
ちょっと汚いですが、スレッドに対して投稿されたかを独自のバリデーションでチェックして、スレッドの元の投稿のテキスト内容を取得して、それを引用しながら、自分が投稿した文字と結合してメール送信しているような仕組みになっています。
さいごに
今回はSlackのEvent APIを利用する方法と、その利用例を紹介しました。 自分の場合は、このようなボットを導入したことで、技術・情報・流行りのキャッチアップをしつつ、それについての発信をSlackのスレッドに返信するだけと手軽に行えるようになりました。 そのため、最近急にツイート数が増えたかもしれませんが、これはこういった理由です。 今後もいろんなAPIを利用したりして、いろんなボットを作ってみたいと思います。