先に結論
Vercel Chat SDK の callbackUrl で一番大きく変わったのは、承認ボタンを押したあとに、同じ workflow をそのまま再開しやすくなったことです。
これまでは onAction だけで頑張ると、どの承認待ちに対するクリックか、自前で状態を引き回しやすくなりました。今回からは button や modal submit の payload を webhook へ直接 POST できます。
だから最初の判断はシンプルです。単発の反応は onAction、承認付きの長いフローは callbackUrl と分けるのがいちばん素直です。
Chat SDK 全体の権限設計から見たいなら、Vercel Chat SDK chat/ai 公開 もつながります。会話 UI と workflow engine の境界まで広く見たいなら、ChatGPT apps vs Zapier vs Make vs MCP を先に見ても迷いにくいです。
何が増えたのか
2026 年 5 月 20 日、Vercel は Chat SDK の button と modal に callbackUrl を追加しました。
changelog では、承認カードの button から Workflow SDK の webhook を直接たたき、クリックを受けて run を再開する流れを例にしています。form submit でも同じ考え方を取れます。
Chat SDK docs で確認できるのは次の点です。
- button click 時に
callbackUrlへ POST できる onActionhandler があっても併存できる- payload には
actionId、user、threadId、messageIdが入る - button の
valueを付けると payload に追加できる - modal の
callbackUrlは Slack と Teams が中心
要するに、今回の更新は chat UI の click を、長い workflow の再開点としてそのまま使えるようにした ということです。
onAction と何が違うのか
onAction は今でも便利です。
軽い確認メッセージを返す、modal を開く、その場で 1 件だけ更新する、といった処理なら onAction だけで十分です。
違いが出るのは、承認待ちの時間が長くなる時です。たとえば「Slack で承認を待つ」「数時間後に誰かが押す」「押されたら同じ処理を続ける」という流れでは、onAction だけだと待機中の状態を別に持ちたくなります。
callbackUrl を使うと、その click 自体を webhook へ流せます。Workflow SDK の createWebhook() とつなげば、workflow は URL を待って一時停止し、button が押された時点で同じ run が再開します。
この差は地味ですが大きいです。承認フロー用の glue code をかなり減らせます。
どんな payload が飛ぶのか
docs の callback payload はシンプルです。
{
"type": "action",
"actionId": "approve",
"user": { "id": "U123", "name": "alice" },
"threadId": "slack:C123:1234567890.123",
"messageId": "1234567890.456"
}
button に value を持たせると、その値も一緒に飛びます。
この shape なら、承認、差し戻し、送信のような分岐を actionId だけでかなり素直に分けられます。複数ボタンを同じ webhook に向けても扱いやすいです。
Workflow SDK と組み合わせると何が楽になるか
Vercel の guide で一番分かりやすいのは、Slack 承認カードの例です。
createWebhook() で公開 URL を作り、その URL を各 button の callbackUrl に入れます。workflow 側は await webhook で止まり、誰かが approve か deny を押すと、その payload を受けて同じ run が先に進みます。
ここで効くのは、承認テーブルや polling を増やさなくていいことです。
guide では、さらに次の実務ポイントも押さえています。
- 承認後は card を再描画し、古い button を消す
- timeout を入れ、誰も押さないまま永遠に待たない
- URL を知る人が再開できるので、重要操作では user 検証を入れる
- もっと厳密に守りたいなら
createHook()と自前 route へ寄せる
つまり、今回の update は click を飛ばせるようになっただけではありません。human-in-the-loop を durable workflow とつなぐ型がかなり明確になったのが実務上の価値です。
workflow 全体をどこへ置くべきか迷うなら、GitHub Agentic Workflows vs Copilot coding agent vs OpenClaw cron も補助になります。
modal まで含めると Slack / Teams の価値が上がる
button だけなら多くの公式 adapter で使えます。
一方で changelog と docs では、modal submit の callbackUrl は Slack と Teams を主対象として案内しています。承認だけでなく、理由入力や補足情報の回収まで同じ流れに載せたいなら、この差はかなり大きいです。
たとえば次のような流れです。
- card の button を押す
- modal で理由や補足を入れる
- submit payload を
callbackUrlへ送る - workflow を再開して後続処理へ進む
この形にすると、承認の yes / no だけでなく、実務上ほしい補足情報まで 1 本の流れで扱えます。
Discord と Telegram は制約を先に見たほうがいい
今回の更新は便利ですが、どの platform でも同じ温度で使えるわけではありません。
Chat SDK docs では、Discord の custom_id は 100 文字、Telegram の callback_data は 64 byte 制限があると明記されています。callbackUrl を載せるぶん button data が膨らむため、action ID が長いだけで ValidationError になる可能性があります。
Slack と Teams の承認フローが素直に見えるのは、この制約が相対的に少ないからです。
Discord や Telegram を主戦場にするなら、最初にやるべきことは feature 追加ではなく action ID を短くする設計 です。長い文脈は value やサーバー側の lookup へ逃がした方が安全です。
既存 bot にどう足すべきか
既存 bot を全部作り直す必要はありません。
まずは onAction のままで困っている承認フローを 1 本だけ選び、そこに callbackUrl を足すのが現実的です。
おすすめはこの順です。
- 単発返信や modal open は
onActionのまま残す - 承認待ちが長い処理だけ
callbackUrlに切り出す - workflow 側で timeout を入れる
- 承認後に card を更新し、stale button を消す
- 機密度が高ければ payload の user 検証か
createHook()を足す
この順なら、便利さだけ取って統制を落とす事故を避けやすいです。
今すぐ向いているのはどんなチームか
いちばん相性がいいのは、Slack や Teams を業務の入口にしているチームです。
特に向いているのは、bot に全部自動でやらせたいのではなく、人間の承認を挟みながら前進したい チームです。法務確認、社外送信、レポート配信、デプロイ承認のような場面では、今回の更新はかなり実用的です。
Slack 常駐の AI 同僚や approval-heavy な bot を広く比較したいなら、Slack常駐AI同僚を比較|Viktor vs Jared vs MuleRun vs Claude Cowork も判断材料になります。
逆に、単なる通知 bot しか持っていないチームには、まだ大きすぎるかもしれません。その場合は onAction のままでも十分です。
まとめ
Vercel Chat SDK の callbackUrl は、button や modal の click を webhook へ直接流し、承認後に workflow を再開しやすくする更新です。
- 単発の UI 反応は
onActionのままでよい - 長い承認フローは
callbackUrlへ分けると壊れにくい - Workflow SDK の
createWebhook()と相性がいい - timeout、stale button 対策、user 検証まで見ておくと運用しやすい
- Discord と Telegram は button data 長さ制約を先に確認したい
なので今の答えは明快です。Slack や Teams で approval flow を作るなら、まず callbackUrl を 1 本だけ入れてみる価値があります。 そこで手応えが出てから、他の承認フローへ広げるのが無理のない進め方です。