Event Subscriptions を使うための認証の仕方

まず指定したURLが404だったり、間違ったレスポンスの場合、以下の画像のようにエラーが表示されます。

これは「俺たちが送ったchallenge値をそのまま返してくれよな!」というような意味です。つまり、{challenge: string}の形で返します。

通すサーバーを建てる Express

以下のようなサーバーを建てて、エンドポイントに slack-event.now.sh/event のようなURLを指定した後再度認証すると通ります。

const express = require('express');
const bodyParser = require('body-parser');

app.post(
  '/event',
  bodyParser.json(),
  (req, res) => {
    res.json({challenge: req.body.challenge});
  }
)

app.listen();

開発中はサーバーを、localtunnelngrokなどで一時的に晒したり、nowに上げたりすると楽です。

コピペしたシングルクォートやダブルクォートがおかしくなる

例えば、'をは付けたはずなのにに勝手に変わっちゃうようなやつです。ちなみに Mac OS の話です。

そしてこれを使っちゃうとシンタックスエラーになったりします。

Mac の設定だった

Mac のキーボード設定にある「Use smart quotes and dashes」というのにチェックが入ってたら、これが原因かもしれません。

僕の環境ではこれで直りました。

アップロードした画像は圧縮処理されたりするのか

4432737(4.2M)サイズの画像を使って、アップロードと再ダウンロードしてサイズ比較して確認しました。

画像はこちらからダウンロードしました。 Pixabayの無料画像 - 子猫, ペット, 眠っている, 猫, 動物, 家畜化された, かわいい

結果は無料プラン・有料プランどちらとも同じでどちらもアップロードしたものとまったく同じものでした。

特定のメッセージを取得

conversations.repilesを使います。最低限必要なのは

  • トークン token ($tに置いてます)
  • チャンネルID channel ($cに置いてます)
  • タイムスタンプ ts

です。

# bash
export u="https://slack.com/api/conversations.replies?token=$t&channel=$c&ts=1555390101.000300"
# fish
# set -l u "https://slack.com/api/conversations.replies?token=$t&channel=$c&ts=1555390101.000300"

curl -Ss $u | jq .messages

messagesというプロパティに配列でメッセージが入っています。以下はただのメッセージのtsを設定した時のレスポンス例です。

[
  {
    "type": "message",
    "subtype": "bot_message",
    "text": "aa",
    "ts": "1555390101.000300",
    "username": "Slack API Tester",
    "bot_id": "BD0LHGB2S",
    "thread_ts": "1555389874.000100"
  }
]

次にスレッドです。同じようにスレッド化しているtsを使います。

# bash
export u="https://slack.com/api/conversations.replies?token=$t&channel=$c&ts=1555394677.001400"
# fish
# set -l u "https://slack.com/api/conversations.replies?token=$t&channel=$c&ts=1555394677.001400"

curl -Ss $u | jq .messages

スレッドの場合は、messagesにスレッドのメッセージが含まれ、配列1つ目のメッセージに、

  • replay_count
  • replay_user_count
  • latest_reply
  • reply_users
  • repiles
  • subscribed

というプロパティが増えます。

