Vercel Chat SDK

View as Markdown

Vercel Chat SDK is a TypeScript framework for building multi-channel bots: one bot handler responds to messages across Slack, Teams, Discord, and other channels through adapters. The @getdial/chat-sdk-adapter package plugs Dial into that adapter surface so the same bot handler also answers phone traffic — SMS, MMS, iMessage, and inbound voice-call transcripts — with replies sent back over the phone through Dial.

Written and maintained by Dial. Published on npm as @getdial/chat-sdk-adapter. Source at GetDial-AI/chat-sdk-adapter.

Install

$npm install @getdial/chat-sdk-adapter chat

chat is Vercel’s Chat SDK; both packages are required. Node 18+.

Usage

1import { Chat } from "chat";
2import { createMemoryState } from "@chat-adapter/state-memory";
3import { createDialAdapter } from "@getdial/chat-sdk-adapter";
4
5const bot = new Chat({
6 userName: "mybot",
7 adapters: {
8 dial: createDialAdapter(), // reads DIAL_* env vars; explicit config wins
9 },
10 state: createMemoryState(), // swap for Redis/Postgres in production
11});
12
13bot.onNewMention(async (thread, message) => {
14 await thread.post(`heard you: ${message.text}`);
15});
16
17// Bind the webhook endpoint on whichever HTTP framework you use:
18app.post("/webhook/dial", (req) => bot.webhooks.dial(req));

The bot.webhooks.dial(request) call routes the inbound HTTP request through the adapter’s signature verification, envelope parsing, and Chat SDK’s per-thread state — your handler runs identically to a Slack or Teams mention.

Configuration

createDialAdapter(config?) reads the environment when a field is omitted. Explicit config values win.

FieldEnv varRequiredWhat it is
apiKeyDIAL_API_KEYDial API key (sk_live_…). Mint it from the dashboard.
fromNumberIdDIAL_FROM_NUMBER_IDDial’s ID of the phone number the bot sends from. Copy it from the Phone Numbers page, or dial number list --json.
webhookSecretDIAL_WEBHOOK_SECRETprodHMAC-SHA256 signing secret Dial issued when the webhook subscription was created. Required in production; when set, incoming requests are verified against X-Dial-Signature and rejected 401 on mismatch.
apiBaseUrlDIAL_API_URLOverride the Dial API host. Defaults to https://api.getdial.ai.
botNameBOT_USERNAMEDisplay name Chat SDK uses for the bot. Defaults to "bot".
loggerChat SDK Logger instance. Defaults to ConsoleLogger("info").child("dial").

Webhook setup

Point a Dial webhook subscription at the endpoint you handed to bot.webhooks.dial. Create the subscription from the Webhooks page or over the API:

$curl -X POST https://api.getdial.ai/api/v1/webhooks \
> -H "Authorization: Bearer $DIAL_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{ "targetUrl": "https://your-bot.example.com/webhook/dial", "eventTypes": ["*"] }'

The whsec_… secret returned at creation goes in DIAL_WEBHOOK_SECRET. See the Webhooks reference for retries, signature format, and event types.

What the adapter carries

DirectionChannelTextMedia
InboundSMS
InboundMMS✅ (image / video / audio / file)
InboundiMessage
InboundVoice call✅ (as transcript)
OutboundSMS / MMS / iMessage✅ (via attachment URLs)

Voice calls surface to the bot as their transcript, delivered via the call.transcribed event. Very short calls that never generate a transcript don’t fire an onNewMention.

Threads

A Chat SDK thread here is a pair of phone numbers — your Dial-owned number and the peer’s — encoded as:

dial:{yourDialNumber}:{peerNumber}

Every distinct pair is a distinct thread. Chat SDK’s per-thread state (conversation history, subscriptions, locks) is scoped per-pair, so multiple concurrent conversations don’t leak into each other.

Design notes

  • Outbound sends and transcript fetches go through the official @getdial/sdk Node SDK — no hand-rolled HTTP.
  • Signature verification uses Node’s built-in crypto.createHmac + timingSafeEqual, matching the exact primitive Dial’s server signs with.
  • ESM-only, TypeScript-first. The adapter ships dist/index.js + dist/index.d.ts — no source, no tests, no node_modules.
  • Peer-depends on chat ^4.20.0 — install chat alongside this adapter.

Learn more