Slack API の新メソッドを試してみた【ストリーミング編】

Slack API の新メソッドを試してみた【ストリーミング編】

Slack のテキストストリーミング API を紹介します。chat.startStream、chat.appendStream、chat.stopStream の各メソッドと chunks パラメータによるブロックの逐次更新を検証例とともに解説します。
2026.09.01

2026 年に入ってから、Slack の Block Kit に新しいブロックが続々と追加されています。本シリーズでは、これらの新ブロックと関連する API を実際に試しながら紹介していきます。

  • 第 1 弾: データ編

https://dev.classmethod.jp/articles/slack-block-kit-new-data-display-blocks/

  • 第 2 弾: 汎用表示編

https://dev.classmethod.jp/articles/slack-block-kit-new-general-display-blocks-guide/

  • 第 3 弾: エージェント編

https://dev.classmethod.jp/articles/slack-block-kit-agent-blocks-guide/

  • 第 4 弾: ストリーミング編(本記事)
  • 第 5 弾: 検証・CI 編

今回は、第 4 弾としてテキストストリーミング API である chat.startStream / chat.appendStream / chat.stopStream の 3 メソッドを紹介します。LLM アプリでお馴染みの、応答が少しずつ表示されていく表示を Slack アプリで実現するための API です。

これまでも chat.update で同じメッセージを繰り返し編集すればストリーミング風の表示は作れました。しかし、この方式はリクエストごとに全文を再度用意して再送する必要があり、更新頻度を上げるとレート制限にも達しやすいものでした。

これに対して、ストリーミング API では追記分だけを送ればよく、追記を担う appendStream のレート制限は緩めで、ますます扱いやすく改善されています

ちなみに、第 3 弾で紹介した plan block と task_card block を逐次更新していく仕組みもこの API が担っています。

なお、今回はお馴染みの Block Kit Builder では検証できないため、Slack CLI の slack api コマンドで API を直接呼び出して検証します。
こちらのコマンドについては以下の記事をご参照ください。

https://dev.classmethod.jp/articles/slack-cli-slack-api/

メソッドの概要

メソッド 役割 レート制限
chat.startStream[1] ストリーミングメッセージを開始する Tier 2(毎分 20+)
chat.appendStream[2] ストリーミング中のメッセージに追記する Tier 4(毎分 100+)
chat.stopStream[3] ストリーミングを終了しメッセージを確定する Tier 2(毎分 20+)

3 メソッドとも必要なスコープは chat:write のみです。start のレスポンスで受け取ったタイムスタンプを append と stop に渡すことで、1 つのメッセージに対して追記と確定を行います。

主要なパラメータ

chat.startStream

項目 内容
channel 必須。チャンネル・スレッド・DM の ID
markdown_text 標準 Markdown 形式のテキスト。最大 12,000 文字
chunks ストリーミングチャンクの配列。markdown_text とは併用不可
thread_ts 返信先のスレッド。通常のチャンネルでは省略すると invalid_thread_ts エラーになる
recipient_user_id / recipient_team_id ストリーミングを受け取るユーザーとチームの ID。チャンネルへのストリーミング時は必須
task_display_mode タスクの表示方法。timeline(タスクカードをテキストと交互に個別表示)か plan(plan block にまとめて表示)。デフォルトは timeline

重要なポイントとして、通常のチャンネルではスレッド返信としてしかストリーミングができません

返信ではない通常投稿としての配信は、チャンネル全体が 1 セッションとなるような特殊な設定のチャンネルでのみ可能です。また、チャンネルへ配信する場合は recipient_user_idrecipient_team_id の指定が必須です。誰に向けたストリーミングかを Slack 側が把握する仕組みになっています。

chat.appendStream

channelts が必須で、markdown_text または chunks で内容を渡します。markdown_text は全文の再送ではなく、追記分だけを送る方式です。

chat.stopStream

同じく channelts が必須で、markdown_text または chunks で内容を渡す形式です。加えて、以下のような特有の項目があります。

項目 内容
blocks 確定したメッセージの末尾にレンダリングされるブロックの配列。最大 50 個で、chunks 経由の 50 個とは別枠
metadata メッセージメタデータ
session_status ストリーミング終了後に設定するセッションのステータス。active / processing / suspended / closed

markdown_text でテキストをストリーミングする

経費精算の質問に答えるボットを想定して、3 メソッドを順に呼び出してみます。まずはストリーミング開始処理です。

$ slack api chat.startStream --json '{
  "channel": "C0123456789",
  "thread_ts": "<スレッド元となるメッセージのタイムスタンプ>",
  "recipient_team_id": "T0123456789",
  "recipient_user_id": "U0123456789",
  "markdown_text": "調べています。\n\n"
}'

