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

推荐订阅源

O
OpenAI News
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园_首页
博客园 - 三生石上(FineUI控件)
美团技术团队
博客园 - 叶小钗
博客园 - 司徒正美
Jina AI
Jina AI
Apple Machine Learning Research
Apple Machine Learning Research
The Cloudflare Blog
博客园 - 聂微东
博客园 - 【当耐特】
罗磊的独立博客
月光博客
月光博客
WordPress大学
WordPress大学
Last Week in AI
Last Week in AI
小众软件
小众软件
P
Privacy International News Feed
V
V2EX
T
The Exploit Database - CXSecurity.com
有赞技术团队
有赞技术团队
T
Tailwind CSS Blog
A
Arctic Wolf
T
Threatpost
博客园 - Franky
The Hacker News
The Hacker News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
G
GRAHAM CLULEY
H
Hacker News: Front Page
雷峰网
雷峰网
C
Cybersecurity and Infrastructure Security Agency CISA
J
Java Code Geeks
P
Palo Alto Networks Blog
H
Heimdal Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
Vulnerabilities – Threatpost
The Last Watchdog
The Last Watchdog
T
Tor Project blog
爱范儿
爱范儿
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
IT之家
IT之家
C
Cisco Blogs
www.infosecurity-magazine.com
www.infosecurity-magazine.com
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
腾讯CDC
V
Visual Studio Blog
S
Schneier on Security
大猫的无限游戏
大猫的无限游戏
T
Threat Research - Cisco Blogs

Chat SDK Documentation

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
Teams Low-Level APIs | Chat SDK
Vercel · 2026-06-16 · via Chat SDK Documentation

Use Teams Activity parsing, Bot Connector calls, Graph reads, formatting, Adaptive Cards, and Task Module helpers without the full Chat runtime.

The Teams adapter is the right default for most bots. It validates Bot Framework requests through the Microsoft Teams SDK, parses Activities, stores conversation context, renders Adaptive Cards, reads Graph history, and routes events through Chat.

Use the low-level Teams subpaths when your app already owns routing, state, sessions, or workflow execution and only needs Teams-specific primitives.

SubpathUse for
@chat-adapter/teams/webhookParse Bot Framework Activity JSON, classify common payloads, and extract continuation data
@chat-adapter/teams/apiFetch-based Bot Connector calls for messages, updates, deletes, typing, and conversations
@chat-adapter/teams/graphFetch-based Microsoft Graph reads for chats, channels, channel messages, and replies
@chat-adapter/teams/formatTeams HTML, mention, Markdown-ish, and emoji string helpers
@chat-adapter/teams/cardsRuntime-free conversion from simple card objects and input requests to Adaptive Cards
@chat-adapter/teams/modalsRuntime-free Task Module Adaptive Card helpers and submit parsing

The webhook subpath parses Activities only. It does not verify Microsoft Bot Framework JWTs. For production request validation, use createTeamsAdapter or the Microsoft Teams SDK request pipeline before handing the Activity to these helpers.

Teams sends Bot Framework Activity JSON. readTeamsWebhook reads the request body and classifies the Activity, but it intentionally does not perform JWT validation.

import { postTeamsMessage } from "@chat-adapter/teams/api";
import { readTeamsWebhook } from "@chat-adapter/teams/webhook";

export async function POST(request: Request) {
  const payload = await readTeamsWebhook(request, {
    botAppId: process.env.TEAMS_APP_ID,
  });

  if (payload.kind === "message") {
    await postTeamsMessage({
      conversationId: payload.continuation.conversationId,
      credentials: {
        appId: process.env.TEAMS_APP_ID!,
        appPassword: process.env.TEAMS_APP_PASSWORD!,
        tenantId: payload.continuation.tenantId,
      },
      markdownText: `received: ${payload.text}`,
      serviceUrl: payload.continuation.serviceUrl,
    });
  }

  return new Response(null, { status: 200 });
}

parseTeamsWebhookBody returns typed payloads:

KindTeams surface
messageMessage activities
message_reactionReaction activities
card_actionAdaptive Card actions and Action.Submit message activities
dialog_openTask Module task/fetch invokes
dialog_submitTask Module task/submit invokes
conversation_updateConversation membership and install context updates
installation_updateApp installation updates
unsupportedValid Activities not normalized by this helper yet

Message-like payloads include continuation, which contains provider-native reply context:

type TeamsContinuation = {
  activityId?: string;
  channelId?: string;
  conversationId: string;
  replyToId?: string;
  serviceUrl: string;
  teamId?: string;
  tenantId?: string;
};

This is not a Chat SDK Thread. It is the durable Teams data you need to reply later with @chat-adapter/teams/api.

The API subpath calls the Bot Framework Connector REST API with fetch. It does not import @microsoft/teams.apps.

import {
  deleteTeamsMessage,
  postTeamsMessage,
  sendTeamsTyping,
  updateTeamsMessage,
} from "@chat-adapter/teams/api";

