惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

宝玉的分享
宝玉的分享
Security Latest
Security Latest
S
Secure Thoughts
H
Heimdal Security Blog
The Last Watchdog
The Last Watchdog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
PCI Perspectives
PCI Perspectives
C
CERT Recently Published Vulnerability Notes
C
CXSECURITY Database RSS Feed - CXSecurity.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
有赞技术团队
有赞技术团队
爱范儿
爱范儿
腾讯CDC
P
Privacy & Cybersecurity Law Blog
量子位
T
Threat Research - Cisco Blogs
V
V2EX
S
Schneier on Security
P
Proofpoint News Feed
美团技术团队
Apple Machine Learning Research
Apple Machine Learning Research
Forbes - Security
Forbes - Security
The Hacker News
The Hacker News
月光博客
月光博客
C
Cybersecurity and Infrastructure Security Agency CISA
Schneier on Security
Schneier on Security
L
LINUX DO - 最新话题
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Visual Studio Blog
S
SegmentFault 最新的问题
G
GRAHAM CLULEY
人人都是产品经理
人人都是产品经理
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 叶小钗
罗磊的独立博客
WordPress大学
WordPress大学
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
T
Tenable Blog
D
Darknet – Hacking Tools, Hacker News & Cyber Security
W
WeLiveSecurity
V
Vulnerabilities – Threatpost
Last Week in AI
Last Week in AI
Google DeepMind News
Google DeepMind News
博客园 - 聂微东
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

Chat SDK Documentation

Vercel Connect | Chat SDK Teams Low-Level APIs | Chat SDK CLI | Chat SDK Platform Adapters | Chat SDK State Adapters | Chat SDK Cards | Chat SDK Getting Started | Chat SDK Introduction | Chat SDK Modals | Chat SDK Slack Low-Level APIs | Chat SDK Streaming | Chat SDK Testing | Chat SDK Overview | Chat SDK toAiMessages | Chat SDK Cards | Chat SDK Overview | Chat SDK Markdown | Chat SDK Modals | Chat SDK AI SDK Tools | Chat SDK Types | Chat SDK Message Subject | Chat SDK Conversation History | Chat SDK Transcripts | Chat SDK Slack bot with Next.js and Redis Actions | Chat SDK Direct Messages | Chat SDK Emoji | Chat SDK Error Handling | Chat SDK File Uploads | Chat SDK Handling Events | Chat SDK Posting Messages | Chat SDK Slash Commands | Chat SDK State Adapters | Chat SDK Threads, Messages, and Channels | Chat SDK Creating a Chat Instance | Chat SDK WhatsApp Business Cloud Channel | Chat SDK Chat | Chat SDK Platform Adapters | Chat SDK Overlapping Messages | Chat SDK Ephemeral Messages | Chat SDK Message | Chat SDK Thread | Chat SDK Building a community adapter | Chat SDK Documenting your adapter | Chat SDK Publishing your adapter | Chat SDK Testing adapters | Chat SDK Code review GitHub bot with Hono and Redis Discord support bot with Nuxt and Redis Durable chat sessions with Next.js, Workflow, and Redis Schedule Slack posts with Next.js, Workflow, and Neon PostableMessage | Chat SDK
Approvals | Chat SDK
Vercel · 2026-07-22 · via Chat SDK Documentation

Pause a durable workflow until a human approves it in chat.

requestApproval from chat/workflow posts a card with Approve/Deny buttons and suspends a Workflow SDK workflow until a user clicks. The wait can last seconds or days and survives deploys and restarts. You don't need an approvals table, an onAction handler, or a polling loop.

import { requestApproval } from "chat/workflow";
import type { Thread } from "chat";

export async function deployApproval(opts: { thread: Thread; version: string }) {
  "use workflow";

  const { approved, user, timedOut } = await requestApproval(opts.thread, {
    title: `Deploy ${opts.version}?`,
    fields: { Version: opts.version },
    timeout: "24h",
  });

  if (approved) {
    await deploy(opts.version);
  }
}

async function deploy(version: string) {
  "use step";
  // Trigger your deploy here.
}

Start the workflow from any handler. Thread instances serialize across the workflow boundary automatically:

import { start } from "workflow/api";
import { deployApproval } from "@/workflows/deploy";

bot.onNewMention(async (thread, message) => {
  await start(deployApproval, [{ thread, version: "v1.2.3" }]);
});

Install the optional workflow peer dependency and configure your framework for Workflow SDK. Then register your Chat instance as a singleton at startup so threads can be revived on the other side of the workflow boundary:

chat.registerSingleton();
OptionTypeDescription
titlestringCard title (required)
subtitlestringRendered under the title
descriptionstringBody text (markdown) above the fields
fieldsRecord<string, string>Key/value pairs rendered as a bold-label list
approveLabel / denyLabelstringButton labels. Default: "Approve" / "Deny"
timeoutnumber | `${number}${"ms"|"s"|"m"|"h"|"d"}`Give up after this long. Omit to wait indefinitely
approversstring[]User IDs allowed to decide. Clicks from others post a notice and keep waiting
PropertyTypeDescription
approvedbooleanTrue when the approve button was clicked
timedOutbooleanTrue when timeout elapsed with no decision
user{ id: string; name?: string }Who decided. Absent on timeout

Once a decision lands (or the timeout elapses), the card is edited in place: the buttons are removed and replaced with an outcome line, leaving an audit trail in the thread and preventing stale clicks.

Anyone who can see the card can decide the approval. The click itself is trustworthy: Chat SDK verifies the platform's signature on the incoming event, and the button's callback URL never reaches the client. So the user.id on the result really is the person who clicked.

If only certain people should decide, pass approvers with their user IDs. When anyone else clicks, the bot posts a notice in the thread and the workflow keeps waiting:

await requestApproval(thread, {
  title: `Deploy ${version}?`,
  approvers: ["U_ALICE", "U_BOB"],
});

Set approvers for anything consequential.

The card builders are exported for cases the wrapper doesn't cover, such as posting an approval card whose buttons target a webhook you manage yourself:

import { buildApprovalCard, buildResolvedCard } from "chat/workflow";

const card = buildApprovalCard(
  { title: "Deploy?", fields: { Version: "v1.2.3" } },
  webhookUrl
);

The Human-in-the-Loop guide walks through the underlying pattern, including multi-stage approvals and validating approvers with createHook().

PreviousActionsNextSlash Commands