レスポンスの ts がストリーミングメッセージの識別子になります。この ts を指定して追記します。

$ slack api chat.appendStream --json '{
  "channel": "C0123456789",
  "ts": "<ストリーミング開始処理レスポンスのタイムスタンプ>",
  "markdown_text": "## 出張費の精算期限\n\n**帰着日から 1 週間以内**に申請してください。"
}'

そして最後に停止します。第 3 弾で紹介した context_actions block を blocks に渡して、確定したメッセージの末尾にフィードバックボタンを付けてみます。

$ slack api chat.stopStream --json '{
  "channel": "C0123456789",
  "ts": "<ストリーミング開始処理レスポンスのタイムスタンプ>",
  "blocks": [
    {
      "type": "context_actions",
      "elements": [
        {
          "type": "feedback_buttons",
          "action_id": "answer_feedback",
          "positive_button": {
            "text": { "type": "plain_text", "text": "👍" },
            "value": "positive_feedback"
          },
          "negative_button": {
            "text": { "type": "plain_text", "text": "👎" },
            "value": "negative_feedback"
          }
        }
      ]
    }
  ]
}'

ストリーミングの様子

メッセージの上書き更新と違って追記分だけを送ればよいので、LLM の出力をそのまま送信するだけで済みます。一気にそれらしい表示になりましたね!

chunks で思考過程をストリーミングする

次に chunks パラメータを使って、第 3 弾で紹介した plan block を逐次更新してみます。chunk には 4 種類があります。

chunk の種類 用途
markdown_text Markdown テキストの追記
task_update タスクの追加・更新。id が同じものは更新として扱われる
plan_update plan のタイトルの更新
blocks ブロック配列の追加。1 つの配列につき最大 50 個で、超過分は破棄され API 経由で警告が出る

task_update chunk の構造は task_card block とほぼ同じですが、detailsoutput が rich_text ではなく文字列である点が異なります。また task_updateplan_update の chunk サイズには 256 文字の制限があります。

task_display_modeplan を指定してストリーミングを開始し、タスクを順に送信していきます。

$ slack api chat.startStream --json '{
  "channel": "C0123456789",
  "thread_ts": "<スレッド元となるメッセージのタイムスタンプ>",
  "recipient_team_id": "T0123456789",
  "recipient_user_id": "U0123456789",
  "task_display_mode": "plan",
  "chunks": [
    { "type": "plan_update", "title": "経費精算の質問に回答中" },
    { "type": "task_update", "id": "step_1", "title": "社内ドキュメントを検索", "status": "in_progress" }
  ]
}'

タスクの完了と次のタスクの開始は、同じ id に対する task_update で表現します。ts には先ほどと同様に、開始時のレスポンスの値を指定します。

$ slack api chat.appendStream --json '{
  "channel": "C0123456789",
  "ts": "<ストリーミング開始処理レスポンスのタイムスタンプ>",
  "chunks": [
    { "type": "task_update", "id": "step_1", "title": "社内ドキュメントを検索", "status": "complete", "output": "経費精算ガイドが見つかりました" },
    { "type": "task_update", "id": "step_2", "title": "回答を生成", "status": "in_progress" }
  ]
}'

plan block のタスクストリーミング

第 3 弾では plan block を静的な JSON として貼っていましたが、こちらがより実践的な実装です。

まとめ

本記事では、テキストストリーミング API の 3 メソッドをご紹介しました。

テキストの逐次表示から plan block の更新、フィードバックボタンの設置までをシンプルな実装で実現できるようになっており、エージェント用の表示コンポーネントがどんどん使いやすくなっている印象です。従来の chat.update を使われている方は、これを機に新しいメソッドを試してみてはいかがでしょうか?

次回はいよいよ最終回です。第 5 弾は検証・CI 編として、blocks.validate によるペイロード検証と CI への組み込みを試します。お楽しみに!

脚注
  1. https://docs.slack.dev/reference/methods/chat.startStream ↩︎

  2. https://docs.slack.dev/reference/methods/chat.appendStream ↩︎

  3. https://docs.slack.dev/reference/methods/chat.stopStream ↩︎


AI白書2026 配布中

クラスメソッドが独自に行なったAI診断調査をもとに、企業のAI活用の現在地を調査レポートとしてまとめました。企業規模別の活用度傾向に加え、規模を超えてAI活用を進める企業に共通する取り組みまで、自社の現在地を捉えるためのヒントにぜひ。

AI白書2026

無料でダウンロードする

この記事をシェアする

DevelopersIO 2026

関連記事