@framers/agentos-ext-channel-discord 0.1.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/dist/DiscordChannelAdapter.d.ts +33 -0
- package/dist/DiscordChannelAdapter.d.ts.map +1 -0
- package/dist/DiscordChannelAdapter.js +188 -0
- package/dist/DiscordChannelAdapter.js.map +1 -0
- package/dist/DiscordService.d.ts +48 -0
- package/dist/DiscordService.d.ts.map +1 -0
- package/dist/DiscordService.js +126 -0
- package/dist/DiscordService.js.map +1 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +74 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/sendMedia.d.ts +58 -0
- package/dist/tools/sendMedia.d.ts.map +1 -0
- package/dist/tools/sendMedia.js +53 -0
- package/dist/tools/sendMedia.js.map +1 -0
- package/dist/tools/sendMessage.d.ts +98 -0
- package/dist/tools/sendMessage.d.ts.map +1 -0
- package/dist/tools/sendMessage.js +94 -0
- package/dist/tools/sendMessage.js.map +1 -0
- package/manifest.json +39 -0
- package/package.json +31 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview IChannelAdapter implementation for Discord via discord.js.
|
|
3
|
+
*/
|
|
4
|
+
import type { IChannelAdapter, ChannelPlatform, ChannelCapability, ChannelAuthConfig, ChannelConnectionInfo, ChannelSendResult, MessageContent, ChannelEventHandler, ChannelEventType } from '@framers/agentos';
|
|
5
|
+
import { DiscordService } from './DiscordService';
|
|
6
|
+
export declare class DiscordChannelAdapter implements IChannelAdapter {
|
|
7
|
+
private readonly service;
|
|
8
|
+
readonly platform: ChannelPlatform;
|
|
9
|
+
readonly displayName = "Discord";
|
|
10
|
+
readonly capabilities: readonly ChannelCapability[];
|
|
11
|
+
private handlers;
|
|
12
|
+
private messageHandler;
|
|
13
|
+
constructor(service: DiscordService);
|
|
14
|
+
initialize(_auth: ChannelAuthConfig): Promise<void>;
|
|
15
|
+
shutdown(): Promise<void>;
|
|
16
|
+
getConnectionInfo(): ChannelConnectionInfo;
|
|
17
|
+
sendMessage(conversationId: string, content: MessageContent): Promise<ChannelSendResult>;
|
|
18
|
+
sendTypingIndicator(conversationId: string, isTyping: boolean): Promise<void>;
|
|
19
|
+
on(handler: ChannelEventHandler, eventTypes?: ChannelEventType[]): () => void;
|
|
20
|
+
editMessage(conversationId: string, messageId: string, content: MessageContent): Promise<void>;
|
|
21
|
+
deleteMessage(conversationId: string, messageId: string): Promise<void>;
|
|
22
|
+
addReaction(conversationId: string, messageId: string, emoji: string): Promise<void>;
|
|
23
|
+
getConversationInfo(conversationId: string): Promise<{
|
|
24
|
+
name?: string;
|
|
25
|
+
memberCount?: number;
|
|
26
|
+
isGroup: boolean;
|
|
27
|
+
metadata?: Record<string, unknown>;
|
|
28
|
+
}>;
|
|
29
|
+
private handleInboundMessage;
|
|
30
|
+
private resolveConversationType;
|
|
31
|
+
private emit;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=DiscordChannelAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiscordChannelAdapter.d.ts","sourceRoot":"","sources":["../src/DiscordChannelAdapter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EACjB,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,EACd,mBAAmB,EACnB,gBAAgB,EAKjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAGlD,qBAAa,qBAAsB,YAAW,eAAe;IAqB/C,OAAO,CAAC,QAAQ,CAAC,OAAO;IApBpC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAa;IAC/C,QAAQ,CAAC,WAAW,aAAa;IACjC,QAAQ,CAAC,YAAY,EAAE,SAAS,iBAAiB,EAAE,CAaxC;IAEX,OAAO,CAAC,QAAQ,CAAkE;IAClF,OAAO,CAAC,cAAc,CAA6C;gBAEtC,OAAO,EAAE,cAAc;IAE9C,UAAU,CAAC,KAAK,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAKnD,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAQ/B,iBAAiB,IAAI,qBAAqB;IAMpC,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA6CxF,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAOnF,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,UAAU,CAAC,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAI;IAOvE,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9F,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASvE,WAAW,CAAC,cAAc,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASpF,mBAAmB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC;QACzD,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,CAAC;IAyBF,OAAO,CAAC,oBAAoB;IAiC5B,OAAO,CAAC,uBAAuB;IAe/B,OAAO,CAAC,IAAI;CASb"}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview IChannelAdapter implementation for Discord via discord.js.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DiscordChannelAdapter = void 0;
|
|
7
|
+
const discord_js_1 = require("discord.js");
|
|
8
|
+
class DiscordChannelAdapter {
|
|
9
|
+
constructor(service) {
|
|
10
|
+
this.service = service;
|
|
11
|
+
this.platform = 'discord';
|
|
12
|
+
this.displayName = 'Discord';
|
|
13
|
+
this.capabilities = [
|
|
14
|
+
'text',
|
|
15
|
+
'rich_text',
|
|
16
|
+
'images',
|
|
17
|
+
'documents',
|
|
18
|
+
'embeds',
|
|
19
|
+
'reactions',
|
|
20
|
+
'threads',
|
|
21
|
+
'typing_indicator',
|
|
22
|
+
'group_chat',
|
|
23
|
+
'mentions',
|
|
24
|
+
'editing',
|
|
25
|
+
'deletion',
|
|
26
|
+
];
|
|
27
|
+
this.handlers = new Map();
|
|
28
|
+
this.messageHandler = null;
|
|
29
|
+
}
|
|
30
|
+
async initialize(_auth) {
|
|
31
|
+
this.messageHandler = (message) => this.handleInboundMessage(message);
|
|
32
|
+
this.service.onMessage(this.messageHandler);
|
|
33
|
+
}
|
|
34
|
+
async shutdown() {
|
|
35
|
+
if (this.messageHandler) {
|
|
36
|
+
this.service.offMessage(this.messageHandler);
|
|
37
|
+
this.messageHandler = null;
|
|
38
|
+
}
|
|
39
|
+
this.handlers.clear();
|
|
40
|
+
}
|
|
41
|
+
getConnectionInfo() {
|
|
42
|
+
return {
|
|
43
|
+
status: this.service.isRunning ? 'connected' : 'disconnected',
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
async sendMessage(conversationId, content) {
|
|
47
|
+
const textBlock = content.blocks.find((b) => b.type === 'text');
|
|
48
|
+
const imageBlock = content.blocks.find((b) => b.type === 'image');
|
|
49
|
+
const documentBlock = content.blocks.find((b) => b.type === 'document');
|
|
50
|
+
const embedBlock = content.blocks.find((b) => b.type === 'embed');
|
|
51
|
+
// Build embeds array from embed blocks
|
|
52
|
+
const embeds = [];
|
|
53
|
+
if (embedBlock && embedBlock.type === 'embed') {
|
|
54
|
+
embeds.push({
|
|
55
|
+
title: embedBlock.title,
|
|
56
|
+
description: embedBlock.description,
|
|
57
|
+
color: embedBlock.color,
|
|
58
|
+
fields: embedBlock.fields,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
if (imageBlock && imageBlock.type === 'image') {
|
|
62
|
+
// Send image as attachment with optional text
|
|
63
|
+
const result = await this.service.sendFile(conversationId, imageBlock.url, imageBlock.caption ?? undefined);
|
|
64
|
+
return { messageId: result.id, timestamp: new Date().toISOString() };
|
|
65
|
+
}
|
|
66
|
+
if (documentBlock && documentBlock.type === 'document') {
|
|
67
|
+
const result = await this.service.sendFile(conversationId, documentBlock.url, documentBlock.filename);
|
|
68
|
+
return { messageId: result.id, timestamp: new Date().toISOString() };
|
|
69
|
+
}
|
|
70
|
+
const text = textBlock?.text ?? '';
|
|
71
|
+
const result = await this.service.sendMessage(conversationId, text, {
|
|
72
|
+
embeds: embeds.length > 0 ? embeds : undefined,
|
|
73
|
+
replyToMessageId: content.replyToMessageId ?? undefined,
|
|
74
|
+
});
|
|
75
|
+
return { messageId: result.id, timestamp: result.timestamp };
|
|
76
|
+
}
|
|
77
|
+
async sendTypingIndicator(conversationId, isTyping) {
|
|
78
|
+
if (isTyping) {
|
|
79
|
+
await this.service.setTyping(conversationId);
|
|
80
|
+
}
|
|
81
|
+
// Discord typing indicator auto-clears after ~10 seconds or on message send.
|
|
82
|
+
}
|
|
83
|
+
on(handler, eventTypes) {
|
|
84
|
+
this.handlers.set(handler, eventTypes);
|
|
85
|
+
return () => {
|
|
86
|
+
this.handlers.delete(handler);
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
async editMessage(conversationId, messageId, content) {
|
|
90
|
+
const client = this.service.getClient();
|
|
91
|
+
const channel = await client.channels.fetch(conversationId);
|
|
92
|
+
if (!channel || !('messages' in channel))
|
|
93
|
+
return;
|
|
94
|
+
const msg = await channel.messages.fetch(messageId);
|
|
95
|
+
const textBlock = content.blocks.find((b) => b.type === 'text');
|
|
96
|
+
if (textBlock && textBlock.type === 'text') {
|
|
97
|
+
await msg.edit({ content: textBlock.text });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async deleteMessage(conversationId, messageId) {
|
|
101
|
+
const client = this.service.getClient();
|
|
102
|
+
const channel = await client.channels.fetch(conversationId);
|
|
103
|
+
if (!channel || !('messages' in channel))
|
|
104
|
+
return;
|
|
105
|
+
const msg = await channel.messages.fetch(messageId);
|
|
106
|
+
await msg.delete();
|
|
107
|
+
}
|
|
108
|
+
async addReaction(conversationId, messageId, emoji) {
|
|
109
|
+
const client = this.service.getClient();
|
|
110
|
+
const channel = await client.channels.fetch(conversationId);
|
|
111
|
+
if (!channel || !('messages' in channel))
|
|
112
|
+
return;
|
|
113
|
+
const msg = await channel.messages.fetch(messageId);
|
|
114
|
+
await msg.react(emoji);
|
|
115
|
+
}
|
|
116
|
+
async getConversationInfo(conversationId) {
|
|
117
|
+
const client = this.service.getClient();
|
|
118
|
+
const channel = await client.channels.fetch(conversationId);
|
|
119
|
+
if (!channel) {
|
|
120
|
+
return { isGroup: false };
|
|
121
|
+
}
|
|
122
|
+
const isDM = channel.isDMBased();
|
|
123
|
+
const isGroup = !isDM;
|
|
124
|
+
return {
|
|
125
|
+
name: 'name' in channel ? channel.name : undefined,
|
|
126
|
+
memberCount: 'guild' in channel && channel.guild
|
|
127
|
+
? channel.guild.memberCount
|
|
128
|
+
: undefined,
|
|
129
|
+
isGroup,
|
|
130
|
+
metadata: {
|
|
131
|
+
type: discord_js_1.ChannelType[channel.type],
|
|
132
|
+
guildId: 'guildId' in channel ? channel.guildId : undefined,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
// -- Private --
|
|
137
|
+
handleInboundMessage(message) {
|
|
138
|
+
const sender = {
|
|
139
|
+
id: message.author.id,
|
|
140
|
+
displayName: message.member?.displayName ?? message.author.displayName ?? undefined,
|
|
141
|
+
username: message.author.username,
|
|
142
|
+
};
|
|
143
|
+
const conversationType = this.resolveConversationType(message);
|
|
144
|
+
const channelMessage = {
|
|
145
|
+
messageId: message.id,
|
|
146
|
+
platform: 'discord',
|
|
147
|
+
conversationId: message.channelId,
|
|
148
|
+
conversationType,
|
|
149
|
+
sender,
|
|
150
|
+
content: [{ type: 'text', text: message.content ?? '' }],
|
|
151
|
+
text: message.content ?? '',
|
|
152
|
+
timestamp: message.createdAt.toISOString(),
|
|
153
|
+
replyToMessageId: message.reference?.messageId ?? undefined,
|
|
154
|
+
rawEvent: message,
|
|
155
|
+
};
|
|
156
|
+
const event = {
|
|
157
|
+
type: 'message',
|
|
158
|
+
platform: 'discord',
|
|
159
|
+
conversationId: message.channelId,
|
|
160
|
+
timestamp: channelMessage.timestamp,
|
|
161
|
+
data: channelMessage,
|
|
162
|
+
};
|
|
163
|
+
this.emit(event);
|
|
164
|
+
}
|
|
165
|
+
resolveConversationType(message) {
|
|
166
|
+
const channelType = message.channel.type;
|
|
167
|
+
if (channelType === discord_js_1.ChannelType.DM)
|
|
168
|
+
return 'direct';
|
|
169
|
+
if (channelType === discord_js_1.ChannelType.PublicThread ||
|
|
170
|
+
channelType === discord_js_1.ChannelType.PrivateThread ||
|
|
171
|
+
channelType === discord_js_1.ChannelType.AnnouncementThread) {
|
|
172
|
+
return 'thread';
|
|
173
|
+
}
|
|
174
|
+
// GuildText, GuildAnnouncement, GuildVoice, GuildStageVoice, GroupDM, etc.
|
|
175
|
+
return 'group';
|
|
176
|
+
}
|
|
177
|
+
emit(event) {
|
|
178
|
+
for (const [handler, filter] of this.handlers) {
|
|
179
|
+
if (!filter || filter.includes(event.type)) {
|
|
180
|
+
Promise.resolve(handler(event)).catch((err) => {
|
|
181
|
+
console.error('[DiscordChannelAdapter] Handler error:', err);
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
exports.DiscordChannelAdapter = DiscordChannelAdapter;
|
|
188
|
+
//# sourceMappingURL=DiscordChannelAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiscordChannelAdapter.js","sourceRoot":"","sources":["../src/DiscordChannelAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Discord SDK wrapper using discord.js.
|
|
3
|
+
* Handles bot lifecycle, message sending, and event dispatch.
|
|
4
|
+
*/
|
|
5
|
+
import { Client, AttachmentBuilder, type Message, type APIEmbed } from 'discord.js';
|
|
6
|
+
export interface DiscordChannelConfig {
|
|
7
|
+
botToken: string;
|
|
8
|
+
applicationId?: string;
|
|
9
|
+
intents?: number[];
|
|
10
|
+
}
|
|
11
|
+
export declare class DiscordService {
|
|
12
|
+
private client;
|
|
13
|
+
private running;
|
|
14
|
+
private messageHandlers;
|
|
15
|
+
private readonly config;
|
|
16
|
+
constructor(config: DiscordChannelConfig);
|
|
17
|
+
initialize(): Promise<void>;
|
|
18
|
+
shutdown(): Promise<void>;
|
|
19
|
+
get isRunning(): boolean;
|
|
20
|
+
onMessage(handler: (message: Message) => void): void;
|
|
21
|
+
offMessage(handler: (message: Message) => void): void;
|
|
22
|
+
sendMessage(channelId: string, text: string, options?: {
|
|
23
|
+
embeds?: APIEmbed[];
|
|
24
|
+
files?: AttachmentBuilder[];
|
|
25
|
+
replyToMessageId?: string;
|
|
26
|
+
}): Promise<{
|
|
27
|
+
id: string;
|
|
28
|
+
channelId: string;
|
|
29
|
+
timestamp: string;
|
|
30
|
+
}>;
|
|
31
|
+
sendFile(channelId: string, url: string, filename?: string, description?: string): Promise<{
|
|
32
|
+
id: string;
|
|
33
|
+
}>;
|
|
34
|
+
setTyping(channelId: string): Promise<void>;
|
|
35
|
+
getBotInfo(): Promise<{
|
|
36
|
+
id: string;
|
|
37
|
+
username: string;
|
|
38
|
+
discriminator: string;
|
|
39
|
+
tag: string;
|
|
40
|
+
} | null>;
|
|
41
|
+
/**
|
|
42
|
+
* Access the underlying discord.js Client for advanced operations.
|
|
43
|
+
* Throws if the service has not been initialized.
|
|
44
|
+
*/
|
|
45
|
+
getClient(): Client;
|
|
46
|
+
private fetchTextChannel;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=DiscordService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiscordService.d.ts","sourceRoot":"","sources":["../src/DiscordService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EACL,MAAM,EAEN,iBAAiB,EAEjB,KAAK,OAAO,EAGZ,KAAK,QAAQ,EACd,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAyC;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;gBAElC,MAAM,EAAE,oBAAoB;IAIlC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA0C3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,SAAS,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAIpD,UAAU,CAAC,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,GAAG,IAAI;IAK/C,WAAW,CACf,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QACR,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC;QACpB,KAAK,CAAC,EAAE,iBAAiB,EAAE,CAAC;QAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,GACA,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAa1D,QAAQ,CACZ,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAUpB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK3C,UAAU,IAAI,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAUxG;;;OAGG;IACH,SAAS,IAAI,MAAM;YAKL,gBAAgB;CAQ/B"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Discord SDK wrapper using discord.js.
|
|
4
|
+
* Handles bot lifecycle, message sending, and event dispatch.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.DiscordService = void 0;
|
|
8
|
+
const discord_js_1 = require("discord.js");
|
|
9
|
+
class DiscordService {
|
|
10
|
+
constructor(config) {
|
|
11
|
+
this.client = null;
|
|
12
|
+
this.running = false;
|
|
13
|
+
this.messageHandlers = [];
|
|
14
|
+
this.config = config;
|
|
15
|
+
}
|
|
16
|
+
async initialize() {
|
|
17
|
+
if (this.running)
|
|
18
|
+
return;
|
|
19
|
+
const intents = this.config.intents ?? [
|
|
20
|
+
discord_js_1.GatewayIntentBits.Guilds,
|
|
21
|
+
discord_js_1.GatewayIntentBits.GuildMessages,
|
|
22
|
+
discord_js_1.GatewayIntentBits.MessageContent,
|
|
23
|
+
discord_js_1.GatewayIntentBits.DirectMessages,
|
|
24
|
+
];
|
|
25
|
+
this.client = new discord_js_1.Client({ intents });
|
|
26
|
+
// Register inbound message listener
|
|
27
|
+
this.client.on('messageCreate', (message) => {
|
|
28
|
+
// Ignore messages from the bot itself
|
|
29
|
+
if (message.author.id === this.client?.user?.id)
|
|
30
|
+
return;
|
|
31
|
+
for (const handler of this.messageHandlers) {
|
|
32
|
+
handler(message);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
// Login and wait for ready
|
|
36
|
+
await new Promise((resolve, reject) => {
|
|
37
|
+
if (!this.client)
|
|
38
|
+
return reject(new Error('Client not created'));
|
|
39
|
+
const timeout = setTimeout(() => {
|
|
40
|
+
reject(new Error('Discord client ready timeout after 30s'));
|
|
41
|
+
}, 30000);
|
|
42
|
+
this.client.once('ready', () => {
|
|
43
|
+
clearTimeout(timeout);
|
|
44
|
+
this.running = true;
|
|
45
|
+
resolve();
|
|
46
|
+
});
|
|
47
|
+
this.client.login(this.config.botToken).catch((err) => {
|
|
48
|
+
clearTimeout(timeout);
|
|
49
|
+
reject(err);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async shutdown() {
|
|
54
|
+
if (!this.running || !this.client)
|
|
55
|
+
return;
|
|
56
|
+
this.client.destroy();
|
|
57
|
+
this.running = false;
|
|
58
|
+
this.client = null;
|
|
59
|
+
}
|
|
60
|
+
get isRunning() {
|
|
61
|
+
return this.running;
|
|
62
|
+
}
|
|
63
|
+
onMessage(handler) {
|
|
64
|
+
this.messageHandlers.push(handler);
|
|
65
|
+
}
|
|
66
|
+
offMessage(handler) {
|
|
67
|
+
const idx = this.messageHandlers.indexOf(handler);
|
|
68
|
+
if (idx >= 0)
|
|
69
|
+
this.messageHandlers.splice(idx, 1);
|
|
70
|
+
}
|
|
71
|
+
async sendMessage(channelId, text, options) {
|
|
72
|
+
const channel = await this.fetchTextChannel(channelId);
|
|
73
|
+
const msg = await channel.send({
|
|
74
|
+
content: text || undefined,
|
|
75
|
+
embeds: options?.embeds,
|
|
76
|
+
files: options?.files,
|
|
77
|
+
reply: options?.replyToMessageId
|
|
78
|
+
? { messageReference: options.replyToMessageId }
|
|
79
|
+
: undefined,
|
|
80
|
+
});
|
|
81
|
+
return { id: msg.id, channelId: msg.channelId, timestamp: msg.createdAt.toISOString() };
|
|
82
|
+
}
|
|
83
|
+
async sendFile(channelId, url, filename, description) {
|
|
84
|
+
const channel = await this.fetchTextChannel(channelId);
|
|
85
|
+
const attachment = new discord_js_1.AttachmentBuilder(url, {
|
|
86
|
+
name: filename,
|
|
87
|
+
description,
|
|
88
|
+
});
|
|
89
|
+
const msg = await channel.send({ files: [attachment] });
|
|
90
|
+
return { id: msg.id };
|
|
91
|
+
}
|
|
92
|
+
async setTyping(channelId) {
|
|
93
|
+
const channel = await this.fetchTextChannel(channelId);
|
|
94
|
+
await channel.sendTyping();
|
|
95
|
+
}
|
|
96
|
+
async getBotInfo() {
|
|
97
|
+
if (!this.client?.user)
|
|
98
|
+
return null;
|
|
99
|
+
return {
|
|
100
|
+
id: this.client.user.id,
|
|
101
|
+
username: this.client.user.username,
|
|
102
|
+
discriminator: this.client.user.discriminator,
|
|
103
|
+
tag: this.client.user.tag,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Access the underlying discord.js Client for advanced operations.
|
|
108
|
+
* Throws if the service has not been initialized.
|
|
109
|
+
*/
|
|
110
|
+
getClient() {
|
|
111
|
+
if (!this.client)
|
|
112
|
+
throw new Error('DiscordService not initialized');
|
|
113
|
+
return this.client;
|
|
114
|
+
}
|
|
115
|
+
async fetchTextChannel(channelId) {
|
|
116
|
+
if (!this.client)
|
|
117
|
+
throw new Error('DiscordService not initialized');
|
|
118
|
+
const channel = await this.client.channels.fetch(channelId);
|
|
119
|
+
if (!channel || !('send' in channel)) {
|
|
120
|
+
throw new Error(`Channel ${channelId} is not a text-based channel or does not exist`);
|
|
121
|
+
}
|
|
122
|
+
return channel;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.DiscordService = DiscordService;
|
|
126
|
+
//# sourceMappingURL=DiscordService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiscordService.js","sourceRoot":"","sources":["../src/DiscordService.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Discord Channel Extension for AgentOS.
|
|
3
|
+
*
|
|
4
|
+
* Provides a bidirectional messaging channel adapter using discord.js,
|
|
5
|
+
* plus ITool descriptors for programmatic message sending.
|
|
6
|
+
*
|
|
7
|
+
* @module @framers/agentos-ext-channel-discord
|
|
8
|
+
*/
|
|
9
|
+
import type { ExtensionContext, ExtensionPack } from '@framers/agentos';
|
|
10
|
+
import { DiscordService, type DiscordChannelConfig } from './DiscordService';
|
|
11
|
+
import { DiscordChannelAdapter } from './DiscordChannelAdapter';
|
|
12
|
+
import { DiscordSendMessageTool } from './tools/sendMessage';
|
|
13
|
+
import { DiscordSendMediaTool } from './tools/sendMedia';
|
|
14
|
+
export interface DiscordChannelOptions {
|
|
15
|
+
botToken?: string;
|
|
16
|
+
botTokenEnv?: string;
|
|
17
|
+
applicationId?: string;
|
|
18
|
+
intents?: number[];
|
|
19
|
+
priority?: number;
|
|
20
|
+
}
|
|
21
|
+
export declare function createExtensionPack(context: ExtensionContext): ExtensionPack;
|
|
22
|
+
export { DiscordService, DiscordChannelAdapter, DiscordSendMessageTool, DiscordSendMediaTool };
|
|
23
|
+
export type { DiscordChannelConfig };
|
|
24
|
+
export default createExtensionPack;
|
|
25
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,EAAE,cAAc,EAAE,KAAK,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAChE,OAAO,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAEzD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAuBD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAqC5E;AAED,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,oBAAoB,EAAE,CAAC;AAC/F,YAAY,EAAE,oBAAoB,EAAE,CAAC;AACrC,eAAe,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Discord Channel Extension for AgentOS.
|
|
4
|
+
*
|
|
5
|
+
* Provides a bidirectional messaging channel adapter using discord.js,
|
|
6
|
+
* plus ITool descriptors for programmatic message sending.
|
|
7
|
+
*
|
|
8
|
+
* @module @framers/agentos-ext-channel-discord
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.DiscordSendMediaTool = exports.DiscordSendMessageTool = exports.DiscordChannelAdapter = exports.DiscordService = void 0;
|
|
12
|
+
exports.createExtensionPack = createExtensionPack;
|
|
13
|
+
const DiscordService_1 = require("./DiscordService");
|
|
14
|
+
Object.defineProperty(exports, "DiscordService", { enumerable: true, get: function () { return DiscordService_1.DiscordService; } });
|
|
15
|
+
const DiscordChannelAdapter_1 = require("./DiscordChannelAdapter");
|
|
16
|
+
Object.defineProperty(exports, "DiscordChannelAdapter", { enumerable: true, get: function () { return DiscordChannelAdapter_1.DiscordChannelAdapter; } });
|
|
17
|
+
const sendMessage_1 = require("./tools/sendMessage");
|
|
18
|
+
Object.defineProperty(exports, "DiscordSendMessageTool", { enumerable: true, get: function () { return sendMessage_1.DiscordSendMessageTool; } });
|
|
19
|
+
const sendMedia_1 = require("./tools/sendMedia");
|
|
20
|
+
Object.defineProperty(exports, "DiscordSendMediaTool", { enumerable: true, get: function () { return sendMedia_1.DiscordSendMediaTool; } });
|
|
21
|
+
function resolveBotToken(options, secrets) {
|
|
22
|
+
if (options.botToken)
|
|
23
|
+
return options.botToken;
|
|
24
|
+
// Check secrets map from registry
|
|
25
|
+
if (secrets?.['discord.botToken'])
|
|
26
|
+
return secrets['discord.botToken'];
|
|
27
|
+
// Environment variable fallback
|
|
28
|
+
const envName = options.botTokenEnv ?? 'DISCORD_BOT_TOKEN';
|
|
29
|
+
const envValue = process.env[envName];
|
|
30
|
+
if (envValue)
|
|
31
|
+
return envValue;
|
|
32
|
+
// Common variations
|
|
33
|
+
for (const v of ['DISCORD_BOT_TOKEN', 'DISCORD_TOKEN']) {
|
|
34
|
+
if (process.env[v])
|
|
35
|
+
return process.env[v];
|
|
36
|
+
}
|
|
37
|
+
throw new Error('Discord bot token not found. Provide via options.botToken, secrets["discord.botToken"], or DISCORD_BOT_TOKEN env var.');
|
|
38
|
+
}
|
|
39
|
+
function createExtensionPack(context) {
|
|
40
|
+
const options = (context.options ?? {});
|
|
41
|
+
const botToken = resolveBotToken(options, options.secrets);
|
|
42
|
+
const config = {
|
|
43
|
+
botToken,
|
|
44
|
+
applicationId: options.applicationId,
|
|
45
|
+
intents: options.intents,
|
|
46
|
+
};
|
|
47
|
+
const service = new DiscordService_1.DiscordService(config);
|
|
48
|
+
const adapter = new DiscordChannelAdapter_1.DiscordChannelAdapter(service);
|
|
49
|
+
const sendMessageTool = new sendMessage_1.DiscordSendMessageTool(service);
|
|
50
|
+
const sendMediaTool = new sendMedia_1.DiscordSendMediaTool(service);
|
|
51
|
+
const priority = options.priority ?? 50;
|
|
52
|
+
return {
|
|
53
|
+
name: '@framers/agentos-ext-channel-discord',
|
|
54
|
+
version: '0.1.0',
|
|
55
|
+
descriptors: [
|
|
56
|
+
{ id: 'discordChannelSendMessage', kind: 'tool', priority, payload: sendMessageTool },
|
|
57
|
+
{ id: 'discordChannelSendMedia', kind: 'tool', priority, payload: sendMediaTool },
|
|
58
|
+
{ id: 'discordChannel', kind: 'messaging-channel', priority, payload: adapter },
|
|
59
|
+
],
|
|
60
|
+
onActivate: async () => {
|
|
61
|
+
await service.initialize();
|
|
62
|
+
// Wire adapter event listeners after service is running
|
|
63
|
+
await adapter.initialize({ platform: 'discord', credential: botToken });
|
|
64
|
+
context.logger?.info('[DiscordChannel] Extension activated');
|
|
65
|
+
},
|
|
66
|
+
onDeactivate: async () => {
|
|
67
|
+
await adapter.shutdown();
|
|
68
|
+
await service.shutdown();
|
|
69
|
+
context.logger?.info('[DiscordChannel] Extension deactivated');
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
exports.default = createExtensionPack;
|
|
74
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview ITool for sending media (image, document) via the Discord channel adapter.
|
|
3
|
+
*/
|
|
4
|
+
import type { ITool, ToolExecutionContext, ToolExecutionResult } from '@framers/agentos';
|
|
5
|
+
import type { DiscordService } from '../DiscordService';
|
|
6
|
+
export declare class DiscordSendMediaTool implements ITool {
|
|
7
|
+
private readonly service;
|
|
8
|
+
readonly id = "discordChannelSendMedia";
|
|
9
|
+
readonly name = "discordChannelSendMedia";
|
|
10
|
+
readonly displayName = "Send Discord Media";
|
|
11
|
+
readonly description = "Send an image or document attachment to a Discord channel.";
|
|
12
|
+
readonly category = "communication";
|
|
13
|
+
readonly version = "0.1.0";
|
|
14
|
+
readonly hasSideEffects = true;
|
|
15
|
+
readonly inputSchema: {
|
|
16
|
+
type: "object";
|
|
17
|
+
required: readonly ["channelId", "url"];
|
|
18
|
+
properties: {
|
|
19
|
+
channelId: {
|
|
20
|
+
type: string;
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
url: {
|
|
24
|
+
type: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
filename: {
|
|
28
|
+
type: string;
|
|
29
|
+
description: string;
|
|
30
|
+
};
|
|
31
|
+
description: {
|
|
32
|
+
type: string;
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
readonly outputSchema: {
|
|
38
|
+
type: "object";
|
|
39
|
+
properties: {
|
|
40
|
+
messageId: {
|
|
41
|
+
type: string;
|
|
42
|
+
description: string;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
constructor(service: DiscordService);
|
|
47
|
+
execute(args: {
|
|
48
|
+
channelId: string;
|
|
49
|
+
url: string;
|
|
50
|
+
filename?: string;
|
|
51
|
+
description?: string;
|
|
52
|
+
}, _context: ToolExecutionContext): Promise<ToolExecutionResult>;
|
|
53
|
+
validateArgs(args: Record<string, any>): {
|
|
54
|
+
isValid: boolean;
|
|
55
|
+
errors?: string[];
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=sendMedia.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendMedia.d.ts","sourceRoot":"","sources":["../../src/tools/sendMedia.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD,qBAAa,oBAAqB,YAAW,KAAK;IA2BpC,OAAO,CAAC,QAAQ,CAAC,OAAO;IA1BpC,SAAgB,EAAE,6BAA6B;IAC/C,SAAgB,IAAI,6BAA6B;IACjD,SAAgB,WAAW,wBAAwB;IACnD,SAAgB,WAAW,gEAAgE;IAC3F,SAAgB,QAAQ,mBAAmB;IAC3C,SAAgB,OAAO,WAAW;IAClC,SAAgB,cAAc,QAAQ;IAEtC,SAAgB,WAAW;;;;;;;;;;;;;;;;;;;;;MASzB;IAEF,SAAgB,YAAY;;;;;;;;MAK1B;gBAE2B,OAAO,EAAE,cAAc;IAE9C,OAAO,CACX,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,EACjF,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC;IAe/B,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;CAMjF"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview ITool for sending media (image, document) via the Discord channel adapter.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DiscordSendMediaTool = void 0;
|
|
7
|
+
class DiscordSendMediaTool {
|
|
8
|
+
constructor(service) {
|
|
9
|
+
this.service = service;
|
|
10
|
+
this.id = 'discordChannelSendMedia';
|
|
11
|
+
this.name = 'discordChannelSendMedia';
|
|
12
|
+
this.displayName = 'Send Discord Media';
|
|
13
|
+
this.description = 'Send an image or document attachment to a Discord channel.';
|
|
14
|
+
this.category = 'communication';
|
|
15
|
+
this.version = '0.1.0';
|
|
16
|
+
this.hasSideEffects = true;
|
|
17
|
+
this.inputSchema = {
|
|
18
|
+
type: 'object',
|
|
19
|
+
required: ['channelId', 'url'],
|
|
20
|
+
properties: {
|
|
21
|
+
channelId: { type: 'string', description: 'Target channel ID' },
|
|
22
|
+
url: { type: 'string', description: 'URL of the file to send' },
|
|
23
|
+
filename: { type: 'string', description: 'Override filename for the attachment' },
|
|
24
|
+
description: { type: 'string', description: 'Alt text / description for the attachment' },
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
this.outputSchema = {
|
|
28
|
+
type: 'object',
|
|
29
|
+
properties: {
|
|
30
|
+
messageId: { type: 'string', description: 'Sent message ID' },
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
async execute(args, _context) {
|
|
35
|
+
try {
|
|
36
|
+
const result = await this.service.sendFile(args.channelId, args.url, args.filename, args.description);
|
|
37
|
+
return { success: true, output: { messageId: result.id } };
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
return { success: false, error: error.message };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
validateArgs(args) {
|
|
44
|
+
const errors = [];
|
|
45
|
+
if (!args.channelId)
|
|
46
|
+
errors.push('channelId is required');
|
|
47
|
+
if (!args.url)
|
|
48
|
+
errors.push('url is required');
|
|
49
|
+
return { isValid: errors.length === 0, errors };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
exports.DiscordSendMediaTool = DiscordSendMediaTool;
|
|
53
|
+
//# sourceMappingURL=sendMedia.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendMedia.js","sourceRoot":"","sources":["../../src/tools/sendMedia.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAKH,MAAa,oBAAoB;IA2B/B,YAA6B,OAAuB;QAAvB,YAAO,GAAP,OAAO,CAAgB;QA1BpC,OAAE,GAAG,yBAAyB,CAAC;QAC/B,SAAI,GAAG,yBAAyB,CAAC;QACjC,gBAAW,GAAG,oBAAoB,CAAC;QACnC,gBAAW,GAAG,4DAA4D,CAAC;QAC3E,aAAQ,GAAG,eAAe,CAAC;QAC3B,YAAO,GAAG,OAAO,CAAC;QAClB,mBAAc,GAAG,IAAI,CAAC;QAEtB,gBAAW,GAAG;YAC5B,IAAI,EAAE,QAAiB;YACvB,QAAQ,EAAE,CAAC,WAAW,EAAE,KAAK,CAAU;YACvC,UAAU,EAAE;gBACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE;gBAC/D,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yBAAyB,EAAE;gBAC/D,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sCAAsC,EAAE;gBACjF,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2CAA2C,EAAE;aAC1F;SACF,CAAC;QAEc,iBAAY,GAAG;YAC7B,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE;aAC9D;SACF,CAAC;IAEqD,CAAC;IAExD,KAAK,CAAC,OAAO,CACX,IAAiF,EACjF,QAA8B;QAE9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CACxC,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,QAAQ,EACb,IAAI,CAAC,WAAW,CACjB,CAAC;YAEF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QAClD,CAAC;IACH,CAAC;IAED,YAAY,CAAC,IAAyB;QACpC,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC1D,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAClD,CAAC;CACF;AArDD,oDAqDC"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview ITool for sending text messages via the Discord channel adapter.
|
|
3
|
+
*/
|
|
4
|
+
import type { ITool, ToolExecutionContext, ToolExecutionResult } from '@framers/agentos';
|
|
5
|
+
import type { DiscordService } from '../DiscordService';
|
|
6
|
+
export declare class DiscordSendMessageTool implements ITool {
|
|
7
|
+
private readonly service;
|
|
8
|
+
readonly id = "discordChannelSendMessage";
|
|
9
|
+
readonly name = "discordChannelSendMessage";
|
|
10
|
+
readonly displayName = "Send Discord Message";
|
|
11
|
+
readonly description = "Send a text message to a Discord channel, optionally with an embed.";
|
|
12
|
+
readonly category = "communication";
|
|
13
|
+
readonly version = "0.1.0";
|
|
14
|
+
readonly hasSideEffects = true;
|
|
15
|
+
readonly inputSchema: {
|
|
16
|
+
type: "object";
|
|
17
|
+
required: readonly ["channelId", "text"];
|
|
18
|
+
properties: {
|
|
19
|
+
channelId: {
|
|
20
|
+
type: string;
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
text: {
|
|
24
|
+
type: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
embed: {
|
|
28
|
+
type: string;
|
|
29
|
+
description: string;
|
|
30
|
+
properties: {
|
|
31
|
+
title: {
|
|
32
|
+
type: string;
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
description: {
|
|
36
|
+
type: string;
|
|
37
|
+
description: string;
|
|
38
|
+
};
|
|
39
|
+
color: {
|
|
40
|
+
type: string;
|
|
41
|
+
description: string;
|
|
42
|
+
};
|
|
43
|
+
fields: {
|
|
44
|
+
type: string;
|
|
45
|
+
description: string;
|
|
46
|
+
items: {
|
|
47
|
+
type: string;
|
|
48
|
+
properties: {
|
|
49
|
+
name: {
|
|
50
|
+
type: string;
|
|
51
|
+
};
|
|
52
|
+
value: {
|
|
53
|
+
type: string;
|
|
54
|
+
};
|
|
55
|
+
inline: {
|
|
56
|
+
type: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
readonly outputSchema: {
|
|
66
|
+
type: "object";
|
|
67
|
+
properties: {
|
|
68
|
+
messageId: {
|
|
69
|
+
type: string;
|
|
70
|
+
description: string;
|
|
71
|
+
};
|
|
72
|
+
channelId: {
|
|
73
|
+
type: string;
|
|
74
|
+
description: string;
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
constructor(service: DiscordService);
|
|
79
|
+
execute(args: {
|
|
80
|
+
channelId: string;
|
|
81
|
+
text: string;
|
|
82
|
+
embed?: {
|
|
83
|
+
title?: string;
|
|
84
|
+
description?: string;
|
|
85
|
+
color?: number;
|
|
86
|
+
fields?: Array<{
|
|
87
|
+
name: string;
|
|
88
|
+
value: string;
|
|
89
|
+
inline?: boolean;
|
|
90
|
+
}>;
|
|
91
|
+
};
|
|
92
|
+
}, _context: ToolExecutionContext): Promise<ToolExecutionResult>;
|
|
93
|
+
validateArgs(args: Record<string, any>): {
|
|
94
|
+
isValid: boolean;
|
|
95
|
+
errors?: string[];
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=sendMessage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendMessage.d.ts","sourceRoot":"","sources":["../../src/tools/sendMessage.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACzF,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGxD,qBAAa,sBAAuB,YAAW,KAAK;IA+CtC,OAAO,CAAC,QAAQ,CAAC,OAAO;IA9CpC,SAAgB,EAAE,+BAA+B;IACjD,SAAgB,IAAI,+BAA+B;IACnD,SAAgB,WAAW,0BAA0B;IACrD,SAAgB,WAAW,yEAAyE;IACpG,SAAgB,QAAQ,mBAAmB;IAC3C,SAAgB,OAAO,WAAW;IAClC,SAAgB,cAAc,QAAQ;IAEtC,SAAgB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MA4BzB;IAEF,SAAgB,YAAY;;;;;;;;;;;;MAM1B;gBAE2B,OAAO,EAAE,cAAc;IAE9C,OAAO,CACX,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAC;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,WAAW,CAAC,EAAE,MAAM,CAAC;YAAC,KAAK,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,KAAK,CAAC;gBAAE,IAAI,EAAE,MAAM,CAAC;gBAAC,KAAK,EAAE,MAAM,CAAC;gBAAC,MAAM,CAAC,EAAE,OAAO,CAAA;aAAE,CAAC,CAAA;SAAE,CAAC;KACrI,EACD,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC;IA6B/B,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE;CAQjF"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview ITool for sending text messages via the Discord channel adapter.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DiscordSendMessageTool = void 0;
|
|
7
|
+
class DiscordSendMessageTool {
|
|
8
|
+
constructor(service) {
|
|
9
|
+
this.service = service;
|
|
10
|
+
this.id = 'discordChannelSendMessage';
|
|
11
|
+
this.name = 'discordChannelSendMessage';
|
|
12
|
+
this.displayName = 'Send Discord Message';
|
|
13
|
+
this.description = 'Send a text message to a Discord channel, optionally with an embed.';
|
|
14
|
+
this.category = 'communication';
|
|
15
|
+
this.version = '0.1.0';
|
|
16
|
+
this.hasSideEffects = true;
|
|
17
|
+
this.inputSchema = {
|
|
18
|
+
type: 'object',
|
|
19
|
+
required: ['channelId', 'text'],
|
|
20
|
+
properties: {
|
|
21
|
+
channelId: { type: 'string', description: 'Target channel ID' },
|
|
22
|
+
text: { type: 'string', description: 'Message text (max 2000 chars)' },
|
|
23
|
+
embed: {
|
|
24
|
+
type: 'object',
|
|
25
|
+
description: 'Optional rich embed',
|
|
26
|
+
properties: {
|
|
27
|
+
title: { type: 'string', description: 'Embed title' },
|
|
28
|
+
description: { type: 'string', description: 'Embed description' },
|
|
29
|
+
color: { type: 'number', description: 'Embed color as integer' },
|
|
30
|
+
fields: {
|
|
31
|
+
type: 'array',
|
|
32
|
+
description: 'Embed fields',
|
|
33
|
+
items: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
properties: {
|
|
36
|
+
name: { type: 'string' },
|
|
37
|
+
value: { type: 'string' },
|
|
38
|
+
inline: { type: 'boolean' },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
this.outputSchema = {
|
|
47
|
+
type: 'object',
|
|
48
|
+
properties: {
|
|
49
|
+
messageId: { type: 'string', description: 'Sent message ID' },
|
|
50
|
+
channelId: { type: 'string', description: 'Target channel ID' },
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async execute(args, _context) {
|
|
55
|
+
try {
|
|
56
|
+
if (args.text.length > 2000) {
|
|
57
|
+
throw new Error('Message text exceeds 2000 character limit');
|
|
58
|
+
}
|
|
59
|
+
const embeds = [];
|
|
60
|
+
if (args.embed) {
|
|
61
|
+
embeds.push({
|
|
62
|
+
title: args.embed.title,
|
|
63
|
+
description: args.embed.description,
|
|
64
|
+
color: args.embed.color,
|
|
65
|
+
fields: args.embed.fields,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
const result = await this.service.sendMessage(args.channelId, args.text, {
|
|
69
|
+
embeds: embeds.length > 0 ? embeds : undefined,
|
|
70
|
+
});
|
|
71
|
+
return {
|
|
72
|
+
success: true,
|
|
73
|
+
output: { messageId: result.id, channelId: args.channelId },
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
return { success: false, error: error.message };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
validateArgs(args) {
|
|
81
|
+
const errors = [];
|
|
82
|
+
if (!args.channelId)
|
|
83
|
+
errors.push('channelId is required');
|
|
84
|
+
if (!args.text)
|
|
85
|
+
errors.push('text is required');
|
|
86
|
+
else if (typeof args.text !== 'string')
|
|
87
|
+
errors.push('text must be a string');
|
|
88
|
+
else if (args.text.length > 2000)
|
|
89
|
+
errors.push('text exceeds 2000 character limit');
|
|
90
|
+
return { isValid: errors.length === 0, errors };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
exports.DiscordSendMessageTool = DiscordSendMessageTool;
|
|
94
|
+
//# sourceMappingURL=sendMessage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendMessage.js","sourceRoot":"","sources":["../../src/tools/sendMessage.ts"],"names":[],"mappings":"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"}
|
package/manifest.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://agentos.sh/schemas/extension-manifest-v1.json",
|
|
3
|
+
"id": "com.framers.channels.discord",
|
|
4
|
+
"name": "Discord Channel Extension",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": "Bidirectional Discord messaging via discord.js — supports text, embeds, images, documents, threads, reactions, and guild management.",
|
|
7
|
+
"categories": ["channel", "communication"],
|
|
8
|
+
"platforms": ["discord"],
|
|
9
|
+
"sdk": "discord.js",
|
|
10
|
+
"extensions": [
|
|
11
|
+
{
|
|
12
|
+
"kind": "tool",
|
|
13
|
+
"id": "discordChannelSendMessage",
|
|
14
|
+
"displayName": "Send Discord Message"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"kind": "tool",
|
|
18
|
+
"id": "discordChannelSendMedia",
|
|
19
|
+
"displayName": "Send Discord Media"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"kind": "messaging-channel",
|
|
23
|
+
"id": "discordChannel",
|
|
24
|
+
"displayName": "Discord Channel Adapter"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"requiredSecrets": ["discord.botToken"],
|
|
28
|
+
"features": [
|
|
29
|
+
"Text messages with Markdown formatting",
|
|
30
|
+
"Rich embed support with fields and colors",
|
|
31
|
+
"Image and document attachments",
|
|
32
|
+
"Thread creation and management",
|
|
33
|
+
"Message reactions",
|
|
34
|
+
"Typing indicators",
|
|
35
|
+
"Guild and DM support",
|
|
36
|
+
"Message editing and deletion",
|
|
37
|
+
"User mentions"
|
|
38
|
+
]
|
|
39
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@framers/agentos-ext-channel-discord",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Discord messaging channel adapter for AgentOS — bidirectional messaging via discord.js",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"types": "dist/index.d.ts",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"build": "tsc",
|
|
9
|
+
"dev": "tsc --watch",
|
|
10
|
+
"test": "vitest run",
|
|
11
|
+
"test:watch": "vitest watch",
|
|
12
|
+
"clean": "rm -rf dist"
|
|
13
|
+
},
|
|
14
|
+
"keywords": ["agentos", "extension", "channel", "discord", "discord.js", "messaging"],
|
|
15
|
+
"author": { "name": "Framers AI", "url": "https://frame.dev" },
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"files": ["dist", "manifest.json"],
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"@framers/agentos": "^0.1.0"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"discord.js": "^14.14.0"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@framers/agentos": "workspace:*",
|
|
26
|
+
"@types/node": "^20.0.0",
|
|
27
|
+
"typescript": "^5.0.0",
|
|
28
|
+
"vitest": "^1.0.0"
|
|
29
|
+
},
|
|
30
|
+
"engines": { "node": ">=18.0.0" }
|
|
31
|
+
}
|