mirror of
https://github.com/vercel/chat.git
synced 2026-09-14 18:32:29 +08:00
d114ebfabf
* toAIMessages docs improvements * toAIMessages docs improvements
212 lines
5.8 KiB
Plaintext
212 lines
5.8 KiB
Plaintext
---
|
|
title: Message
|
|
description: Normalized message format with text, AST, author, and metadata.
|
|
type: reference
|
|
---
|
|
|
|
Incoming messages are normalized across all platforms into a consistent `Message` object.
|
|
|
|
```typescript
|
|
import { Message } from "chat";
|
|
```
|
|
|
|
## Properties
|
|
|
|
<TypeTable
|
|
type={{
|
|
id: {
|
|
description: 'Platform-specific message ID.',
|
|
type: 'string',
|
|
},
|
|
threadId: {
|
|
description: 'Thread ID in adapter:channel:thread format.',
|
|
type: 'string',
|
|
},
|
|
text: {
|
|
description: 'Plain text content with all formatting stripped.',
|
|
type: 'string',
|
|
},
|
|
formatted: {
|
|
description: 'mdast AST representation — the canonical format for processing.',
|
|
type: 'Root',
|
|
},
|
|
raw: {
|
|
description: 'Original platform-specific payload (escape hatch).',
|
|
type: 'unknown',
|
|
},
|
|
author: {
|
|
description: 'Message author info.',
|
|
type: 'Author',
|
|
},
|
|
metadata: {
|
|
description: 'Timestamps and edit status.',
|
|
type: 'MessageMetadata',
|
|
},
|
|
attachments: {
|
|
description: 'File attachments.',
|
|
type: 'Attachment[]',
|
|
},
|
|
links: {
|
|
description: 'Links found in the message, with optional preview metadata.',
|
|
type: 'LinkPreview[]',
|
|
},
|
|
isMention: {
|
|
description: 'Whether the bot was @-mentioned in this message.',
|
|
type: 'boolean | undefined',
|
|
},
|
|
}}
|
|
/>
|
|
|
|
## Author
|
|
|
|
<TypeTable
|
|
type={{
|
|
userId: {
|
|
description: 'Platform-specific user ID.',
|
|
type: 'string',
|
|
},
|
|
userName: {
|
|
description: 'Username/handle for @-mentions.',
|
|
type: 'string',
|
|
},
|
|
fullName: {
|
|
description: 'Display name.',
|
|
type: 'string',
|
|
},
|
|
isBot: {
|
|
description: 'Whether the author is a bot.',
|
|
type: 'boolean | "unknown"',
|
|
},
|
|
isMe: {
|
|
description: 'Whether the author is this bot.',
|
|
type: 'boolean',
|
|
},
|
|
}}
|
|
/>
|
|
|
|
### How `isMe` works
|
|
|
|
Each adapter detects whether a message came from the bot itself. The detection logic varies by platform:
|
|
|
|
| Platform | Detection method |
|
|
|----------|-----------------|
|
|
| Slack | Checks `event.user === botUserId` (primary), then `event.bot_id === botId` (for `bot_message` subtypes). Both IDs are fetched during initialization via `auth.test`. |
|
|
| Teams | Checks `activity.from.id === appId` (exact match), then checks if `activity.from.id` ends with `:{appId}` (handles `28:{appId}` format). |
|
|
| Google Chat | Checks `message.sender.name === botUserId`. The bot user ID is learned dynamically from message annotations when the bot is first @-mentioned. |
|
|
|
|
<Callout type="info">
|
|
All adapters return `false` if the bot ID isn't known yet. This is a safe default that prevents the bot from ignoring messages it should process.
|
|
</Callout>
|
|
|
|
## MessageMetadata
|
|
|
|
<TypeTable
|
|
type={{
|
|
dateSent: {
|
|
description: 'When the message was sent.',
|
|
type: 'Date',
|
|
},
|
|
edited: {
|
|
description: 'Whether the message has been edited.',
|
|
type: 'boolean',
|
|
},
|
|
editedAt: {
|
|
description: 'When the message was last edited.',
|
|
type: 'Date | undefined',
|
|
},
|
|
}}
|
|
/>
|
|
|
|
## Attachment
|
|
|
|
<TypeTable
|
|
type={{
|
|
type: {
|
|
description: 'Attachment type.',
|
|
type: '"image" | "file" | "video" | "audio"',
|
|
},
|
|
url: {
|
|
description: 'URL to the file.',
|
|
type: 'string | undefined',
|
|
},
|
|
data: {
|
|
description: 'Binary data (if already fetched).',
|
|
type: 'Buffer | Blob | undefined',
|
|
},
|
|
name: {
|
|
description: 'Filename.',
|
|
type: 'string | undefined',
|
|
},
|
|
mimeType: {
|
|
description: 'MIME type.',
|
|
type: 'string | undefined',
|
|
},
|
|
size: {
|
|
description: 'File size in bytes.',
|
|
type: 'number | undefined',
|
|
},
|
|
'fetchData()': {
|
|
description: 'Fetch the attachment data. Handles platform auth automatically.',
|
|
type: '() => Promise<Buffer> | undefined',
|
|
},
|
|
}}
|
|
/>
|
|
|
|
## LinkPreview
|
|
|
|
Links found in incoming messages are extracted and exposed as `LinkPreview` objects. On platforms that support it (currently Slack), links pointing to other chat messages include a `fetchMessage()` callback to retrieve the full linked message.
|
|
|
|
<TypeTable
|
|
type={{
|
|
url: {
|
|
description: 'The URL.',
|
|
type: 'string',
|
|
},
|
|
title: {
|
|
description: 'Title from unfurl metadata (if available).',
|
|
type: 'string | undefined',
|
|
},
|
|
description: {
|
|
description: 'Description from unfurl metadata (if available).',
|
|
type: 'string | undefined',
|
|
},
|
|
imageUrl: {
|
|
description: 'Preview image URL (if available).',
|
|
type: 'string | undefined',
|
|
},
|
|
siteName: {
|
|
description: 'Site name, e.g. "Vercel" (if available).',
|
|
type: 'string | undefined',
|
|
},
|
|
'fetchMessage()': {
|
|
description: 'Fetch the linked chat message. Available when the URL points to a message on the same platform (e.g. a Slack message link).',
|
|
type: '() => Promise<Message> | undefined',
|
|
},
|
|
}}
|
|
/>
|
|
|
|
<Callout type="info">
|
|
When using [`toAiMessages()`](/docs/api/to-ai-messages), link metadata is automatically appended to the message content. Embedded message links are labeled as `[Embedded message: ...]` so the AI model understands the context.
|
|
</Callout>
|
|
|
|
### Platform support
|
|
|
|
| Platform | Link extraction | `fetchMessage()` |
|
|
|----------|----------------|-------------------|
|
|
| Slack | URLs from `rich_text` blocks or `<url>` text patterns | Slack message links (`*.slack.com/archives/...`) |
|
|
| Others | Not yet — `links` is always `[]` | — |
|
|
|
|
## Serialization
|
|
|
|
Messages can be serialized for workflow engines and external systems.
|
|
|
|
```typescript
|
|
// Serialize
|
|
const json = message.toJSON();
|
|
|
|
// Deserialize
|
|
const restored = Message.fromJSON(json);
|
|
```
|
|
|
|
The serialized format converts `Date` fields to ISO strings and omits non-serializable fields like `data` buffers and `fetchData` functions.
|