てくなべ (tekunabe)

ansible / network automation / 学習メモ

StackStorm で Slack 投稿時に特定のアクションをするルールを作ってみた

■ はじめに

以前のエントリで、 StackStorm の Slack Pack の Action を利用して、Slack への投稿を試しました。

tekunabe.hatenablog.jp

今回は、Action ではなく、Trigger や Sensor を使って Slack 上のイベントを拾って何かする、という機能を試してみます。


■ ためすこと

Slack の投稿を検出して、以下のようにテキストファイルに出力する、という簡単な処理をためすことにします。

名前: 投稿内容
名前: 投稿内容
名前: 投稿内容
名前: 投稿内容


■ 準備

トークンの取得

連携のためには Slack のトークンが必要です。 Slack Pack の GitHub リポジトリの README に説明があります。 今回は、とにかく簡単に試したかったため、「For testing purposes..」の下りで説明されている方法でトークンを取得しました。

Slack Pack の設定

先程取得したトークンを、st2 pack config slack コマンドで設定します。

今回は以下の値にして、他はデフォルトのままにしました。

設定項目 備考
post_message_action.username akira6592 任意の名前
post_message_action.webhook_url (着信WebフックのURL)
sensor.token (先程控えたトークン)
admin.organization admin 任意の名前

途中、以下のように聞かれますのでエンターを押します。

Do you want to preview the config in an editor before saving? [y]:

設定内容がテキストとしてエディタで開かれるので、確認後エディタを終了します。

最後に

Do you want me to save it? [y]: 

と聞かれるのでエンターを押します。


■ Slack Trigger の仕様調査

後で必要になる情報を調べておきます。

Slack Pack に含まれる Trigger を調べます。

[ec2-user@ip-172-31-4-147 ~]$ st2 trigger list -p slack
+---------------+-------+------------------------------------------------------+
| ref           | pack  | description                                          |
+---------------+-------+------------------------------------------------------+
| slack.message | slack | Trigger which indicates a new message has been       |
|               |       | posted to a channel                                  |
+---------------+-------+------------------------------------------------------+

slack.message という Trigger があり、新着メッセージを拾えるようです。

次に、この Trigger の詳細を調べます。

[ec2-user@ip-172-31-4-147 ~]$ st2 trigger get slack.message
+-------------------+--------------------------------------------------------------+
| Property          | Value                                                        |
+-------------------+--------------------------------------------------------------+
| id                | 5b0b5b426fb12304dc0e014f                                     |
| ref               | slack.message                                                |
| pack              | slack                                                        |
| name              | message                                                      |
| description       | Trigger which indicates a new message has been posted to a   |
|                   | channel                                                      |
| parameters_schema |                                                              |
| payload_schema    | {                                                            |
|                   |     "type": "object",                                        |
|                   |     "properties": {                                          |
|                   |         "text": {                                            |
|                   |             "type": "string"                                 |
|                   |         },                                                   |
|                   |         "timestamp_raw": {                                   |
|                   |             "type": "string"                                 |
|                   |         },                                                   |
|                   |         "user": {                                            |
|                   |             "type": "object"                                 |
|                   |         },                                                   |
|                   |         "channel": {                                         |
|                   |             "type": "object"                                 |
|                   |         },                                                   |
|                   |         "timestamp": {                                       |
|                   |             "type": "integer"                                |
|                   |         }                                                    |
|                   |     }                                                        |
|                   | }                                                            |
| tags              |                                                              |
| uid               | trigger_type:slack:message                                   |
+-------------------+--------------------------------------------------------------+

例えば、投稿内容そのものは text で取得できそうです。

Slack Pack の GitHub リポジトリの README の slack.message trigger に、ペイロードのサンプルが載っていました。

(引用)

{
    "user": {
        "first_name": "Tomaz",
        "last_name": "Muraus",
        "is_owner": false,
        "name": "kami",
        "real_name": "Tomaz Muraus",
        "is_admin": false,
        "id": "U0CCCCC"
    },
    "channel": {
        "topic": "",
        "id": "C0CCCCCC",
        "name": "test"
    },
    "timestamp": 1419164091,
    "timestamp_raw": "1419164091.00005",
    "text": "This is a test message."
}

例えば、投稿者の名前は user.name で取得できそうです。


■ ルールの作成

何が起きたときに何をする、というルールを作成します。

ルールの書き方は、公式ドキュメントの Quick Start の Define a Ruleを参考にしました。後でわかりましたが、ここでの ~/slack.log/home/stanley/slack.log になります。

r_slack.yml

---
name: "r_slack"
pack: "test"
description: "test rule for slack"
enabled: true

trigger:
  type: "slack.message"
  parameters: {}
action:
  ref: "core.local"
  parameters:
    cmd: "echo \"{{trigger.user.name}}: {{trigger.text}}\" >>  ; sync"

続いて、ルールを登録します。

[ec2-user@ip-172-31-4-147 ~]$ st2 rule create r_slack.yml 
+-------------+--------------------------------------------------------------+
| Property    | Value                                                        |
+-------------+--------------------------------------------------------------+
| id          | 5b128cfd6fb12304f47d825c                                     |
| name        | r_slack                                                      |
| pack        | test                                                         |
| description | test rule for slack                                          |
| action      | {                                                            |
|             |     "ref": "core.local",                                     |
|             |     "parameters": {                                          |
|             |         "cmd": "echo "{{trigger.user.name}}:                 |
|             | {{trigger.text}}" >> ~/slack.log ; sync"                     |
|             |     }                                                        |
|             | }                                                            |
| criteria    |                                                              |
| enabled     | True                                                         |
| ref         | test.r_slack                                                 |
| tags        |                                                              |
| trigger     | {                                                            |
|             |     "type": "slack.message",                                 |
|             |     "ref": "slack.message",                                  |
|             |     "parameters": {}                                         |
|             | }                                                            |
| type        | {                                                            |
|             |     "ref": "standard",                                       |
|             |     "parameters": {}                                         |
|             | }                                                            |
| uid         | rule:test:r_slack                                            |
+-------------+--------------------------------------------------------------+

念の為、ルールのリストを確認します。

[ec2-user@ip-172-31-4-147 ~]$ st2 rule list -p test
+--------------+------+---------------------+---------+
| ref          | pack | description         | enabled |
+--------------+------+---------------------+---------+
| test.r_slack | test | test rule for slack | True    |
+--------------+------+---------------------+---------+

無事に登録されたようです。


■ おためし

それではいよいよ試してみます。

Slack の general チャンネルに Hello, Slack! と投稿すると、/home/stanley/slack.log

yokochi: Hello, Slack!

と書き込まれました。

デモ動画 f:id:akira6592:20180603133910g:plain

試した限り、今回利用したトークンでは、いずれかのユーザーが general に投稿したイベントを取得することができるようです。他のチャンネルではイベントを取得することができませんでした。


■ まとめ

簡単な例ですが、Slack Pack の Trigger を利用して、Slack に投稿があったら何かする、というルールの動作の確認ができました。 chatops Pack でも色々できそうなので調べてみたいと思います。