- はじめに -
正直今時AWS LambdaがSlackサポートしていてポチポチやってスクリプト数行でbotが出来るし、フレームワークも充実しているので、何故今更GASなのかと思ったらブラウザバックした方が良い。
hubotもAWSも実質サーバ代がかかるけど `GASは無料` で `Google Driveの中身を触れる` くらいしかメリットがない。
投稿するだけなら以下の記事のようにIncoming Webhooksだけ設定して適当な所からPOSTするので良い
vaaaaaanquish.hatenablog.com
それでもGoogle Apps Scriptで簡単に応答するbotが作りたいんじゃいという記事。
Slackにbotもどきを導入する方法はいくつかあるが、今回目指すのは以下のようにbotがリプライできて、リプライ内容に対してbotが返信してくれる状態。
結論からいうとSlackにAppでbot追加するのと、Outgoing WebHooksを組み合わせるのが現状最善手っぽい。
- Slack側の色々 -
Slackにbotらしきものを導入する方法はいくつかある。
Custom Integrations には Bots や Outgoing WebHooks、Incoming Webhooksが用意されているし、公開AppにはHubot連携等のbot作成フレームワークとの連携Appがいくつかある。
本記事では簡単に「独自App追加」と「Outgoing WebHooks」だけでSlack botを実現する。
Slackにbotを追加して投稿する設定
SlackのAppページから新しいAppを作成
https://api.slack.com/apps
アプリ名と登録したいチャンネルを選んでCreate App
画面が遷移しApp管理画面に移る
左タブからBot Userを選択、適当な名前でbotを追加し、Always Show My BotをOnにしてSave。
このBotから投稿できるよう、左タブからIncoming Webhooksを選択。
認証画面が出るのでここで投稿したいチャンネルを選んでAuthorize。
Botの投稿URLが生成されるのでコピーしておく。
ちなみにこの時点でコンソール等からURLに対してPOSTしてやれば試せる(まあ試さなくても大体できてる)。
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/~~~
あとこの時点で、botデフォルトのicon等が設定でき、左タブのSettings>Basic Informationに飛んで下の方にスライドしていくと設定する箇所がある。
GASからSlackにPOST
GASが入ってない場合は新規でアプリの追加すれば、Google Drive上から右クリックメニュー>その他>Google Apps Scriptが選択出来るようになる。
GASでSlackする記事を見ると、大抵soundTrickerさんが作ったLibraryを使った方法が出て来るが、Slack APIのTokenが必要な事と拡張できないので使わない。
もしライブラリを使うなら以下が導入で分かりやすいかも。
Slack BotをGASでいい感じで書くためのライブラリを作った
GASとSlackではじめるチャットボット〜初心者プログラマ向け〜
初心者がGASでSlack Botをつくってみた - CAMPHOR- Tech Blog
先程取得したbotのURLを指定してGASのコードをコピペして、test関数をGASエディタの上部バーの再生ボタンっぽいやつで実行。
function postSlack(text){ var url = "https://hooks.slack.com/services/T~~~~"; var options = { "method" : "POST", "headers": {"Content-type": "application/json"}, "payload" : '{"text":"' + text + '"}' }; UrlFetchApp.fetch(url, options); } function test(){ postSlack("これはテストです"); }
注意するとしたらpayloadは {"text": "hoge"} という内容のStringであるという事くらいか。
Slackの投稿フォームで@を押した際に出るサジェストにbotが追加されている事も確認する。
SlackからGASでリプライを受け取る
本来なら上記のAppでリプライを受け取れたり出来れば良いのだが、現状できなさそう。
一般的な Browse Apps > Custom Integrations > Outgoing WebHooks を使って受け取りを行う。
GAS側の設定
GASはdoPost()なるイベントハンドラがデフォルトで用意されているので、doPostを適当に書けばHTTPメソッドでPOSTされた内容を受け取る事ができる。GETされる場合はdoGETもある。
先程のコードに以下を追記する。
function doPost(e) { var message = "こんにちは " + e.parameter.user_name + "さん"; postSlack(message) }
Slackから受け取った内容からuser_nameを見て返すというシンプルなコード。
Slackの場合だとe.parameter.textで投稿内容を取得できますが今回はスルー。
上記を追記し保存したら、GASをWebアプリケーションとして公開する。
GASエディタ画面の上部から公開を選択、ウェブアプリケーションとして導入する。
プロジェクトバージョンを新規作成して、アプリケーションの実行者を自分に、全員が実行できるよう設定して公開する。
最初だけ許可の確認があるかもしれないので許可。
こんな感じで公開されたURLが出て来るので保存しておく。
GASの一番面倒くさいところは、この「プロジェクトとして公開する」ところにある。
ウェブアプリケーションとしてAPIのような形で公開していく場合、スクリプトの保存に加えて、上記の「ウェブアプリケーションとして導入」「プロジェクトバージョンを新しく作成」「公開」の手順を毎回踏む必要がある。
(スクリプトの保存だけして新バージョンとして公開してなかった〜という事が多々発生する)
僕は適当にバージョン1、バージョン2、…と命名しているけど、大体どっかで破綻してしまうので何かいい方法が欲しい…
Slack側の設定
自分のSlackチーム名を確認してappsに飛ぶ
https://自分のSlackチームドメイン.slack.com/apps
検索窓があるので Outgoing WebHooks を検索。
Add ConfigurationするとWebhock Integrationボタンがある画面に遷移するのでIntegration。
それっぽい設定画面に遷移したら少し下にスクロールして、Integration Settingを行いSaveする。
URLは上部GAS側の設定時に取得したウェブアプリケーションのURL。
Trigger Wordは、Slack上の投稿の先頭を見て引っ掛ける単語で、カンマ区切りで設定できる。
test,bot,@,&
みたいに複数設定できるのだが、例えば@だと
@hoge こんにちは
が取得できない。
理由は@hogeとした場合、リプライやコマンド形式となり、リンクになるから。
リプライをcatchしたい時は、実際Botへリプライして右クリックでリンク取得し、URL末尾のIDを<@ >で挟む。
上記だとhttps://hogehoge.slack.com/team/U78NAL1QQ になるので <@U78NAL1QQ> をtrigger wordに設定しておけば良い。
詳しくは以下。
https://api.slack.com/docs/message-formatting
ちゃんとSaveする。
上記設定した上でBotに向けてリプライを飛ばせば返答が得られる。