@framers/agentos-ext-channel-whatsapp 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/WhatsAppChannelAdapter.d.ts +23 -0
- package/dist/WhatsAppChannelAdapter.d.ts.map +1 -0
- package/dist/WhatsAppChannelAdapter.js +128 -0
- package/dist/WhatsAppChannelAdapter.js.map +1 -0
- package/dist/WhatsAppService.d.ts +60 -0
- package/dist/WhatsAppService.d.ts.map +1 -0
- package/dist/WhatsAppService.js +182 -0
- package/dist/WhatsAppService.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +75 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/sendMedia.d.ts +64 -0
- package/dist/tools/sendMedia.d.ts.map +1 -0
- package/dist/tools/sendMedia.js +63 -0
- package/dist/tools/sendMedia.js.map +1 -0
- package/dist/tools/sendMessage.d.ts +52 -0
- package/dist/tools/sendMessage.d.ts.map +1 -0
- package/dist/tools/sendMessage.js +59 -0
- package/dist/tools/sendMessage.js.map +1 -0
- package/manifest.json +37 -0
- package/package.json +29 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview IChannelAdapter implementation for WhatsApp via Baileys.
|
|
3
|
+
*/
|
|
4
|
+
import type { IChannelAdapter, ChannelPlatform, ChannelCapability, ChannelAuthConfig, ChannelConnectionInfo, ChannelSendResult, MessageContent, ChannelEventHandler, ChannelEventType } from '@framers/agentos';
|
|
5
|
+
import { WhatsAppService } from './WhatsAppService';
|
|
6
|
+
export declare class WhatsAppChannelAdapter implements IChannelAdapter {
|
|
7
|
+
private readonly service;
|
|
8
|
+
readonly platform: ChannelPlatform;
|
|
9
|
+
readonly displayName = "WhatsApp";
|
|
10
|
+
readonly capabilities: readonly ChannelCapability[];
|
|
11
|
+
private handlers;
|
|
12
|
+
private msgHandler;
|
|
13
|
+
constructor(service: WhatsAppService);
|
|
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
|
+
private handleInboundMessage;
|
|
21
|
+
private emit;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=WhatsAppChannelAdapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WhatsAppChannelAdapter.d.ts","sourceRoot":"","sources":["../src/WhatsAppChannelAdapter.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,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,qBAAa,sBAAuB,YAAW,eAAe;IAkBhD,OAAO,CAAC,QAAQ,CAAC,OAAO;IAjBpC,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAc;IAChD,QAAQ,CAAC,WAAW,cAAc;IAClC,QAAQ,CAAC,YAAY,EAAE,SAAS,iBAAiB,EAAE,CAQxC;IAEX,OAAO,CAAC,QAAQ,CAAkE;IAGlF,OAAO,CAAC,UAAU,CAA2D;gBAEhD,OAAO,EAAE,eAAe;IAE/C,UAAU,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQlD,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;IAgCxF,mBAAmB,CAAC,cAAc,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IAInF,EAAE,CAAC,OAAO,EAAE,mBAAmB,EAAE,UAAU,CAAC,EAAE,gBAAgB,EAAE,GAAG,MAAM,IAAI;IAS7E,OAAO,CAAC,oBAAoB;IAmD5B,OAAO,CAAC,IAAI;CASb"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview IChannelAdapter implementation for WhatsApp via Baileys.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WhatsAppChannelAdapter = void 0;
|
|
7
|
+
class WhatsAppChannelAdapter {
|
|
8
|
+
constructor(service) {
|
|
9
|
+
this.service = service;
|
|
10
|
+
this.platform = 'whatsapp';
|
|
11
|
+
this.displayName = 'WhatsApp';
|
|
12
|
+
this.capabilities = [
|
|
13
|
+
'text',
|
|
14
|
+
'images',
|
|
15
|
+
'audio',
|
|
16
|
+
'documents',
|
|
17
|
+
'typing_indicator',
|
|
18
|
+
'read_receipts',
|
|
19
|
+
'group_chat',
|
|
20
|
+
];
|
|
21
|
+
this.handlers = new Map();
|
|
22
|
+
// Baileys is an optional peer dependency. Keep types loose so this package can
|
|
23
|
+
// compile in environments where Baileys isn't installed.
|
|
24
|
+
this.msgHandler = null;
|
|
25
|
+
}
|
|
26
|
+
async initialize(auth) {
|
|
27
|
+
// Service is initialized by the extension pack lifecycle, but
|
|
28
|
+
// if called directly (e.g., standalone usage), we wire up here.
|
|
29
|
+
this.msgHandler = (message, isGroup) => this.handleInboundMessage(message, isGroup);
|
|
30
|
+
this.service.onMessage(this.msgHandler);
|
|
31
|
+
}
|
|
32
|
+
async shutdown() {
|
|
33
|
+
if (this.msgHandler) {
|
|
34
|
+
this.service.offMessage(this.msgHandler);
|
|
35
|
+
this.msgHandler = null;
|
|
36
|
+
}
|
|
37
|
+
this.handlers.clear();
|
|
38
|
+
}
|
|
39
|
+
getConnectionInfo() {
|
|
40
|
+
return {
|
|
41
|
+
status: this.service.isRunning ? 'connected' : 'disconnected',
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
async sendMessage(conversationId, content) {
|
|
45
|
+
const textBlock = content.blocks.find((b) => b.type === 'text');
|
|
46
|
+
const imageBlock = content.blocks.find((b) => b.type === 'image');
|
|
47
|
+
const documentBlock = content.blocks.find((b) => b.type === 'document');
|
|
48
|
+
let messageId;
|
|
49
|
+
if (imageBlock && imageBlock.type === 'image') {
|
|
50
|
+
const result = await this.service.sendImage(conversationId, imageBlock.url, imageBlock.caption ?? (textBlock?.type === 'text' ? textBlock.text : undefined));
|
|
51
|
+
messageId = result.key.id;
|
|
52
|
+
}
|
|
53
|
+
else if (documentBlock && documentBlock.type === 'document') {
|
|
54
|
+
const result = await this.service.sendDocument(conversationId, documentBlock.url, documentBlock.filename);
|
|
55
|
+
messageId = result.key.id;
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const text = textBlock?.type === 'text' ? textBlock.text : '';
|
|
59
|
+
const result = await this.service.sendMessage(conversationId, text, {
|
|
60
|
+
quotedMessageId: content.replyToMessageId ?? undefined,
|
|
61
|
+
});
|
|
62
|
+
messageId = result.key.id;
|
|
63
|
+
}
|
|
64
|
+
return { messageId, timestamp: new Date().toISOString() };
|
|
65
|
+
}
|
|
66
|
+
async sendTypingIndicator(conversationId, isTyping) {
|
|
67
|
+
await this.service.sendPresenceUpdate(conversationId, isTyping ? 'composing' : 'paused');
|
|
68
|
+
}
|
|
69
|
+
on(handler, eventTypes) {
|
|
70
|
+
this.handlers.set(handler, eventTypes);
|
|
71
|
+
return () => {
|
|
72
|
+
this.handlers.delete(handler);
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
// ── Private ──
|
|
76
|
+
handleInboundMessage(msg, isGroup) {
|
|
77
|
+
const jid = msg.key.remoteJid ?? '';
|
|
78
|
+
const participantJid = msg.key.participant ?? jid;
|
|
79
|
+
// Extract the text content from the message
|
|
80
|
+
const textContent = msg.message?.conversation ??
|
|
81
|
+
msg.message?.extendedTextMessage?.text ??
|
|
82
|
+
msg.message?.imageMessage?.caption ??
|
|
83
|
+
'';
|
|
84
|
+
// Extract sender information
|
|
85
|
+
const pushName = msg.pushName ?? undefined;
|
|
86
|
+
const senderNumber = participantJid.replace(/@s\.whatsapp\.net$/, '').replace(/@.*$/, '');
|
|
87
|
+
const sender = {
|
|
88
|
+
id: participantJid,
|
|
89
|
+
displayName: pushName,
|
|
90
|
+
username: senderNumber,
|
|
91
|
+
};
|
|
92
|
+
const conversationType = isGroup ? 'group' : 'direct';
|
|
93
|
+
const timestamp = typeof msg.messageTimestamp === 'number'
|
|
94
|
+
? msg.messageTimestamp
|
|
95
|
+
: Number(msg.messageTimestamp ?? Math.floor(Date.now() / 1000));
|
|
96
|
+
const channelMessage = {
|
|
97
|
+
messageId: msg.key.id ?? '',
|
|
98
|
+
platform: 'whatsapp',
|
|
99
|
+
conversationId: jid,
|
|
100
|
+
conversationType,
|
|
101
|
+
sender,
|
|
102
|
+
content: [{ type: 'text', text: textContent }],
|
|
103
|
+
text: textContent,
|
|
104
|
+
timestamp: new Date(timestamp * 1000).toISOString(),
|
|
105
|
+
replyToMessageId: msg.message?.extendedTextMessage?.contextInfo?.stanzaId ?? undefined,
|
|
106
|
+
rawEvent: msg,
|
|
107
|
+
};
|
|
108
|
+
const event = {
|
|
109
|
+
type: 'message',
|
|
110
|
+
platform: 'whatsapp',
|
|
111
|
+
conversationId: jid,
|
|
112
|
+
timestamp: channelMessage.timestamp,
|
|
113
|
+
data: channelMessage,
|
|
114
|
+
};
|
|
115
|
+
this.emit(event);
|
|
116
|
+
}
|
|
117
|
+
emit(event) {
|
|
118
|
+
for (const [handler, filter] of this.handlers) {
|
|
119
|
+
if (!filter || filter.includes(event.type)) {
|
|
120
|
+
Promise.resolve(handler(event)).catch((err) => {
|
|
121
|
+
console.error('[WhatsAppChannelAdapter] Handler error:', err);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.WhatsAppChannelAdapter = WhatsAppChannelAdapter;
|
|
128
|
+
//# sourceMappingURL=WhatsAppChannelAdapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WhatsAppChannelAdapter.js","sourceRoot":"","sources":["../src/WhatsAppChannelAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview WhatsApp SDK wrapper using @whiskeysockets/baileys.
|
|
3
|
+
* Handles socket lifecycle, message sending, and rate limiting.
|
|
4
|
+
*/
|
|
5
|
+
type WAMessage = any;
|
|
6
|
+
export interface WhatsAppChannelConfig {
|
|
7
|
+
sessionData: string;
|
|
8
|
+
phoneNumber?: string;
|
|
9
|
+
reconnect?: {
|
|
10
|
+
maxRetries: number;
|
|
11
|
+
delayMs: number;
|
|
12
|
+
};
|
|
13
|
+
rateLimit?: {
|
|
14
|
+
maxRequests: number;
|
|
15
|
+
windowMs: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
type MessageHandler = (message: WAMessage, isGroup: boolean) => void;
|
|
19
|
+
export declare class WhatsAppService {
|
|
20
|
+
private sock;
|
|
21
|
+
private running;
|
|
22
|
+
private messageHandlers;
|
|
23
|
+
private rateMap;
|
|
24
|
+
private readonly config;
|
|
25
|
+
constructor(config: WhatsAppChannelConfig);
|
|
26
|
+
initialize(): Promise<void>;
|
|
27
|
+
shutdown(): Promise<void>;
|
|
28
|
+
get isRunning(): boolean;
|
|
29
|
+
onMessage(handler: MessageHandler): void;
|
|
30
|
+
offMessage(handler: MessageHandler): void;
|
|
31
|
+
sendMessage(jid: string, text: string, options?: {
|
|
32
|
+
quotedMessageId?: string;
|
|
33
|
+
}): Promise<{
|
|
34
|
+
key: {
|
|
35
|
+
id: string;
|
|
36
|
+
};
|
|
37
|
+
messageTimestamp: number;
|
|
38
|
+
}>;
|
|
39
|
+
sendImage(jid: string, url: string, caption?: string): Promise<{
|
|
40
|
+
key: {
|
|
41
|
+
id: string;
|
|
42
|
+
};
|
|
43
|
+
}>;
|
|
44
|
+
sendDocument(jid: string, url: string, filename?: string): Promise<{
|
|
45
|
+
key: {
|
|
46
|
+
id: string;
|
|
47
|
+
};
|
|
48
|
+
}>;
|
|
49
|
+
sendPresenceUpdate(jid: string, type: 'composing' | 'paused'): Promise<void>;
|
|
50
|
+
/**
|
|
51
|
+
* Determines whether a JID represents a group conversation.
|
|
52
|
+
* Groups end with `@g.us`, DMs end with `@s.whatsapp.net`.
|
|
53
|
+
*/
|
|
54
|
+
isGroupJid(jid: string): boolean;
|
|
55
|
+
private ensureSocket;
|
|
56
|
+
private parseSessionData;
|
|
57
|
+
private checkRateLimit;
|
|
58
|
+
}
|
|
59
|
+
export {};
|
|
60
|
+
//# sourceMappingURL=WhatsAppService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WhatsAppService.d.ts","sourceRoot":"","sources":["../src/WhatsAppService.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAuBH,KAAK,SAAS,GAAG,GAAG,CAAC;AAGrB,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,SAAS,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAOD,KAAK,cAAc,GAAG,CAAC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;AAErE,qBAAa,eAAe;IAC1B,OAAO,CAAC,IAAI,CAAyB;IACrC,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,OAAO,CAAgC;IAC/C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAEG;gBAEd,MAAM,EAAE,qBAAqB;IAQnC,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IA4D3B,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAS/B,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAIxC,UAAU,CAAC,OAAO,EAAE,cAAc,GAAG,IAAI;IAKnC,WAAW,CACf,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;QACR,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,GACA,OAAO,CAAC;QAAE,GAAG,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;IAiBvD,SAAS,CACb,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,GAAG,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAY7B,YAAY,CAChB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC;QAAE,GAAG,EAAE;YAAE,EAAE,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IAY7B,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAKlF;;;OAGG;IACH,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAMhC,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,gBAAgB;YAWV,cAAc;CAe7B"}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview WhatsApp SDK wrapper using @whiskeysockets/baileys.
|
|
4
|
+
* Handles socket lifecycle, message sending, and rate limiting.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.WhatsAppService = void 0;
|
|
8
|
+
// Baileys depends on git-hosted packages. To keep `pnpm install` usable in offline
|
|
9
|
+
// and minimal environments, this extension treats Baileys as a peer dependency
|
|
10
|
+
// and loads it lazily at runtime.
|
|
11
|
+
let cachedBaileys = null;
|
|
12
|
+
function loadBaileys() {
|
|
13
|
+
if (cachedBaileys)
|
|
14
|
+
return cachedBaileys;
|
|
15
|
+
try {
|
|
16
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
17
|
+
cachedBaileys = require('@whiskeysockets/baileys');
|
|
18
|
+
return cachedBaileys;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
cachedBaileys = null;
|
|
22
|
+
const details = error instanceof Error ? error.message : String(error);
|
|
23
|
+
throw new Error(`Missing peer dependency "@whiskeysockets/baileys". Install it to enable WhatsApp support (e.g. \`pnpm add @whiskeysockets/baileys\`). Original error: ${details}`);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
class WhatsAppService {
|
|
27
|
+
constructor(config) {
|
|
28
|
+
this.sock = null;
|
|
29
|
+
this.running = false;
|
|
30
|
+
this.messageHandlers = [];
|
|
31
|
+
this.rateMap = new Map();
|
|
32
|
+
this.config = {
|
|
33
|
+
...config,
|
|
34
|
+
reconnect: config.reconnect ?? { maxRetries: 5, delayMs: 3000 },
|
|
35
|
+
rateLimit: config.rateLimit ?? { maxRequests: 30, windowMs: 1000 },
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
async initialize() {
|
|
39
|
+
if (this.running)
|
|
40
|
+
return;
|
|
41
|
+
// Parse session data into auth state
|
|
42
|
+
const authState = this.parseSessionData(this.config.sessionData);
|
|
43
|
+
const baileys = loadBaileys();
|
|
44
|
+
const makeWASocket = baileys?.default ?? baileys;
|
|
45
|
+
const DisconnectReason = baileys?.DisconnectReason;
|
|
46
|
+
this.sock = makeWASocket({
|
|
47
|
+
auth: authState,
|
|
48
|
+
printQRInTerminal: false,
|
|
49
|
+
});
|
|
50
|
+
// Wire up connection updates
|
|
51
|
+
this.sock.ev.on('connection.update', (update) => {
|
|
52
|
+
const { connection, lastDisconnect } = update;
|
|
53
|
+
if (connection === 'close') {
|
|
54
|
+
const statusCode = lastDisconnect?.error?.output?.statusCode;
|
|
55
|
+
const loggedOutCode = DisconnectReason?.loggedOut;
|
|
56
|
+
const shouldReconnect = loggedOutCode == null ? true : statusCode !== loggedOutCode;
|
|
57
|
+
if (shouldReconnect && this.config.reconnect.maxRetries > 0) {
|
|
58
|
+
setTimeout(() => {
|
|
59
|
+
this.initialize().catch((err) => {
|
|
60
|
+
console.error('[WhatsAppService] Reconnect failed:', err);
|
|
61
|
+
});
|
|
62
|
+
}, this.config.reconnect.delayMs);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
this.running = false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (connection === 'open') {
|
|
69
|
+
this.running = true;
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
// Wire up inbound message handler
|
|
73
|
+
this.sock.ev.on('messages.upsert', ({ messages, type }) => {
|
|
74
|
+
if (type !== 'notify')
|
|
75
|
+
return;
|
|
76
|
+
for (const msg of messages) {
|
|
77
|
+
if (!msg.message || msg.key.fromMe)
|
|
78
|
+
continue;
|
|
79
|
+
const jid = msg.key.remoteJid ?? '';
|
|
80
|
+
const isGroup = this.isGroupJid(jid);
|
|
81
|
+
for (const handler of this.messageHandlers) {
|
|
82
|
+
handler(msg, isGroup);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
this.running = true;
|
|
87
|
+
}
|
|
88
|
+
async shutdown() {
|
|
89
|
+
if (!this.running || !this.sock)
|
|
90
|
+
return;
|
|
91
|
+
this.sock.ev.removeAllListeners('messages.upsert');
|
|
92
|
+
this.sock.ev.removeAllListeners('connection.update');
|
|
93
|
+
this.sock.end(undefined);
|
|
94
|
+
this.running = false;
|
|
95
|
+
this.sock = null;
|
|
96
|
+
}
|
|
97
|
+
get isRunning() {
|
|
98
|
+
return this.running;
|
|
99
|
+
}
|
|
100
|
+
onMessage(handler) {
|
|
101
|
+
this.messageHandlers.push(handler);
|
|
102
|
+
}
|
|
103
|
+
offMessage(handler) {
|
|
104
|
+
const idx = this.messageHandlers.indexOf(handler);
|
|
105
|
+
if (idx >= 0)
|
|
106
|
+
this.messageHandlers.splice(idx, 1);
|
|
107
|
+
}
|
|
108
|
+
async sendMessage(jid, text, options) {
|
|
109
|
+
this.ensureSocket();
|
|
110
|
+
await this.checkRateLimit(jid);
|
|
111
|
+
const quoted = options?.quotedMessageId
|
|
112
|
+
? { key: { remoteJid: jid, id: options.quotedMessageId } }
|
|
113
|
+
: undefined;
|
|
114
|
+
const result = await this.sock.sendMessage(jid, { text }, { quoted });
|
|
115
|
+
return {
|
|
116
|
+
key: { id: result?.key?.id ?? '' },
|
|
117
|
+
messageTimestamp: typeof result?.messageTimestamp === 'number'
|
|
118
|
+
? result.messageTimestamp
|
|
119
|
+
: Math.floor(Date.now() / 1000),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async sendImage(jid, url, caption) {
|
|
123
|
+
this.ensureSocket();
|
|
124
|
+
await this.checkRateLimit(jid);
|
|
125
|
+
const result = await this.sock.sendMessage(jid, {
|
|
126
|
+
image: { url },
|
|
127
|
+
caption: caption ?? undefined,
|
|
128
|
+
});
|
|
129
|
+
return { key: { id: result?.key?.id ?? '' } };
|
|
130
|
+
}
|
|
131
|
+
async sendDocument(jid, url, filename) {
|
|
132
|
+
this.ensureSocket();
|
|
133
|
+
await this.checkRateLimit(jid);
|
|
134
|
+
const result = await this.sock.sendMessage(jid, {
|
|
135
|
+
document: { url },
|
|
136
|
+
fileName: filename ?? 'document',
|
|
137
|
+
});
|
|
138
|
+
return { key: { id: result?.key?.id ?? '' } };
|
|
139
|
+
}
|
|
140
|
+
async sendPresenceUpdate(jid, type) {
|
|
141
|
+
this.ensureSocket();
|
|
142
|
+
await this.sock.sendPresenceUpdate(type, jid);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Determines whether a JID represents a group conversation.
|
|
146
|
+
* Groups end with `@g.us`, DMs end with `@s.whatsapp.net`.
|
|
147
|
+
*/
|
|
148
|
+
isGroupJid(jid) {
|
|
149
|
+
return jid.endsWith('@g.us');
|
|
150
|
+
}
|
|
151
|
+
// ── Private ──
|
|
152
|
+
ensureSocket() {
|
|
153
|
+
if (!this.sock)
|
|
154
|
+
throw new Error('WhatsAppService not initialized');
|
|
155
|
+
}
|
|
156
|
+
parseSessionData(sessionData) {
|
|
157
|
+
try {
|
|
158
|
+
const parsed = JSON.parse(sessionData);
|
|
159
|
+
return parsed;
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
throw new Error('Invalid sessionData: must be a valid JSON string representing WhatsApp auth state.');
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
async checkRateLimit(key) {
|
|
166
|
+
const now = Date.now();
|
|
167
|
+
const state = this.rateMap.get(key);
|
|
168
|
+
if (!state || now >= state.resetAt) {
|
|
169
|
+
this.rateMap.set(key, { count: 1, resetAt: now + this.config.rateLimit.windowMs });
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
if (state.count >= this.config.rateLimit.maxRequests) {
|
|
173
|
+
const waitMs = state.resetAt - now;
|
|
174
|
+
await new Promise((resolve) => setTimeout(resolve, waitMs));
|
|
175
|
+
this.rateMap.set(key, { count: 1, resetAt: Date.now() + this.config.rateLimit.windowMs });
|
|
176
|
+
return;
|
|
177
|
+
}
|
|
178
|
+
state.count++;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
exports.WhatsAppService = WhatsAppService;
|
|
182
|
+
//# sourceMappingURL=WhatsAppService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WhatsAppService.js","sourceRoot":"","sources":["../src/WhatsAppService.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview WhatsApp Channel Extension for AgentOS.
|
|
3
|
+
*
|
|
4
|
+
* Provides a bidirectional messaging channel adapter using @whiskeysockets/baileys,
|
|
5
|
+
* plus ITool descriptors for programmatic message sending.
|
|
6
|
+
*
|
|
7
|
+
* @module @framers/agentos-ext-channel-whatsapp
|
|
8
|
+
*/
|
|
9
|
+
import type { ExtensionContext, ExtensionPack } from '@framers/agentos';
|
|
10
|
+
import { WhatsAppService, type WhatsAppChannelConfig } from './WhatsAppService';
|
|
11
|
+
import { WhatsAppChannelAdapter } from './WhatsAppChannelAdapter';
|
|
12
|
+
import { WhatsAppSendMessageTool } from './tools/sendMessage';
|
|
13
|
+
import { WhatsAppSendMediaTool } from './tools/sendMedia';
|
|
14
|
+
export interface WhatsAppChannelOptions {
|
|
15
|
+
sessionData?: string;
|
|
16
|
+
sessionDataEnv?: string;
|
|
17
|
+
phoneNumber?: string;
|
|
18
|
+
reconnect?: {
|
|
19
|
+
maxRetries: number;
|
|
20
|
+
delayMs: number;
|
|
21
|
+
};
|
|
22
|
+
rateLimit?: {
|
|
23
|
+
maxRequests: number;
|
|
24
|
+
windowMs: number;
|
|
25
|
+
};
|
|
26
|
+
priority?: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function createExtensionPack(context: ExtensionContext): ExtensionPack;
|
|
29
|
+
export { WhatsAppService, WhatsAppChannelAdapter, WhatsAppSendMessageTool, WhatsAppSendMediaTool };
|
|
30
|
+
export type { WhatsAppChannelConfig };
|
|
31
|
+
export default createExtensionPack;
|
|
32
|
+
//# 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,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,WAAW,sBAAsB;IACrC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,SAAS,CAAC,EAAE;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IACtD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAuBD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,GAAG,aAAa,CAsC5E;AAED,OAAO,EAAE,eAAe,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,qBAAqB,EAAE,CAAC;AACnG,YAAY,EAAE,qBAAqB,EAAE,CAAC;AACtC,eAAe,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview WhatsApp Channel Extension for AgentOS.
|
|
4
|
+
*
|
|
5
|
+
* Provides a bidirectional messaging channel adapter using @whiskeysockets/baileys,
|
|
6
|
+
* plus ITool descriptors for programmatic message sending.
|
|
7
|
+
*
|
|
8
|
+
* @module @framers/agentos-ext-channel-whatsapp
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
exports.WhatsAppSendMediaTool = exports.WhatsAppSendMessageTool = exports.WhatsAppChannelAdapter = exports.WhatsAppService = void 0;
|
|
12
|
+
exports.createExtensionPack = createExtensionPack;
|
|
13
|
+
const WhatsAppService_1 = require("./WhatsAppService");
|
|
14
|
+
Object.defineProperty(exports, "WhatsAppService", { enumerable: true, get: function () { return WhatsAppService_1.WhatsAppService; } });
|
|
15
|
+
const WhatsAppChannelAdapter_1 = require("./WhatsAppChannelAdapter");
|
|
16
|
+
Object.defineProperty(exports, "WhatsAppChannelAdapter", { enumerable: true, get: function () { return WhatsAppChannelAdapter_1.WhatsAppChannelAdapter; } });
|
|
17
|
+
const sendMessage_1 = require("./tools/sendMessage");
|
|
18
|
+
Object.defineProperty(exports, "WhatsAppSendMessageTool", { enumerable: true, get: function () { return sendMessage_1.WhatsAppSendMessageTool; } });
|
|
19
|
+
const sendMedia_1 = require("./tools/sendMedia");
|
|
20
|
+
Object.defineProperty(exports, "WhatsAppSendMediaTool", { enumerable: true, get: function () { return sendMedia_1.WhatsAppSendMediaTool; } });
|
|
21
|
+
function resolveSessionData(options, secrets) {
|
|
22
|
+
if (options.sessionData)
|
|
23
|
+
return options.sessionData;
|
|
24
|
+
// Check secrets map from registry
|
|
25
|
+
if (secrets?.['whatsapp.sessionData'])
|
|
26
|
+
return secrets['whatsapp.sessionData'];
|
|
27
|
+
// Environment variable fallback
|
|
28
|
+
const envName = options.sessionDataEnv ?? 'WHATSAPP_SESSION_DATA';
|
|
29
|
+
const envValue = process.env[envName];
|
|
30
|
+
if (envValue)
|
|
31
|
+
return envValue;
|
|
32
|
+
// Common variations
|
|
33
|
+
for (const v of ['WHATSAPP_SESSION_DATA', 'WHATSAPP_AUTH_STATE']) {
|
|
34
|
+
if (process.env[v])
|
|
35
|
+
return process.env[v];
|
|
36
|
+
}
|
|
37
|
+
throw new Error('WhatsApp session data not found. Provide via options.sessionData, secrets["whatsapp.sessionData"], or WHATSAPP_SESSION_DATA env var.');
|
|
38
|
+
}
|
|
39
|
+
function createExtensionPack(context) {
|
|
40
|
+
const options = (context.options ?? {});
|
|
41
|
+
const sessionData = resolveSessionData(options, options.secrets);
|
|
42
|
+
const config = {
|
|
43
|
+
sessionData,
|
|
44
|
+
phoneNumber: options.phoneNumber,
|
|
45
|
+
reconnect: options.reconnect ?? { maxRetries: 5, delayMs: 3000 },
|
|
46
|
+
rateLimit: options.rateLimit ?? { maxRequests: 30, windowMs: 1000 },
|
|
47
|
+
};
|
|
48
|
+
const service = new WhatsAppService_1.WhatsAppService(config);
|
|
49
|
+
const adapter = new WhatsAppChannelAdapter_1.WhatsAppChannelAdapter(service);
|
|
50
|
+
const sendMessageTool = new sendMessage_1.WhatsAppSendMessageTool(service);
|
|
51
|
+
const sendMediaTool = new sendMedia_1.WhatsAppSendMediaTool(service);
|
|
52
|
+
const priority = options.priority ?? 50;
|
|
53
|
+
return {
|
|
54
|
+
name: '@framers/agentos-ext-channel-whatsapp',
|
|
55
|
+
version: '0.1.0',
|
|
56
|
+
descriptors: [
|
|
57
|
+
{ id: 'whatsappChannelSendMessage', kind: 'tool', priority, payload: sendMessageTool },
|
|
58
|
+
{ id: 'whatsappChannelSendMedia', kind: 'tool', priority, payload: sendMediaTool },
|
|
59
|
+
{ id: 'whatsappChannel', kind: 'messaging-channel', priority, payload: adapter },
|
|
60
|
+
],
|
|
61
|
+
onActivate: async () => {
|
|
62
|
+
await service.initialize();
|
|
63
|
+
// Wire adapter event listeners after service is running
|
|
64
|
+
await adapter.initialize({ platform: 'whatsapp', credential: sessionData });
|
|
65
|
+
context.logger?.info('[WhatsAppChannel] Extension activated');
|
|
66
|
+
},
|
|
67
|
+
onDeactivate: async () => {
|
|
68
|
+
await adapter.shutdown();
|
|
69
|
+
await service.shutdown();
|
|
70
|
+
context.logger?.info('[WhatsAppChannel] Extension deactivated');
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
exports.default = createExtensionPack;
|
|
75
|
+
//# 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,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview ITool for sending media (image, document) via the WhatsApp channel adapter.
|
|
3
|
+
*/
|
|
4
|
+
import type { ITool, ToolExecutionContext, ToolExecutionResult } from '@framers/agentos';
|
|
5
|
+
import type { WhatsAppService } from '../WhatsAppService';
|
|
6
|
+
export declare class WhatsAppSendMediaTool implements ITool {
|
|
7
|
+
private readonly service;
|
|
8
|
+
readonly id = "whatsappChannelSendMedia";
|
|
9
|
+
readonly name = "whatsappChannelSendMedia";
|
|
10
|
+
readonly displayName = "Send WhatsApp Media";
|
|
11
|
+
readonly description = "Send an image or document to a WhatsApp chat via the channel adapter.";
|
|
12
|
+
readonly category = "communication";
|
|
13
|
+
readonly version = "0.1.0";
|
|
14
|
+
readonly hasSideEffects = true;
|
|
15
|
+
readonly inputSchema: {
|
|
16
|
+
type: "object";
|
|
17
|
+
required: readonly ["jid", "mediaType", "url"];
|
|
18
|
+
properties: {
|
|
19
|
+
jid: {
|
|
20
|
+
type: string;
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
mediaType: {
|
|
24
|
+
type: string;
|
|
25
|
+
enum: string[];
|
|
26
|
+
description: string;
|
|
27
|
+
};
|
|
28
|
+
url: {
|
|
29
|
+
type: string;
|
|
30
|
+
description: string;
|
|
31
|
+
};
|
|
32
|
+
caption: {
|
|
33
|
+
type: string;
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
filename: {
|
|
37
|
+
type: string;
|
|
38
|
+
description: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
readonly outputSchema: {
|
|
43
|
+
type: "object";
|
|
44
|
+
properties: {
|
|
45
|
+
messageId: {
|
|
46
|
+
type: string;
|
|
47
|
+
description: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
constructor(service: WhatsAppService);
|
|
52
|
+
execute(args: {
|
|
53
|
+
jid: string;
|
|
54
|
+
mediaType: 'image' | 'document';
|
|
55
|
+
url: string;
|
|
56
|
+
caption?: string;
|
|
57
|
+
filename?: string;
|
|
58
|
+
}, _context: ToolExecutionContext): Promise<ToolExecutionResult>;
|
|
59
|
+
validateArgs(args: Record<string, any>): {
|
|
60
|
+
isValid: boolean;
|
|
61
|
+
errors?: string[];
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
//# 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,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,qBAAa,qBAAsB,YAAW,KAAK;IA4BrC,OAAO,CAAC,QAAQ,CAAC,OAAO;IA3BpC,SAAgB,EAAE,8BAA8B;IAChD,SAAgB,IAAI,8BAA8B;IAClD,SAAgB,WAAW,yBAAyB;IACpD,SAAgB,WAAW,2EAA2E;IACtG,SAAgB,QAAQ,mBAAmB;IAC3C,SAAgB,OAAO,WAAW;IAClC,SAAgB,cAAc,QAAQ;IAEtC,SAAgB,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;MAUzB;IAEF,SAAgB,YAAY;;;;;;;;MAK1B;gBAE2B,OAAO,EAAE,eAAe;IAE/C,OAAO,CACX,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,GAAG,UAAU,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,EACxG,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC;IAgB/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;CASjF"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview ITool for sending media (image, document) via the WhatsApp channel adapter.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WhatsAppSendMediaTool = void 0;
|
|
7
|
+
class WhatsAppSendMediaTool {
|
|
8
|
+
constructor(service) {
|
|
9
|
+
this.service = service;
|
|
10
|
+
this.id = 'whatsappChannelSendMedia';
|
|
11
|
+
this.name = 'whatsappChannelSendMedia';
|
|
12
|
+
this.displayName = 'Send WhatsApp Media';
|
|
13
|
+
this.description = 'Send an image or document to a WhatsApp chat via the channel adapter.';
|
|
14
|
+
this.category = 'communication';
|
|
15
|
+
this.version = '0.1.0';
|
|
16
|
+
this.hasSideEffects = true;
|
|
17
|
+
this.inputSchema = {
|
|
18
|
+
type: 'object',
|
|
19
|
+
required: ['jid', 'mediaType', 'url'],
|
|
20
|
+
properties: {
|
|
21
|
+
jid: { type: 'string', description: 'Target JID (e.g., 1234567890@s.whatsapp.net or group-id@g.us)' },
|
|
22
|
+
mediaType: { type: 'string', enum: ['image', 'document'], description: 'Type of media to send' },
|
|
23
|
+
url: { type: 'string', description: 'URL of the media file' },
|
|
24
|
+
caption: { type: 'string', description: 'Optional caption (images only)' },
|
|
25
|
+
filename: { type: 'string', description: 'Filename (documents only)' },
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
this.outputSchema = {
|
|
29
|
+
type: 'object',
|
|
30
|
+
properties: {
|
|
31
|
+
messageId: { type: 'string', description: 'Sent message ID' },
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
async execute(args, _context) {
|
|
36
|
+
try {
|
|
37
|
+
let result;
|
|
38
|
+
if (args.mediaType === 'image') {
|
|
39
|
+
result = await this.service.sendImage(args.jid, args.url, args.caption);
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
result = await this.service.sendDocument(args.jid, args.url, args.filename);
|
|
43
|
+
}
|
|
44
|
+
return { success: true, output: { messageId: result.key.id } };
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
return { success: false, error: error.message };
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
validateArgs(args) {
|
|
51
|
+
const errors = [];
|
|
52
|
+
if (!args.jid)
|
|
53
|
+
errors.push('jid is required');
|
|
54
|
+
if (!args.mediaType || !['image', 'document'].includes(args.mediaType)) {
|
|
55
|
+
errors.push('mediaType must be "image" or "document"');
|
|
56
|
+
}
|
|
57
|
+
if (!args.url)
|
|
58
|
+
errors.push('url is required');
|
|
59
|
+
return { isValid: errors.length === 0, errors };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.WhatsAppSendMediaTool = WhatsAppSendMediaTool;
|
|
63
|
+
//# 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,qBAAqB;IA4BhC,YAA6B,OAAwB;QAAxB,YAAO,GAAP,OAAO,CAAiB;QA3BrC,OAAE,GAAG,0BAA0B,CAAC;QAChC,SAAI,GAAG,0BAA0B,CAAC;QAClC,gBAAW,GAAG,qBAAqB,CAAC;QACpC,gBAAW,GAAG,uEAAuE,CAAC;QACtF,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,KAAK,EAAE,WAAW,EAAE,KAAK,CAAU;YAC9C,UAAU,EAAE;gBACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+DAA+D,EAAE;gBACrG,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,WAAW,EAAE,uBAAuB,EAAE;gBAChG,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,uBAAuB,EAAE;gBAC7D,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE;gBAC1E,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,2BAA2B,EAAE;aACvE;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;IAEsD,CAAC;IAEzD,KAAK,CAAC,OAAO,CACX,IAAwG,EACxG,QAA8B;QAE9B,IAAI,CAAC;YACH,IAAI,MAA+B,CAAC;YAEpC,IAAI,IAAI,CAAC,SAAS,KAAK,OAAO,EAAE,CAAC;gBAC/B,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAC1E,CAAC;iBAAM,CAAC;gBACN,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC9E,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC;QACjE,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,GAAG;YAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACvE,MAAM,CAAC,IAAI,CAAC,yCAAyC,CAAC,CAAC;QACzD,CAAC;QACD,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;AA1DD,sDA0DC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview ITool for sending text messages via the WhatsApp channel adapter.
|
|
3
|
+
*/
|
|
4
|
+
import type { ITool, ToolExecutionContext, ToolExecutionResult } from '@framers/agentos';
|
|
5
|
+
import type { WhatsAppService } from '../WhatsAppService';
|
|
6
|
+
export declare class WhatsAppSendMessageTool implements ITool {
|
|
7
|
+
private readonly service;
|
|
8
|
+
readonly id = "whatsappChannelSendMessage";
|
|
9
|
+
readonly name = "whatsappChannelSendMessage";
|
|
10
|
+
readonly displayName = "Send WhatsApp Message";
|
|
11
|
+
readonly description = "Send a text message to a WhatsApp chat via the channel adapter.";
|
|
12
|
+
readonly category = "communication";
|
|
13
|
+
readonly version = "0.1.0";
|
|
14
|
+
readonly hasSideEffects = true;
|
|
15
|
+
readonly inputSchema: {
|
|
16
|
+
type: "object";
|
|
17
|
+
required: readonly ["jid", "text"];
|
|
18
|
+
properties: {
|
|
19
|
+
jid: {
|
|
20
|
+
type: string;
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
text: {
|
|
24
|
+
type: string;
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
readonly outputSchema: {
|
|
30
|
+
type: "object";
|
|
31
|
+
properties: {
|
|
32
|
+
messageId: {
|
|
33
|
+
type: string;
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
jid: {
|
|
37
|
+
type: string;
|
|
38
|
+
description: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
constructor(service: WhatsAppService);
|
|
43
|
+
execute(args: {
|
|
44
|
+
jid: string;
|
|
45
|
+
text: string;
|
|
46
|
+
}, _context: ToolExecutionContext): Promise<ToolExecutionResult>;
|
|
47
|
+
validateArgs(args: Record<string, any>): {
|
|
48
|
+
isValid: boolean;
|
|
49
|
+
errors?: string[];
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
//# 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,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1D,qBAAa,uBAAwB,YAAW,KAAK;IA0BvC,OAAO,CAAC,QAAQ,CAAC,OAAO;IAzBpC,SAAgB,EAAE,gCAAgC;IAClD,SAAgB,IAAI,gCAAgC;IACpD,SAAgB,WAAW,2BAA2B;IACtD,SAAgB,WAAW,qEAAqE;IAChG,SAAgB,QAAQ,mBAAmB;IAC3C,SAAgB,OAAO,WAAW;IAClC,SAAgB,cAAc,QAAQ;IAEtC,SAAgB,WAAW;;;;;;;;;;;;;MAOzB;IAEF,SAAgB,YAAY;;;;;;;;;;;;MAM1B;gBAE2B,OAAO,EAAE,eAAe;IAE/C,OAAO,CACX,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EACnC,QAAQ,EAAE,oBAAoB,GAC7B,OAAO,CAAC,mBAAmB,CAAC;IAa/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,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview ITool for sending text messages via the WhatsApp channel adapter.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.WhatsAppSendMessageTool = void 0;
|
|
7
|
+
class WhatsAppSendMessageTool {
|
|
8
|
+
constructor(service) {
|
|
9
|
+
this.service = service;
|
|
10
|
+
this.id = 'whatsappChannelSendMessage';
|
|
11
|
+
this.name = 'whatsappChannelSendMessage';
|
|
12
|
+
this.displayName = 'Send WhatsApp Message';
|
|
13
|
+
this.description = 'Send a text message to a WhatsApp chat via the channel adapter.';
|
|
14
|
+
this.category = 'communication';
|
|
15
|
+
this.version = '0.1.0';
|
|
16
|
+
this.hasSideEffects = true;
|
|
17
|
+
this.inputSchema = {
|
|
18
|
+
type: 'object',
|
|
19
|
+
required: ['jid', 'text'],
|
|
20
|
+
properties: {
|
|
21
|
+
jid: { type: 'string', description: 'Target JID (e.g., 1234567890@s.whatsapp.net or group-id@g.us)' },
|
|
22
|
+
text: { type: 'string', description: 'Message text' },
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
this.outputSchema = {
|
|
26
|
+
type: 'object',
|
|
27
|
+
properties: {
|
|
28
|
+
messageId: { type: 'string', description: 'Sent message ID' },
|
|
29
|
+
jid: { type: 'string', description: 'Target JID' },
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
async execute(args, _context) {
|
|
34
|
+
try {
|
|
35
|
+
const result = await this.service.sendMessage(args.jid, args.text);
|
|
36
|
+
return {
|
|
37
|
+
success: true,
|
|
38
|
+
output: { messageId: result.key.id, jid: args.jid },
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
return { success: false, error: error.message };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
validateArgs(args) {
|
|
46
|
+
const errors = [];
|
|
47
|
+
if (!args.jid)
|
|
48
|
+
errors.push('jid is required');
|
|
49
|
+
else if (typeof args.jid !== 'string')
|
|
50
|
+
errors.push('jid must be a string');
|
|
51
|
+
if (!args.text)
|
|
52
|
+
errors.push('text is required');
|
|
53
|
+
else if (typeof args.text !== 'string')
|
|
54
|
+
errors.push('text must be a string');
|
|
55
|
+
return { isValid: errors.length === 0, errors };
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
exports.WhatsAppSendMessageTool = WhatsAppSendMessageTool;
|
|
59
|
+
//# sourceMappingURL=sendMessage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sendMessage.js","sourceRoot":"","sources":["../../src/tools/sendMessage.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAKH,MAAa,uBAAuB;IA0BlC,YAA6B,OAAwB;QAAxB,YAAO,GAAP,OAAO,CAAiB;QAzBrC,OAAE,GAAG,4BAA4B,CAAC;QAClC,SAAI,GAAG,4BAA4B,CAAC;QACpC,gBAAW,GAAG,uBAAuB,CAAC;QACtC,gBAAW,GAAG,iEAAiE,CAAC;QAChF,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,KAAK,EAAE,MAAM,CAAU;YAClC,UAAU,EAAE;gBACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,+DAA+D,EAAE;gBACrG,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE;aACtD;SACF,CAAC;QAEc,iBAAY,GAAG;YAC7B,IAAI,EAAE,QAAiB;YACvB,UAAU,EAAE;gBACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,EAAE;gBAC7D,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,YAAY,EAAE;aACnD;SACF,CAAC;IAEsD,CAAC;IAEzD,KAAK,CAAC,OAAO,CACX,IAAmC,EACnC,QAA8B;QAE9B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAEnE,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,MAAM,EAAE,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE;aACpD,CAAC;QACJ,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,GAAG;YAAE,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;aACzC,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ;YAAE,MAAM,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC3E,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;aAC3C,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;YAAE,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAClD,CAAC;CACF;AApDD,0DAoDC"}
|
package/manifest.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://agentos.sh/schemas/extension-manifest-v1.json",
|
|
3
|
+
"id": "com.framers.channels.whatsapp",
|
|
4
|
+
"name": "WhatsApp Channel Extension",
|
|
5
|
+
"version": "0.1.0",
|
|
6
|
+
"description": "Bidirectional WhatsApp messaging via Baileys — supports text, images, documents, typing indicators, and groups.",
|
|
7
|
+
"categories": ["channel", "communication"],
|
|
8
|
+
"platforms": ["whatsapp"],
|
|
9
|
+
"sdk": "@whiskeysockets/baileys",
|
|
10
|
+
"extensions": [
|
|
11
|
+
{
|
|
12
|
+
"kind": "tool",
|
|
13
|
+
"id": "whatsappChannelSendMessage",
|
|
14
|
+
"displayName": "Send WhatsApp Message"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"kind": "tool",
|
|
18
|
+
"id": "whatsappChannelSendMedia",
|
|
19
|
+
"displayName": "Send WhatsApp Media"
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"kind": "messaging-channel",
|
|
23
|
+
"id": "whatsappChannel",
|
|
24
|
+
"displayName": "WhatsApp Channel Adapter"
|
|
25
|
+
}
|
|
26
|
+
],
|
|
27
|
+
"requiredSecrets": ["whatsapp.sessionData"],
|
|
28
|
+
"features": [
|
|
29
|
+
"Text messages",
|
|
30
|
+
"Image and document sending",
|
|
31
|
+
"Rate limiting with queue management",
|
|
32
|
+
"Group chat support",
|
|
33
|
+
"Typing indicators (composing/paused)",
|
|
34
|
+
"Read receipts",
|
|
35
|
+
"Audio message support"
|
|
36
|
+
]
|
|
37
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@framers/agentos-ext-channel-whatsapp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "WhatsApp messaging channel adapter for AgentOS — bidirectional messaging via Baileys",
|
|
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", "whatsapp", "baileys", "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
|
+
"@whiskeysockets/baileys": ">=6.0.0"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@framers/agentos": "workspace:*",
|
|
24
|
+
"@types/node": "^20.0.0",
|
|
25
|
+
"typescript": "^5.0.0",
|
|
26
|
+
"vitest": "^1.0.0"
|
|
27
|
+
},
|
|
28
|
+
"engines": { "node": ">=18.0.0" }
|
|
29
|
+
}
|