const credentials = {
  appId: process.env.TEAMS_APP_ID!,
  appPassword: process.env.TEAMS_APP_PASSWORD!,
  tenantId: process.env.TEAMS_APP_TENANT_ID!,
};

const posted = await postTeamsMessage({
  conversationId: "19:abc@thread.tacv2",
  credentials,
  markdownText: "**hello**",
  serviceUrl: "https://smba.trafficmanager.net/teams/",
});

await updateTeamsMessage({
  conversationId: "19:abc@thread.tacv2",
  credentials,
  messageId: posted.id,
  serviceUrl: "https://smba.trafficmanager.net/teams/",
  text: "updated",
});

await sendTeamsTyping({
  conversationId: "19:abc@thread.tacv2",
  credentials,
  serviceUrl: "https://smba.trafficmanager.net/teams/",
});

await deleteTeamsMessage({
  conversationId: "19:abc@thread.tacv2",
  credentials,
  messageId: posted.id,
  serviceUrl: "https://smba.trafficmanager.net/teams/",
});

Use accessToken in credentials when your runtime already owns Microsoft token acquisition. A direct accessToken must be scoped for the API you call it against — the Bot Connector subpath (/api) needs a https://api.botframework.com/.default token, while the Graph subpath (/graph) needs a https://graph.microsoft.com/.default token. Passing the same token to both will fail against one of them. When you supply appId/appPassword instead, each subpath requests the correct scope for you.

The Graph subpath reads Teams history with explicit Graph IDs. Unlike TeamsAdapter, it does not use the adapter state cache to infer teamId, channelId, or chatId.

import { listTeamsChannelMessages } from "@chat-adapter/teams/graph";

const messages = await listTeamsChannelMessages({
  channelId: "19:channel@thread.tacv2",
  credentials: {
    appId: process.env.TEAMS_APP_ID!,
    appPassword: process.env.TEAMS_APP_PASSWORD!,
    tenantId: process.env.TEAMS_APP_TENANT_ID!,
  },
  limit: 25,
  teamId: "19:team@thread.tacv2",
});

const latestText = messages.items[0]?.text;

Graph reads require the same Microsoft Graph permissions as the full adapter. Channel and group-chat reads can use RSC permissions; DM reads require Azure AD application permissions such as Chat.Read.All.

Teams renders message text as HTML. The format subpath provides small helpers for custom runtimes:

import {
  formatTeamsMention,
  markdownToTeamsHtml,
  teamsHtmlToMarkdown,
} from "@chat-adapter/teams/format";

const html = markdownToTeamsHtml(
  `${formatTeamsMention("Ada")} approved **deploy v2.4.1**`
);
const markdown = teamsHtmlToMarkdown("<p>Hello <strong>world</strong></p>");

Use the full TeamsFormatConverter from @chat-adapter/teams when you need mdast conversion inside Chat SDK.

The cards subpath converts simple card objects into Adaptive Card JSON without importing the full chat JSX runtime.

import {
  cardToAdaptiveCard,
  cardToTeamsFallbackText,
} from "@chat-adapter/teams/cards";
import { postTeamsMessage } from "@chat-adapter/teams/api";

const card = {
  children: [
    { content: "deploy v2.4.1?", type: "text" },
    {
      children: [
        { id: "approve", label: "Approve", style: "primary", type: "button" },
        { id: "deny", label: "Deny", style: "danger", type: "button" },
      ],
      type: "actions",
    },
  ],
  title: "Deployment",
  type: "card",
} as const;

await postTeamsMessage({
  adaptiveCard: cardToAdaptiveCard(card),
  conversationId: payload.continuation.conversationId,
  credentials,
  serviceUrl: payload.continuation.serviceUrl,
  text: cardToTeamsFallbackText(card),
});

Use the full Chat SDK card JSX when you want cross-platform rendering. Use @chat-adapter/teams/cards when you are building a Teams-only runtime and want Adaptive Card output directly.

Teams Task Modules are invoke-based dialogs backed by Adaptive Cards. The modals subpath builds those cards and parses submit data.

import {
  modalToAdaptiveCard,
  parseTeamsDialogSubmitValues,
  toTeamsTaskModuleResponse,
} from "@chat-adapter/teams/modals";

const modal = {
  callbackId: "deploy",
  children: [
    { content: "Why deploy now?", type: "text" },
    { id: "reason", label: "Reason", type: "text_input" },
  ],
  title: "Deploy",
  type: "modal",
} as const;

const card = modalToAdaptiveCard(modal, { contextId: "deploy-1" });
const values = parseTeamsDialogSubmitValues(payload.value);

return Response.json(
  toTeamsTaskModuleResponse({ action: "update", modal }, { contextId: "deploy-1" })
);

The low-level Teams subpaths are designed to avoid the full runtime import graph:

  • no chat import
  • no @chat-adapter/shared import
  • no @microsoft/teams.apps import
  • no full adapter import

The package still installs the full Teams adapter dependencies. The subpaths keep your source and bundle imports clean, but they are not a package-size split.