chat
Version:
Unified chat abstraction for Slack, Teams, Google Chat, and Discord
75 lines (56 loc) • 2.63 kB
text/mdx
---
title: Direct Messages
description: Initiate DM conversations with users programmatically.
type: guide
prerequisites:
- /docs/usage
---
Open direct message conversations with users using `bot.openDM()`. For globally recognizable user IDs, the adapter is automatically inferred from the ID format.
DMs behave slightly differently from channel messages:
- **Direct message handlers** — if you register `onDirectMessage`, every incoming DM routes there before `onSubscribedMessage`, `onNewMention`, and pattern handlers. This keeps DM-centric flows like WhatsApp conversations, Telegram DMs, and web chat on one consistent handler.
- **Mention fallback** — if no `onDirectMessage` handlers are registered, DMs continue through normal routing. Unsubscribed DMs are treated as mentions, so existing `onNewMention` bots keep working without requiring the user to @-mention the bot.
- **Per-conversation threading** — Each top-level DM starts a new conversation. Thread replies within a DM continue the same conversation, giving you the same per-thread isolation as channels.
```typescript title="lib/bot.ts" lineNumbers
bot.onDirectMessage(async (thread, message) => {
await thread.post(`You said: ${message.text}`);
});
```
The most common pattern — use the `author` from an incoming message:
```typescript title="lib/bot.ts" lineNumbers
bot.onSubscribedMessage(async (thread, message) => {
if (message.text === "DM me") {
const dmThread = await bot.openDM(message.author);
await dmThread.post("Hello! This is a private message.");
}
});
```
Pass a user ID string directly. The adapter is inferred from the ID format:
```typescript title="lib/bot.ts"
const dmThread = await bot.openDM("U1234567890"); // Slack
```
| Format | Platform |
|--------|----------|
| `U...` / `W...` | Slack |
| `29:...` | Teams |
| `users/...` | Google Chat |
| Numeric ID | Discord or Telegram |
<Callout type="info">
Numeric IDs can be ambiguous when multiple numeric-ID adapters are registered. For platforms whose user IDs are not globally distinguishable, call the adapter directly and wrap the returned thread ID with `bot.thread()`.
</Callout>
```typescript title="lib/bot.ts"
const threadId = await bot.getAdapter("whatsapp").openDM("15551234567");
const dmThread = bot.thread(threadId);
```
```typescript title="lib/bot.ts" lineNumbers
bot.onSubscribedMessage(async (thread, message) => {
if (thread.isDM) {
await thread.post("This is a private conversation.");
}
});
```