[
  {
    "type": "message",
    "subtype": "bot_message",
    "text": "a",
    "ts": "1555394677.001400",
    "username": "Slack API Tester",
    "bot_id": "BD0LHGB2S",
    "thread_ts": "1555394677.001400",
    "reply_count": 4,
    "reply_users_count": 1,
    "latest_reply": "1555398693.000400",
    "reply_users": [
      "BD0LHGB2S"
    ],
    "replies": [
      {
        "user": "BD0LHGB2S",
        "ts": "1555395278.001500"
      },
      {
        "user": "BD0LHGB2S",
        "ts": "1555395460.002100"
      },
      {
        "user": "BD0LHGB2S",
        "ts": "1555398692.000200"
      },
      {
        "user": "BD0LHGB2S",
        "ts": "1555398693.000400"
      }
    ],
    "subscribed": false
  },
  {
    "type": "message",
    "subtype": "bot_message",
    "text": "aa",
    "ts": "1555395278.001500",
    "username": "Slack API Tester",
    "bot_id": "BD0LHGB2S",
    "thread_ts": "1555394677.001400"
  },
  {
    "type": "message",
    "subtype": "bot_message",
    "text": "aaa",
    "ts": "1555395460.002100",
    "username": "Slack API Tester",
    "bot_id": "BD0LHGB2S",
    "thread_ts": "1555394677.001400"
  },
  {
    "type": "message",
    "subtype": "bot_message",
    "text": "aaa",
    "ts": "1555398692.000200",
    "username": "Slack API Tester",
    "bot_id": "BD0LHGB2S",
    "thread_ts": "1555394677.001400"
  },
  {
    "type": "message",
    "subtype": "bot_message",
    "text": "aaa",
    "ts": "1555398693.000400",
    "username": "Slack API Tester",
    "bot_id": "BD0LHGB2S",
    "thread_ts": "1555394677.001400"
  }
]

Attachment はいくつ付けれるのか

結論から言うと100個までです。

20個まで

すべてのアッタチメントが見える状態で投稿されます。

100個まで

最初の20個が最初から表示されそれ以降のものに関しては折り畳まれて表示されます。折り畳まれた部分をクリックすると全件表示されます。

21個のアッタチメントの時は1個折り畳まれた状態。

100個のアッタチメントの時は80個折り畳まれた状態です。

100個より多い

これはtoo_many_attachments(アタッチメント多すぎ)エラーになります。

{
  "ok": false,
  "error": "too_many_attachments"
}

おまけ(データ作成)

以下を Chrome Devtool で実行するとアタッチメントの JSON を生成できて便利です。100を変えて件数を変えて使います。

copy(
  JSON.stringify(
    Array.from(Array(100)).map((_, i) => {
      return {
        text: `${i}`,
      }
    })
  )
)

Attachment の中の field はいくつ付けられるのか

結論から言うと102個まで大丈夫でした。

生成コード

以下のようなコードを Chrome devtool で実行してコピーされたものをattachemntsに設定して調べました。

copy(
  JSON.stringify(
    [
      {
        text: '0',
        fields: Array.from(Array(102)).map((_, i) => {
          return {
            title: `${i}`,
            value: `${i}`,
            short: true
          }
        })
      }
    ]
  )
)

102個まで

shorttrue,falseどちらであっても最初からすべてのフィールドが表示されます。

102から大きいと

これは複数パターンがありました。ざっとですが見つけた時の値でまとめてみます。

103

サーバーエラー。

120

413エラー。番号的にフィールドの個数というより JSON サイズの問題?

ただ、1つ1つのサイズを少し多くして100個で送ってみても大丈夫そうでした。

200

応答なし。

というわけで

100個を上限にするようにしましょう!

スレッドへ投稿したメッセージの ts を thread_ts として使うとどうなるか

結果は、「スレッドへ投稿したメッセージと同じスレッドに投稿される」です。

確認コード

すこし楽するためにjqコマンドを使ってます。

準備

最低限必要となるトークンとチャンネルIDは何度もコピーするのが面倒くさいので以下のように環境変数に置いておきます。

# bash
export t=xoxp-xxx-xxx-xxx-xxxxx
export c=xxxxx
# fish
# set -l t xoxp-xxx-xxx-xxx-xxxxx
# set -l c xxxxx

$tがトークン、$cをチャンネルIDとして使っていきます。

ベースとなるメッセージを投稿

以下は適当なチャンネルに「a]とだけ投稿し、結果のtsを表示するコマンドです。

# bash
export u="https://slack.com/api/chat.postMessage?token=$t&channel=$c&text=a"
# fish
# set -l u "https://slack.com/api/chat.postMessage?token=$t&channel=$c&text=a"
curl -Ss $u | jq -r .ts

1555394677.001400というような値が得られます。

ts を thead_ts に設定してスレッドに投稿

