Slack の投稿を Kompira Enterprise で取得する

Kompira Enterprise から Slack に通知する」では、Kompira Enterprise から Slack にメッセージを投稿する方法をご紹介しました。
今回は逆に Slack の特定のチャンネルに投稿されたメッセージを Kompira Enterprise で取得してみましょう。


動作確認環境

ソフトウェア バージョン
Kompira Enterprise 1.6.2.post4
OS CentOS 7.8.2003

Slack の設定

まずは「Kompira Enterprise から Slack に通知する」と同様に、お使いの Slack のアカウントに #kompira チャンネルを作成してください。

この際、チャンネル ID を以下のようにチャンネルの詳細画面から確認して記録しておいてください。

その後、Slack API にアクセスし、”Creare New App” > ”From scratch” を選択してください。

”App Name” に任意の名前、”Pick a workspace to develop your app in:” にご利用の Slack のチームを指定します。

“Add features and functionality” が表示されますので、”Permissions” を選択します。

“OAuth & Permissions” に移るため、下にスクロールして以下のように “Scopes” > “User Token Scopes” > “Add an OAuth Scope” をクリックし、“channels:history” を選択してください。

※ プライベートチャンネルで使用する場合は、“groups:history” を選択してください 。

設定が完了したら上にスクロールし、“Install to Workspace” をクリックします。

以下のような画面が表示されるため、“許可する” をクリックしてください。

“User OAuth Token” が発行されるため、記録してください。Kompira Enterprise からリクエストを送る際に必要になります。

ここまでで、Slack 側の設定は終了です。

Kompira Enterprise で Slack の投稿を取得

まずは Kompira Enterprise で以下のようなジョブフローを作成します。

| user_token = "xoxp-**************" |
| channel = "***********" |
| limit = 100 |
 
[
    url = "https://slack.com/api/conversations.history",
    # クエリストリング
    params = {
        # メッセージを取得するチャンネル
        "channel": channel,
        # 最大取得件数
        "limit": limit,
        # いつからのメッセージを取得するか
        "oldest": int(now().format('%s')) - 60
    },
    headers = {
        "Authorization": "Bearer ${user_token}"
    }
] ->
 
urlopen(
    url=url,
    headers=headers,
    params=params,
    quiet=true
) ->
 
[result = json_parse($RESULT.content)] ->
print(result)

“user_token” には、先ほど取得した User OAuth Token を入力してください。

“channel” には、作成したチャンネルのチャンネル ID を入力してください。

クエリストリングに相当する “params” では必須パラメータである “channel” の他に “limit” と “oldest” が設定してあります。“limit” は最大取得件数、“oldest” はいつからのメッセージを取得するか (Timestamp 型) を指定しています。今回の場合は、1分前からのメッセージを最大100件取得することになります。

これを実行すると以下のように1分以内の #kompira チャンネルの投稿内容が最大100件表示されます。始めが ‘ok’: true となっていれば成功です。

このままでは見づらいため、時間とメッセージ内容のみ抽出して表示するように変更します。

“messages” 配列内に各メッセージデータが辞書型で格納されていて、 “ts” に日時 (Timestamp 型)、“text” にメッセージ内容が記述されているため、これらを用いてジョブフローを書き換えます。

ここでは、for 文を用いて各メッセージの日時と内容を1つずつ出力するようにしました。

| user_token = "xoxp-*****************" |
| channel = "***********" |
| limit = 100 |

[
    url = "https://slack.com/api/conversations.history",
    # クエリストリング
    params = {
        # メッセージを取得するチャンネル
        "channel": channel,
        # 最大取得件数
        "limit": limit,
        # いつからのメッセージを取得するか
        "oldest": int(now().format('%s')) - 60 
    },
    headers = {
        "Authorization": "Bearer ${user_token}"
    }
] ->

urlopen(
    url=url,
    headers=headers,
    params=params,
    quiet=true
) ->

[result = json_parse($RESULT.content)] ->
{ for message in result.messages | 
    [dt = datetime('1970-01-01 00:00:00') + timedelta(seconds=float(message.ts))] ->
    print(dt, message.text)
}

この実行結果は以下のようになります。

