1. Qiita
  2. 投稿
  3. GoogleAppsScript

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

  • 317
    いいね
  • 4
    コメント
この記事は最終更新日から1年以上が経過しています。

全国の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ライフを!

Comments Loading...