Edited at

Slack BotをGASでいい感じで書くためのライブラリを作った

全国のGoogle Apps Scriptファンの皆様こんにちは

Apps Scriptガチ勢の大橋です。

今年でGoogle Apps Scriptアドベントカレンダーも3年目になりました。

年々人は減っている気がしますが、BigQueryとの連携など他のアドベントカレンダーに名前が出ることが増えてきて、嬉しい限りです。

さて、ちょいSlack BotをGASで作る機会があったのでSlack API周りをGASで扱うためのLibraryを作りました。

今回はこのLibraryとそれを使って作った会議予約Botのサンプルコードについて書いていきたいと思います。

なお知らない方も多いので書いておくと、GASのLibrary機能は丁寧に作ると補完が非常に効くようになり、開発効率が10倍以上変わります。

26_12_08_10_55.png

Libraryについて詳しくは以下の記事を見て下さい。


ライブラリ SlackApp


基本情報


使い方

前提として https://script.google.com からGoogle Apps Scriptプロジェクトを作成して下さい。

当然GASガチ勢の皆様はブラウザのアドレスバーにscぐらいまで打てば上記URLが補完され、

GASエディターが起動できる状態になっていると思います。


Libraryを導入

プロジェクトにLibraryを導入します。

GASのライブラリを使って楽したい① とりあえず使ってみる(:3」∠)」を参考に、下記キーのライブラリを導入して下さい。

M3W5Ut3Q39AaIwLquryEPMwV62A3znfOO


Slack API Tokenの取得

APIへアクセスするためのtokenを取得します。

tokenは https://api.slack.com/web の「Authentication」から取得できるはずです。

Slack_API___Slack.png

取得したらGASプロジェクトのScript Propertiesあたりに保存しておきます。


save.gs

function saveToken() {

PropertiesService.getScriptProperties().setProperty("token", "取得したトークン");
}

なお、Slack APIにはOAuth2による認証方式が有り、Library自体もそれに対応しているのですが、めんど... 複雑なためドキュメント化していません。

ほとんど過去に作ったTypeTalkのLibraryと同じ作りなので、そちらを参考にしていただくとやれると思います。


投稿してみる

Tokenを使って投稿しています。


postMessage.gs

function postMessage() {

var prop = PropertiesService.getScriptProperties().getProperties();

//slackApp インスタンスの取得
var slackApp = SlackApp.create(prop.token);

//適当にchannel idを取得
var channelId = slackApp.channelsList().channels[0].id;

 //投稿
slackApp.postMessage(channelId, "ハロー世界", {
username : "MyFirstBot"
});
}


このLibraryの各メソッド名はSlackAppのAPI名と同じです。

例えばチャネル情報を取得する「channels.info」APIであれば「slackApp.channelsInfo(channelId)」が対応します。


Botとして動かしてみる

Slackへの投稿に対して反応するBotを作成する場合は、Slackの「Outgoing Webhook」とGASのdoGetを利用します。


GASにdoGetを作る

2013年度版 5分で始めるWebアプリケーション(Google Apps Script)」を参考にGASプロジェクトにてdoGet関数をつくり、HTTP GETアクセスできるようにします。

この時入り口のURL(https://script.google.com/macros/s/xxxxxxxxxxxxxxxxxxx/exec)をメモっておいて下さい。

なおSlackからは何も認証を行っていない、単純なGetリクエストが来るため、「ウェブアプリケーションとして導入」する際に「アプリケーションにアクセスできるユーザー」を「全員(匿名ユーザーを含む)」にしておいて下さい。

Google Appsのアカウントを利用している場合Apps側の設定によってはこのオプションが選べないのでご注意下さい。

=諦めて下さい。

無題のプロジェクト.png


doGet.gs

function doGet(e) {

return null;
}



SlackにてOutgoing Webhookの設定を行う。

Slackのoutgoing-webhookの設定画面にアクセスします。

画面が表示されたら「Add Outgoing WebHooks Integration」をクリックします。

outgoing.png

次の画面が表示されたら下の方の「Integration Settings」に行き設定を行っていきます。

「Channel」はOutgoing WebHooksが動くChannelですね。

「Any」にしておくとどこでも動きます。Channelを絞りたい場合は何かしらのChannelを選択しておきます。

「Trigger Word(s)」は「Outgoing WebHooks」が動くためのTriggerとなる単語です。

例えば「MyFirstBot:」とかしておくと「MyFirstBot:」が先頭にあるときだけ動きます。

「URL(s)」に先ほどメモったURLを貼り付けておきます。

また必須ではないですが「Token」をメモって置くと良いです。TokenはSlackがGetリクエストを送ってくる際に渡してくれる検証用トークンです。

GASのdoGet内でSlackからのアクセスかどうか突合して置くと良いと思います。

outgoing-webhooksetting.png


GAS側でdoGet内のコードを書く

以下の感じでコードを書きます。

function doGet(e) {

//Get properties.
var prop = PropertiesService.getScriptProperties().getProperties();
if (!e) {

//for Test. Slackからは以下のパラメータで飛んできます。
e = {
parameter : {
token : prop.verifyToken,
team_id : "T0001",
channel_id : "C12345678910",
channel_name : "test",
timestamp : "1355517523.000005",
user_id : "U2147483697",
user_name : "Steve",
text : "MyFirstBot: Hi",
trigger_word : "MyFirstBot:"
}
};
}

if (prop.verifyToken != e.parameter.token) {
throw new Error("invalid token.");
}

//Create an instance.
var slackApp = SlackApp.create(prop.slackToken);

//My first Message!
slackApp.chatPostMessage(e.parameter.channel_id, "Hi " + e.parameter.user_name, {
username : "My First Bot",
icon_emoji : ":+1:"
});

return null;
}

なおコードの更新後、GASプロジェクトのバージョンを上げ、ウェブアプリケーションのバージョンを上げるのを忘れないで下さい。

何言っているかわからない人は多分「コード更新したんだけど動かない」ってなるはずです。

その時上の呪文を唱えて下さい。


Slackから送ってみる

実際に選択したSlackのchannelから上記Trigger Wordを付けてメッセージを送ってみましょう。

Botが返信してくれるはずです。


まとめ

いかがでしたでしょうか?

GASとSlackが混ざることによりかなりのことが自動化できます。

個人的に作っているものだと「会議予約Bot」というのがあって、

「会議予約: 2014/12/01 17:00-18:00 定例会議 人:"大橋、...." 場所:"A会議室"」

みたいな投稿をすると以下のことをしてくれます。


  • Google Calendarへのイベントの作成(参加者全員を呼び出し)

  • Goodle Docsの議事録フォーマットをコピーし人、場所、日時を設定

  • 会議日前日当日(朝、開始10分前)に事前作成した議事録のURLをSlackに貼り付け

これだけでかなりの自動化と、「会議室予約ミスの削減」「議事録の作り忘れ、テンプレートの場所がわからないから作らない問題の解決」「議事録どこだっけの無駄な時間の削除」ができます。

素敵ですね!

あとはBigQueryのQueryを投げると検索してそのまま返してくれるBotと、

グラフ化して返してくれるBotもいたりします。

BotとGASは色々相性が良いです。

またHubotなどのようにサーバを準備する必要が無いため、

必要になったその日にBotを運用開始できます。

ぜひ素敵なChatOpsライフを!