Kompira Enterprise で Slack の投稿を定期的に取得

先ほどのジョブフローはチャンネル内のメッセージを1回取得しただけで終了しますが、次に定期的に新着メッセージが来ているか確認するジョブフローを作成します。

先ほどのジョブフローでは新しいメッセージが一番上に表示されていましたが、定期的にメッセージを取得する場合新しいメッセージが一番下に表示された方がよいです。

しかし、Kompira Enterprise にデフォルトで配列の中身を逆順にする機能はないため、Python ライブラリを用います。

以下のようにライブラリ型オブジェクト “slack” を作成してください。

ライブラリ “slack”

def reverse_messages(messages):
    return reversed(messages)

今回は配列を逆順にする関数 reverse_messages() を定義しました。

これを用いて先ほどのジョブフローを以下のように書き換えます。ライブラリはジョブフローと同一ディレクトリにあるものとします。

“self()” はこのジョブフロー自身を表し、ジョブフローの最後に再度このジョブフローを実行することで、繰り返し処理を実装しています。

“interval” はここではメッセージの取得期間及び “sleep()” での待機時間 (秒) になります。例えば “interval = 60” の場合、1分毎に直近1分間のメッセージを取得することになります。

| user_token = "xoxp-*****************" |
| channel = "***********" |
| limit = 100 |
| interval = 60 |
 
[
    url = "https://slack.com/api/conversations.history",
    # クエリストリング
    params = {
        # メッセージを取得するチャンネル
        "channel": channel,
        # 最大取得件数
        "limit": limit,
        # いつからのメッセージを取得するか
        "oldest": int(now().format('%s')) - interval
    },
    headers = {
        "Authorization": "Bearer ${user_token}"
    }
] ->
 
urlopen(
    url=url,
    params=params,
    headers=headers,
    quiet=true
) ->
 
[result = json_parse($RESULT.content)] ->
{ for message in ./slack.reverse_messages(result.messages) |
    [dt = datetime('1970-01-01 00:00:00') + timedelta(seconds=float(message.ts))] ->
    print(dt, message.text)
} ->
sleep(interval) ->
self()

実行結果は以下のようになります。1分毎に直近1分間のメッセージが表示されます。

受信メッセージを利用したコマンド実行

次に、Slack から受信したメッセージを基に Kompira Enterprise サーバーにコマンドを実行させてみましょう。

今回は “shell ” から始まるメッセージを取得したときに、その文字以降をコマンドとして実行するようにします。例えば、“shell echo hello” というメッセージを取得したら、 “echo hello” を実行します。

先ほどのジョブフローを以下のように書き換えます。文字列の判別には Kompira Enterprise の組み込みメソッド “startswith” を使用します。

| user_token = "xoxp-*****************" |
| channel = "***********" |
| limit = 100 |
| interval = 60 |
 
[
    url = "https://slack.com/api/conversations.history",
    params = {
        # メッセージを取得するチャンネル
        "channel": channel,
        # 最大取得件数
        "limit": limit,
        # いつからのメッセージを取得するか
        "oldest": int(now().format('%s')) - interval
    },
    headers = {
        "Authorization": "Bearer ${user_token}"
    }
] ->
 
urlopen(
    url=url,
    params=params,
    headers=headers,
    quiet=true
) ->
 
[result = json_parse($RESULT.content)] ->
{ for message in ./slack.reverse_messages(result.messages) |
    [text = message.text] ->

    # "shell " ではじまるならばコマンド扱い
    { if text.startswith("shell ") | 
        # 文頭の "shell " を削除
        [command = text.replace("shell ", "", 1)] ->
        print("コマンド ${command} を実行します") ->
        [command] =>
        { if $STATUS != 0 |
          then:
            print("コマンド失敗")
          else:
            print("コマンド成功")
        }
    }
} ->
sleep(interval) ->
self()

例えば、“shell whoami” とチャンネルに投稿した後にこのジョブフローを実行すると以下のようになります。[whoami] を実行した場合と同じ結果が表示されているはずです。

この連携を応用すれば、コマンド実行以外にも様々な機能を slack から実行することが可能です。

TOP