先程の1555394677.001400thread_tsというクエリに置いて再度コマンドを叩くことでそのスレッドへメッセージを投稿できます。またそのメッセージのtsが表示されるのでコピーしておきます。

# bash
export u="https://slack.com/api/chat.postMessage?token=$t&channel=$c&text=aa&thread_ts=1555394677.001400"
# fish
# set -l u "https://slack.com/api/chat.postMessage?token=$t&channel=$c&text=aa&thread_ts=1555394677.001400"
curl -Ss $u | jq -r .ts

そして、1555395278.001500が得られました。

ここまでの流れで Slack の画面は以下のようになっているはずです。

スレッド投稿メッセージの ts を thread_ts に設定して再度スレッドに投稿

以下を実行します。

# bash
export u="https://slack.com/api/chat.postMessage?token=$t&channel=$c&text=aaa&thread_ts=1555395278.001500"
# fish
# set -l u "https://slack.com/api/chat.postMessage?token=$t&channel=$c&text=aaa&thread_ts=1555395278.001500"
curl -Ss $u | jq -r .ts

冒頭に書いた結果が得られたはずです。

データとしてはどうなっているか

conversations.repliesで取得して見た所、最後に投稿したメッセージのthread_ts1555394677.001400(最初のメッセージのts)が設定されていました。

チャンネルのメッセージをまとめて削除

ツールをちょっと作った。

リンク

使い方

イメージ名はnju33/slack-channel-cleanerですので、とりあえずこれを持ってきます。

docker pull nju33/slack-channel-cleaner

終わったらコンテナを作って中に入ります。

docker run --rm -it nju33/slack-channel-cleaner

中ではslack-channel-cleanersccというコマンドが使えるようになっているはずです。このコマンドでメッセージを消していきます。
必要なオプションはトークンとチャンネルIDの2つ必要なのでコピーしておきます。

# $TOKEN や $CHANNEL は書き換えて
scc --token $TOKEN --channel $CHANNEL
# 12 ⠸ Deleting bot_message...

実行すると新しいものから1つずつ削除していってくれると思います。

API ∋ search.messages

ワークスペース内のあらゆる事について検索できる API です。この API はtokenを除くとqueryフィールドが必須です。

query

一番重要な引数で、ここに置いたテキストでワークスペース内を検索します。スペースなどを挟んで複数のワードを置いた場合or検索(どちらかが含まれてればマッチ)します。
また、幾つかの特殊なプレフィックスが用意されており、それらを組み合わせることで効率良く結果を絞り込むことができます。

in:<channel-name>in:<group-name>in:@<user-id>のようにin:の後ろにチャンネル名やユーザー名などを続けることで、検索対象をそれら指定したチャンネル内や DM 内に絞り込めます。

他にfrom:があります。これをfrom:@<user-name>from:<bot-name>のように使う事で、その人の発言だけに絞り込めます。

ボット名での絞り込みの注意点

Slack ではボット名は割と適当に決めてchat.postMessageから投稿できてしまいます。例えば、jun というアプリから john というボット名で投稿するといった具合です。
そのメッセージはfrom:Johnでちゃんと検索できます。しかし、その後のワークスペースの管理の方法によってはfrom:johnでの検索で引っかからなくなる恐れがあります。

それはjohnというアプリをインストールした場合です。その環境になると jun アプリのアクセストークンでfrom:johnと検索してもメッセージは引っかかりません。   その環境でどうしても検索したいのであれば、john アプリで Bot Access Token を作り、それを使ってsearch.messageをリクエストするしかなくなります。

count

結果1ページ辺りのメッセージ数です。

page

何ページ目の結果を返すかどうかです。

highlight

trueを指定するとマッチした箇所のテキストが\ue000\ue001で挟まれて返されます。

エラー

レスポンスを返す時

{status: 500, statusText: 'Internal Server Error'}

payloadなどで来たresponse_urlへのposthreadersAuthorization: 'Bearer ...'を含んでいる。