Slack / ボタン付きのメッセージを投稿する

Shunsuke Sawada

前回まではこちら。
Slack / Google Cloud Platformと連携してスラッシュコマンドを作成する
Slack / Functions FrameworkでサクッとCloud Functionsをカスタマイズ
Slack / ローカルの開発環境を整える

ローカル開発環境が準備できたので、ようやく Slack API をつかってカスタマイズされたメッセージを送ってみたいと思います。

まずは一番かんたんな Incoming Webhook からやっていきます。
公式ドキュメントはこちら。
https://api.slack.com/incoming-webhooks

Webhook

Slack APIのページ に行って、Webhookを作成しましょう。
Screen_Shot_2019-09-07_at_18.39.05

https://hooks.slack.com/services/xx/xx/xx こんな感じのURLが発行されると思います。
ここにメッセージをJSONで送りつければSlackに投稿されるというシンプルなもの。

まずはテストしてみる。

bash
1
curl -X POST -H 'Content-type: application/json' --data '{"text":"メッセージ"}' https://hooks.slack.com/services/xx/xx/xx

メソッドは POST 、ヘッダーでJSONを指定して、 --data でメッセージを送ります。
これをターミナルから叩くとスラックに投稿されるはず。

Screen_Shot_2019-09-07_at_18.44.24

ボタン付きメッセージを投稿する

Webhookで投稿はできるようになったので、送信するJSONを工夫してボタン付きのメッセージを送信してみたい。

bash
1
2
# このフォーマットは同じ。
$ curl -X POST -H "Content-type: application/json" --data '{"text": "xxx"}' https://hooks.slack.com/services/xx/xx/xx

↑の --data '' の部分にJSONを入れるんですが、ボタン付きとなるとちょっと複雑になります。 attachments というキーを追加してその中に付属情報を記入してきましょう。

こんな感じのJSONになります。
actionsの中身がボタンの記述です。

json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
    "text": "hi",
    "attachments": [
        {
            "title": "Click button!",
            "actions": [
                {
                    "type": "button",
                    "text": "Button",
                    "name": "greeting"
                }
            ]
        }
    ]
}

これをCurlで叩こうとするとこうなる。

bash
1
$ curl -X POST -H "Content-type: application/json" --data '{"text":"hi","attachments":[{"title":"Click button!","actions":[{"type":"button","text":"Button","name":"greeting"}]}]}' https://hooks.slack.com/services/xx/xx/xx

JSONを一行にするには、Chromeの開発者コンソールでこんな感じにすると簡単。
普通に書いても良いですが、ちょっと1行だと見にくいので。

js
1
2
3
4
5
6
json = {
  // ... JSONをコピペ
}

JSON.stringify(json)
=> {"text":"hi","attachments":[{"title":"Click button!","actions":[{"type":"button","text":"Button","name":"greeting"}]}]}

見事こんなメッセージが投稿されました。

Screen_Shot_2019-09-07_at_19.09.22

この attachments を使えば凄くいろんな種類のメッセージが作成できます。
下記のページでは、JSONを書いてメッセージの見た目をリアルタイムで確認することができます。
https://api.slack.com/docs/messages/builder

Slashコマンドで実行する

curlコマンドを毎回叩くことはしたくないと思うので、Slashコマンドを実行した時に、同じようなリクエストをWebhookに送りたいと思います。

同じようなリクエストをWebhookに送りたい

ここの部分がSlackだけではできないので、Cloud Functionを使います。実際にデプロイしても良いですし、ngrok使ってローカルで実行してもOKです。詳しくは前回の記事を参考にしてください。

Slack上で /post というコマンドを叩いた時にリクエストが送られるエンドポイントの処理を書いていきます。
こんな感じです。ちょっとボタンを増やしてみました。

js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
const request = require('request');
exports.voteForDrink = (req, res) => {
  request({
    url: 'https://hooks.slack.com/services/xx/xx/xx',
    method: 'POST',
    json: {
      "text": "飲み会の場所どっちにする?",
      "attachments": [
          {
              "text": "投票してね",
              "callback_id": "vote_for_place",
              "color": "#3AA3E3",
              "attachment_type": "default",
              "actions": [
                  {
                      "name": "vote",
                      "text": "焼き肉",
                      "type": "button",
                      "value": "meet"
                  },
                  {
                      "name": "vote",
                      "text": "居酒屋系",
                      "type": "button",
                      "value": "izakaya"
                  },
                  {
                      "name": "vote",
                      "text": "不参加",
                      "style": "danger",
                      "type": "button",
                      "value": "absence",
                      "confirm": {
                          "title": "ほんとに?",
                          "text": "今回はぜんぶ奢りだよ。",
                          "ok_text": "欠席する",
                          "dismiss_text": "キャンセル"
                      }
                  }
              ]
          }
      ]
    }
  }, function(error, response, body) {
    if (error) {
      console.log(error);
      res.status(500).end();
    } else {
      res.status(200).end();
    }
  });
};

request というモジュールを使ってWebhookにリクエストを投げます。
url にWebhookのURLを指定してください。

エラーがあったらレスポンスのステータスを変更しているだけなので、コールバック処理はあまり今は気にしなくて良いです。

voteForDrink function をGCPなりローカル環境でアクセスできるようにしておいてSlackの /post コマンドを叩きましょう。

Screen_Shot_2019-09-07_at_19.32.11

見事投票メッセージが投稿されました。
不参加ボタンを押した時のアラート付き。

Screen_Shot_2019-09-07_at_19.32.16

今回はここまで。
だいぶリッチなメッセージ投稿になってきましたね。

  

5
Shunsuke Sawada

おすすめの記事

エンジニアの人いろいろ
Slack / Google Cloud Platformと連携してスラッシュコマンドを作成する
Slack / Functions FrameworkでサクッとCloud Functionsをカスタマイズ