@chat-adapter/discord 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +9 -0
- package/README.md +231 -0
- package/dist/index.d.ts +301 -0
- package/dist/index.js +1569 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Vercel, Inc.
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
6
|
+
|
|
7
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
8
|
+
|
|
9
|
+
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
# @chat-adapter/discord
|
|
2
|
+
|
|
3
|
+
Discord adapter for the [chat](https://github.com/vercel-labs/chat) SDK.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install chat @chat-adapter/discord
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { Chat } from "chat";
|
|
15
|
+
import { createDiscordAdapter } from "@chat-adapter/discord";
|
|
16
|
+
|
|
17
|
+
const chat = new Chat({
|
|
18
|
+
userName: "mybot",
|
|
19
|
+
adapters: {
|
|
20
|
+
discord: createDiscordAdapter({
|
|
21
|
+
botToken: process.env.DISCORD_BOT_TOKEN!,
|
|
22
|
+
publicKey: process.env.DISCORD_PUBLIC_KEY!,
|
|
23
|
+
applicationId: process.env.DISCORD_APPLICATION_ID!,
|
|
24
|
+
// Optional: trigger on role mentions too
|
|
25
|
+
mentionRoleIds: process.env.DISCORD_MENTION_ROLE_IDS?.split(","),
|
|
26
|
+
}),
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Handle @mentions
|
|
31
|
+
chat.onNewMention(async (thread, message) => {
|
|
32
|
+
await thread.post("Hello from Discord!");
|
|
33
|
+
});
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Configuration
|
|
37
|
+
|
|
38
|
+
| Option | Required | Description |
|
|
39
|
+
|--------|----------|-------------|
|
|
40
|
+
| `botToken` | Yes | Discord bot token |
|
|
41
|
+
| `publicKey` | Yes | Discord application public key (for webhook signature verification) |
|
|
42
|
+
| `applicationId` | Yes | Discord application ID |
|
|
43
|
+
| `mentionRoleIds` | No | Array of role IDs that should trigger mention handlers |
|
|
44
|
+
|
|
45
|
+
## Discord Application Setup
|
|
46
|
+
|
|
47
|
+
### 1. Create Application
|
|
48
|
+
|
|
49
|
+
1. Go to the [Discord Developer Portal](https://discord.com/developers/applications)
|
|
50
|
+
2. Click **New Application** and give it a name
|
|
51
|
+
3. Note the **Application ID** from the General Information page
|
|
52
|
+
4. Copy the **Public Key** from the General Information page
|
|
53
|
+
|
|
54
|
+
### 2. Create Bot
|
|
55
|
+
|
|
56
|
+
1. Go to the **Bot** section in the left sidebar
|
|
57
|
+
2. Click **Reset Token** to generate a new bot token
|
|
58
|
+
3. Copy and save the token (you won't see it again)
|
|
59
|
+
4. Enable these **Privileged Gateway Intents**:
|
|
60
|
+
- Message Content Intent
|
|
61
|
+
- Server Members Intent (if needed)
|
|
62
|
+
|
|
63
|
+
### 3. Configure Interactions Endpoint
|
|
64
|
+
|
|
65
|
+
1. Go to **General Information**
|
|
66
|
+
2. Set **Interactions Endpoint URL** to: `https://your-domain.com/api/webhooks/discord`
|
|
67
|
+
3. Discord will send a PING request to verify the endpoint
|
|
68
|
+
|
|
69
|
+
### 4. Add Bot to Server
|
|
70
|
+
|
|
71
|
+
1. Go to **OAuth2 > URL Generator**
|
|
72
|
+
2. Select scopes: `bot`, `applications.commands`
|
|
73
|
+
3. Select bot permissions:
|
|
74
|
+
- Send Messages
|
|
75
|
+
- Send Messages in Threads
|
|
76
|
+
- Create Public Threads
|
|
77
|
+
- Read Message History
|
|
78
|
+
- Add Reactions
|
|
79
|
+
- Attach Files
|
|
80
|
+
4. Copy the generated URL and open it to add the bot to your server
|
|
81
|
+
|
|
82
|
+
## Environment Variables
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
# Required
|
|
86
|
+
DISCORD_BOT_TOKEN=your-bot-token
|
|
87
|
+
DISCORD_PUBLIC_KEY=your-application-public-key
|
|
88
|
+
DISCORD_APPLICATION_ID=your-application-id
|
|
89
|
+
|
|
90
|
+
# Optional: trigger on role mentions (comma-separated)
|
|
91
|
+
DISCORD_MENTION_ROLE_IDS=1234567890,0987654321
|
|
92
|
+
|
|
93
|
+
# For Gateway mode with Vercel Cron
|
|
94
|
+
CRON_SECRET=your-random-secret
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Architecture: HTTP Interactions vs Gateway
|
|
98
|
+
|
|
99
|
+
Discord has two ways to receive events:
|
|
100
|
+
|
|
101
|
+
### HTTP Interactions (Default)
|
|
102
|
+
- Receives button clicks, slash commands, and verification pings
|
|
103
|
+
- Works out of the box with serverless
|
|
104
|
+
- **Does NOT receive regular messages** - only interactions
|
|
105
|
+
|
|
106
|
+
### Gateway WebSocket (Required for Messages)
|
|
107
|
+
- Required to receive regular messages and reactions
|
|
108
|
+
- Requires a persistent connection
|
|
109
|
+
- In serverless environments, use a cron job to maintain the connection
|
|
110
|
+
|
|
111
|
+
## Gateway Setup for Serverless
|
|
112
|
+
|
|
113
|
+
For Vercel/serverless deployments, set up a cron job to maintain the Gateway connection:
|
|
114
|
+
|
|
115
|
+
### 1. Create Gateway Route
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
// app/api/discord/gateway/route.ts
|
|
119
|
+
import { NextResponse } from "next/server";
|
|
120
|
+
import { after } from "next/server";
|
|
121
|
+
import { discord } from "@/lib/bot";
|
|
122
|
+
|
|
123
|
+
export const maxDuration = 800; // Maximum Vercel function duration
|
|
124
|
+
|
|
125
|
+
export async function GET(request: Request): Promise<Response> {
|
|
126
|
+
// Validate cron secret
|
|
127
|
+
const cronSecret = process.env.CRON_SECRET;
|
|
128
|
+
if (!cronSecret) {
|
|
129
|
+
return new Response("CRON_SECRET not configured", { status: 500 });
|
|
130
|
+
}
|
|
131
|
+
const authHeader = request.headers.get("authorization");
|
|
132
|
+
if (authHeader !== `Bearer ${cronSecret}`) {
|
|
133
|
+
return new Response("Unauthorized", { status: 401 });
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Start Gateway listener (runs for 10 minutes)
|
|
137
|
+
const durationMs = 600 * 1000;
|
|
138
|
+
const webhookUrl = `https://${process.env.VERCEL_URL}/api/webhooks/discord`;
|
|
139
|
+
|
|
140
|
+
return discord.startGatewayListener(
|
|
141
|
+
{ waitUntil: (task) => after(() => task) },
|
|
142
|
+
durationMs,
|
|
143
|
+
undefined,
|
|
144
|
+
webhookUrl
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 2. Configure Vercel Cron
|
|
150
|
+
|
|
151
|
+
Create `vercel.json`:
|
|
152
|
+
|
|
153
|
+
```json
|
|
154
|
+
{
|
|
155
|
+
"crons": [
|
|
156
|
+
{
|
|
157
|
+
"path": "/api/discord/gateway",
|
|
158
|
+
"schedule": "*/9 * * * *"
|
|
159
|
+
}
|
|
160
|
+
]
|
|
161
|
+
}
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This runs every 9 minutes, ensuring overlap with the 10-minute listener duration.
|
|
165
|
+
|
|
166
|
+
### 3. Add Environment Variables
|
|
167
|
+
|
|
168
|
+
Add `CRON_SECRET` to your Vercel project settings.
|
|
169
|
+
|
|
170
|
+
## Role Mentions
|
|
171
|
+
|
|
172
|
+
By default, only direct user mentions (`@BotName`) trigger `onNewMention` handlers. To also trigger on role mentions (e.g., `@AI`):
|
|
173
|
+
|
|
174
|
+
1. Create a role in your Discord server (e.g., "AI")
|
|
175
|
+
2. Assign the role to your bot
|
|
176
|
+
3. Copy the role ID (right-click role in server settings with Developer Mode enabled)
|
|
177
|
+
4. Add the role ID to `DISCORD_MENTION_ROLE_IDS`
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
createDiscordAdapter({
|
|
181
|
+
botToken: process.env.DISCORD_BOT_TOKEN!,
|
|
182
|
+
publicKey: process.env.DISCORD_PUBLIC_KEY!,
|
|
183
|
+
applicationId: process.env.DISCORD_APPLICATION_ID!,
|
|
184
|
+
mentionRoleIds: ["1457473602180878604"], // Your role ID
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Features
|
|
189
|
+
|
|
190
|
+
- Message posting and editing
|
|
191
|
+
- Thread creation and management
|
|
192
|
+
- Reaction handling (add/remove/events)
|
|
193
|
+
- File attachments
|
|
194
|
+
- Rich embeds (cards with buttons)
|
|
195
|
+
- Action callbacks (button interactions)
|
|
196
|
+
- Direct messages
|
|
197
|
+
- Role mention support
|
|
198
|
+
|
|
199
|
+
## Testing
|
|
200
|
+
|
|
201
|
+
Run a local tunnel (e.g., ngrok) to test webhooks:
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
ngrok http 3000
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
Update the Interactions Endpoint URL in the Discord Developer Portal to your ngrok URL.
|
|
208
|
+
|
|
209
|
+
## Troubleshooting
|
|
210
|
+
|
|
211
|
+
### Bot not responding to messages
|
|
212
|
+
|
|
213
|
+
1. **Check Gateway connection**: Messages require the Gateway WebSocket, not just HTTP interactions
|
|
214
|
+
2. **Verify Message Content Intent**: Enable this in the Bot settings
|
|
215
|
+
3. **Check bot permissions**: Ensure the bot can read messages in the channel
|
|
216
|
+
|
|
217
|
+
### Role mentions not triggering
|
|
218
|
+
|
|
219
|
+
1. **Verify role ID**: Enable Developer Mode in Discord settings, then right-click the role
|
|
220
|
+
2. **Check mentionRoleIds config**: Ensure the role ID is in the array
|
|
221
|
+
3. **Confirm bot has the role**: The bot must have the role assigned to be mentioned via that role
|
|
222
|
+
|
|
223
|
+
### Signature verification failing
|
|
224
|
+
|
|
225
|
+
1. **Check public key format**: Should be a 64-character hex string (lowercase)
|
|
226
|
+
2. **Verify endpoint URL**: Must exactly match what's configured in Discord Developer Portal
|
|
227
|
+
3. **Check for body parsing**: Don't parse the request body before verification
|
|
228
|
+
|
|
229
|
+
## License
|
|
230
|
+
|
|
231
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
import { CardElement, BaseFormatConverter, AdapterPostableMessage, Root, Adapter, Logger, ChatInstance, WebhookOptions, RawMessage, EmojiValue, FetchOptions, FetchResult, ThreadInfo, Message, FormattedContent } from 'chat';
|
|
2
|
+
import { ButtonStyle, APIEmbed } from 'discord-api-types/v10';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Discord adapter types.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Discord adapter configuration.
|
|
10
|
+
*/
|
|
11
|
+
interface DiscordAdapterConfig {
|
|
12
|
+
/** Discord bot token */
|
|
13
|
+
botToken: string;
|
|
14
|
+
/** Discord application public key for webhook signature verification */
|
|
15
|
+
publicKey: string;
|
|
16
|
+
/** Discord application ID */
|
|
17
|
+
applicationId: string;
|
|
18
|
+
/** Role IDs that should trigger mention handlers (in addition to direct user mentions) */
|
|
19
|
+
mentionRoleIds?: string[];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Discord thread ID components.
|
|
23
|
+
* Used for encoding/decoding thread IDs.
|
|
24
|
+
*/
|
|
25
|
+
interface DiscordThreadId {
|
|
26
|
+
/** Guild ID, or "@me" for DMs */
|
|
27
|
+
guildId: string;
|
|
28
|
+
/** Channel ID */
|
|
29
|
+
channelId: string;
|
|
30
|
+
/** Thread ID (if message is in a thread) */
|
|
31
|
+
threadId?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Discord emoji.
|
|
35
|
+
*/
|
|
36
|
+
interface DiscordEmoji {
|
|
37
|
+
id?: string;
|
|
38
|
+
name: string;
|
|
39
|
+
animated?: boolean;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Discord button component.
|
|
43
|
+
*/
|
|
44
|
+
interface DiscordButton {
|
|
45
|
+
type: 2;
|
|
46
|
+
style: ButtonStyle;
|
|
47
|
+
label?: string;
|
|
48
|
+
emoji?: DiscordEmoji;
|
|
49
|
+
custom_id?: string;
|
|
50
|
+
url?: string;
|
|
51
|
+
disabled?: boolean;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Discord action row component.
|
|
55
|
+
*/
|
|
56
|
+
interface DiscordActionRow {
|
|
57
|
+
type: 1;
|
|
58
|
+
components: DiscordButton[];
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Discord Embed and Component converter for cross-platform cards.
|
|
63
|
+
*
|
|
64
|
+
* Converts CardElement to Discord Embeds and Action Row Components.
|
|
65
|
+
* @see https://discord.com/developers/docs/resources/message#embed-object
|
|
66
|
+
* @see https://discord.com/developers/docs/interactions/message-components
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Convert a CardElement to Discord message payload (embeds + components).
|
|
71
|
+
*/
|
|
72
|
+
declare function cardToDiscordPayload(card: CardElement): {
|
|
73
|
+
embeds: APIEmbed[];
|
|
74
|
+
components: DiscordActionRow[];
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Generate fallback text from a card element.
|
|
78
|
+
* Used when embeds aren't supported or for notifications.
|
|
79
|
+
*/
|
|
80
|
+
declare function cardToFallbackText(card: CardElement): string;
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Discord-specific format conversion using AST-based parsing.
|
|
84
|
+
*
|
|
85
|
+
* Discord uses standard markdown with some extensions:
|
|
86
|
+
* - Bold: **text** (standard)
|
|
87
|
+
* - Italic: *text* or _text_ (standard)
|
|
88
|
+
* - Strikethrough: ~~text~~ (standard GFM)
|
|
89
|
+
* - Links: [text](url) (standard)
|
|
90
|
+
* - User mentions: <@userId>
|
|
91
|
+
* - Channel mentions: <#channelId>
|
|
92
|
+
* - Role mentions: <@&roleId>
|
|
93
|
+
* - Custom emoji: <:name:id> or <a:name:id> (animated)
|
|
94
|
+
* - Spoiler: ||text||
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
declare class DiscordFormatConverter extends BaseFormatConverter {
|
|
98
|
+
/**
|
|
99
|
+
* Convert @mentions to Discord format in plain text.
|
|
100
|
+
* @name → <@name>
|
|
101
|
+
*/
|
|
102
|
+
private convertMentionsToDiscord;
|
|
103
|
+
/**
|
|
104
|
+
* Override renderPostable to convert @mentions in plain strings.
|
|
105
|
+
*/
|
|
106
|
+
renderPostable(message: AdapterPostableMessage): string;
|
|
107
|
+
/**
|
|
108
|
+
* Render an AST to Discord markdown format.
|
|
109
|
+
*/
|
|
110
|
+
fromAst(ast: Root): string;
|
|
111
|
+
/**
|
|
112
|
+
* Parse Discord markdown into an AST.
|
|
113
|
+
*/
|
|
114
|
+
toAst(discordMarkdown: string): Root;
|
|
115
|
+
private nodeToDiscordMarkdown;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Discord adapter for chat-sdk.
|
|
120
|
+
*
|
|
121
|
+
* Uses Discord's HTTP Interactions API (not Gateway WebSocket) for
|
|
122
|
+
* serverless compatibility. Webhook signature verification uses Ed25519.
|
|
123
|
+
*/
|
|
124
|
+
|
|
125
|
+
declare class DiscordAdapter implements Adapter<DiscordThreadId, unknown> {
|
|
126
|
+
readonly name = "discord";
|
|
127
|
+
readonly userName: string;
|
|
128
|
+
readonly botUserId?: string;
|
|
129
|
+
private botToken;
|
|
130
|
+
private publicKey;
|
|
131
|
+
private applicationId;
|
|
132
|
+
private mentionRoleIds;
|
|
133
|
+
private chat;
|
|
134
|
+
private logger;
|
|
135
|
+
private formatConverter;
|
|
136
|
+
constructor(config: DiscordAdapterConfig & {
|
|
137
|
+
logger: Logger;
|
|
138
|
+
userName?: string;
|
|
139
|
+
});
|
|
140
|
+
initialize(chat: ChatInstance): Promise<void>;
|
|
141
|
+
/**
|
|
142
|
+
* Handle incoming Discord webhook (HTTP Interactions or forwarded Gateway events).
|
|
143
|
+
*/
|
|
144
|
+
handleWebhook(request: Request, options?: WebhookOptions): Promise<Response>;
|
|
145
|
+
/**
|
|
146
|
+
* Verify Discord's Ed25519 signature using official discord-interactions library.
|
|
147
|
+
*/
|
|
148
|
+
private verifySignature;
|
|
149
|
+
/**
|
|
150
|
+
* Create a JSON response for Discord interactions.
|
|
151
|
+
*/
|
|
152
|
+
private respondToInteraction;
|
|
153
|
+
/**
|
|
154
|
+
* Handle MESSAGE_COMPONENT interactions (button clicks).
|
|
155
|
+
*/
|
|
156
|
+
private handleComponentInteraction;
|
|
157
|
+
/**
|
|
158
|
+
* Handle a forwarded Gateway event received via webhook.
|
|
159
|
+
*/
|
|
160
|
+
private handleForwardedGatewayEvent;
|
|
161
|
+
/**
|
|
162
|
+
* Handle a forwarded MESSAGE_CREATE event.
|
|
163
|
+
*/
|
|
164
|
+
private handleForwardedMessage;
|
|
165
|
+
/**
|
|
166
|
+
* Handle a forwarded REACTION_ADD or REACTION_REMOVE event.
|
|
167
|
+
*/
|
|
168
|
+
private handleForwardedReaction;
|
|
169
|
+
/**
|
|
170
|
+
* Post a message to a Discord channel or thread.
|
|
171
|
+
*/
|
|
172
|
+
postMessage(threadId: string, message: AdapterPostableMessage): Promise<RawMessage<unknown>>;
|
|
173
|
+
/**
|
|
174
|
+
* Create a Discord thread from a message.
|
|
175
|
+
*/
|
|
176
|
+
private createDiscordThread;
|
|
177
|
+
/**
|
|
178
|
+
* Truncate content to Discord's maximum length.
|
|
179
|
+
*/
|
|
180
|
+
private truncateContent;
|
|
181
|
+
/**
|
|
182
|
+
* Post a message with file attachments.
|
|
183
|
+
*/
|
|
184
|
+
private postMessageWithFiles;
|
|
185
|
+
/**
|
|
186
|
+
* Edit an existing Discord message.
|
|
187
|
+
*/
|
|
188
|
+
editMessage(threadId: string, messageId: string, message: AdapterPostableMessage): Promise<RawMessage<unknown>>;
|
|
189
|
+
/**
|
|
190
|
+
* Delete a Discord message.
|
|
191
|
+
*/
|
|
192
|
+
deleteMessage(threadId: string, messageId: string): Promise<void>;
|
|
193
|
+
/**
|
|
194
|
+
* Add a reaction to a Discord message.
|
|
195
|
+
*/
|
|
196
|
+
addReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
|
|
197
|
+
/**
|
|
198
|
+
* Remove a reaction from a Discord message.
|
|
199
|
+
*/
|
|
200
|
+
removeReaction(threadId: string, messageId: string, emoji: EmojiValue | string): Promise<void>;
|
|
201
|
+
/**
|
|
202
|
+
* Encode an emoji for use in Discord API URLs.
|
|
203
|
+
*/
|
|
204
|
+
private encodeEmoji;
|
|
205
|
+
/**
|
|
206
|
+
* Start typing indicator in a Discord channel or thread.
|
|
207
|
+
*/
|
|
208
|
+
startTyping(threadId: string): Promise<void>;
|
|
209
|
+
/**
|
|
210
|
+
* Fetch messages from a Discord channel or thread.
|
|
211
|
+
* If threadId includes a Discord thread ID, fetches from that thread channel.
|
|
212
|
+
*/
|
|
213
|
+
fetchMessages(threadId: string, options?: FetchOptions): Promise<FetchResult<unknown>>;
|
|
214
|
+
/**
|
|
215
|
+
* Fetch thread/channel information.
|
|
216
|
+
*/
|
|
217
|
+
fetchThread(threadId: string): Promise<ThreadInfo>;
|
|
218
|
+
/**
|
|
219
|
+
* Open a DM with a user.
|
|
220
|
+
*/
|
|
221
|
+
openDM(userId: string): Promise<string>;
|
|
222
|
+
/**
|
|
223
|
+
* Check if a thread is a DM.
|
|
224
|
+
*/
|
|
225
|
+
isDM(threadId: string): boolean;
|
|
226
|
+
/**
|
|
227
|
+
* Encode platform data into a thread ID string.
|
|
228
|
+
*/
|
|
229
|
+
encodeThreadId(platformData: DiscordThreadId): string;
|
|
230
|
+
/**
|
|
231
|
+
* Decode thread ID string back to platform data.
|
|
232
|
+
*/
|
|
233
|
+
decodeThreadId(threadId: string): DiscordThreadId;
|
|
234
|
+
/**
|
|
235
|
+
* Parse a Discord message into normalized format.
|
|
236
|
+
*/
|
|
237
|
+
parseMessage(raw: unknown): Message<unknown>;
|
|
238
|
+
/**
|
|
239
|
+
* Parse a Discord API message into normalized format.
|
|
240
|
+
*/
|
|
241
|
+
private parseDiscordMessage;
|
|
242
|
+
/**
|
|
243
|
+
* Determine attachment type from MIME type.
|
|
244
|
+
*/
|
|
245
|
+
private getAttachmentType;
|
|
246
|
+
/**
|
|
247
|
+
* Render formatted content to Discord markdown.
|
|
248
|
+
*/
|
|
249
|
+
renderFormatted(content: FormattedContent): string;
|
|
250
|
+
/**
|
|
251
|
+
* Make a request to the Discord API.
|
|
252
|
+
*/
|
|
253
|
+
private discordFetch;
|
|
254
|
+
/**
|
|
255
|
+
* Start Gateway WebSocket listener for receiving messages/mentions.
|
|
256
|
+
* Uses waitUntil to keep the connection alive for the specified duration.
|
|
257
|
+
*
|
|
258
|
+
* This is a workaround for serverless environments - the Gateway connection
|
|
259
|
+
* will stay alive for the duration, listening for messages.
|
|
260
|
+
*
|
|
261
|
+
* @param options - Webhook options with waitUntil function
|
|
262
|
+
* @param durationMs - How long to keep listening (default: 180000ms = 3 minutes)
|
|
263
|
+
* @param abortSignal - Optional AbortSignal to stop the listener early (e.g., when a new listener starts)
|
|
264
|
+
* @param webhookUrl - URL to forward Gateway events to (required for webhook forwarding mode)
|
|
265
|
+
* @returns Response indicating the listener was started
|
|
266
|
+
*/
|
|
267
|
+
startGatewayListener(options: WebhookOptions, durationMs?: number, abortSignal?: AbortSignal, webhookUrl?: string): Promise<Response>;
|
|
268
|
+
/**
|
|
269
|
+
* Run the Gateway listener for a specified duration.
|
|
270
|
+
*/
|
|
271
|
+
private runGatewayListener;
|
|
272
|
+
/**
|
|
273
|
+
* Set up legacy Gateway handlers for direct processing (when webhookUrl is not provided).
|
|
274
|
+
*/
|
|
275
|
+
private setupLegacyGatewayHandlers;
|
|
276
|
+
/**
|
|
277
|
+
* Forward a Gateway event to the webhook endpoint.
|
|
278
|
+
*/
|
|
279
|
+
private forwardGatewayEvent;
|
|
280
|
+
/**
|
|
281
|
+
* Handle a message received via the Gateway WebSocket.
|
|
282
|
+
*/
|
|
283
|
+
private handleGatewayMessage;
|
|
284
|
+
/**
|
|
285
|
+
* Handle a reaction received via the Gateway WebSocket.
|
|
286
|
+
*/
|
|
287
|
+
private handleGatewayReaction;
|
|
288
|
+
/**
|
|
289
|
+
* Normalize a Discord emoji to our standard EmojiValue format.
|
|
290
|
+
*/
|
|
291
|
+
private normalizeDiscordEmoji;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Create a Discord adapter instance.
|
|
295
|
+
*/
|
|
296
|
+
declare function createDiscordAdapter(config: DiscordAdapterConfig & {
|
|
297
|
+
logger: Logger;
|
|
298
|
+
userName?: string;
|
|
299
|
+
}): DiscordAdapter;
|
|
300
|
+
|
|
301
|
+
export { DiscordAdapter, type DiscordAdapterConfig, DiscordFormatConverter, DiscordFormatConverter as DiscordMarkdownConverter, type DiscordThreadId, cardToDiscordPayload, cardToFallbackText, createDiscordAdapter };
|