Slack APIのconversations.historyはPOSTなのかGETなのか

Slack APIでチャンネルのメッセージを抽出するときに conversations.history を使っている。オプションを確認しようと思ってドキュメントを確認したら、ちょっと気になることがあった。

ドキュメントの「Reference docs」ではPOSTだが、「Sample code」ではGETになっている。

もともとはGETを使っており、POSTのリクエスト方法も複数種類あり、どれを使うか迷ったのでメモ。

状況

以下が conversations.history のドキュメント。

api.slack.com

2024/11/15 現在、リクエスト時のHTTPメソッドが、「Reference docs」タブではPOST、「Sample code」タブではGETになっている。ただし、サンプルコードではリクエストボディが設定されているように見える。

Reference docs

Sample code

どちらが正か

試してみたところ、GET/POSTともに実行できた。また、書き込みではないが、JSONリクエストボディも許可されている。

SLACK_TOKEN=...
SLACK_CHANNEL_ID=...

AUTH_HEADER="Authorization: Bearer ${SLACK_BOT_TOKEN}"

# GET
curl "https://slack.com/api/conversations.history?channel=${SLACK_CHANNEL_ID}" \
  -H "${AUTH_HEADER}"

# POST
# curlの場合、 `Content-Type: x-www-form-urlencoded` が自動的に付与されるため省略
curl -X POST "https://slack.com/api/conversations.history" \
  -H "${AUTH_HEADER}" \
  -d "channel=${SLACK_CHANNEL_ID}"

# POST JSON、Content-Typeの理由は後述
curl -X POST "https://slack.com/api/conversations.history" \
  -H "${AUTH_HEADER}" \
  -H "Content-Type: application/json; charset=UTF-8" \
  -d "{ \"channel\": \"${SLACK_CHANNEL_ID}\" }"

# POSTでもクエリパラメータが有効
# この場合はContent-Type未指定となるが問題ない
curl -X POST "https://slack.com/api/conversations.history?channel=${SLACK_CHANNEL_ID}" \
  -H "${AUTH_HEADER}"

どの方法がいいか

POSTについては、クエリパラメータ指定以外だと、 Content-Type を指定する必要がある。それぞれ Content-Type: x-www-form-urlencoded または Content-Type: application/json を指定しないと、以下のエラーが発生。

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

また、JSON形式の場合、 Content-Type: application/json を指定しても、レスポンスに警告が含まれる。この警告を消すには Content-Type: application/json; charset=UTF-8 のように、文字コードを指定する必要がある。

{
  "ok": true,
  // 中略
  "warning": "missing_charset",
  "response_metadata": {
    "warnings": [
      "missing_charset"
    ]
  }
}

たしかJSONって、UTF-8にする必要がなかったっけ?

www.publickey1.jp

zenn.dev

楽なのはGETかPOSTのクエリパラメータ指定で、 Content-Type の指定は不要。

シンプルなのはGETだが、はたして利用していいのか判断がつかない。

とはいえ今まで使えていたので、結局はシンプルさを重視してGETを使うことにした。

振り返り

当然GETだろうと思っていたが、ドキュメントを見たらPOSTになっていたのでびっくり。

というか、以前からPOSTだったとしたら、なぜ自分はGETにしたのだろうか...

使用頻度が高いメソッドだと思うので、GETできるならできると明記してほしいな。