@adonis-agora/agent 0.62.0 → 0.64.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/CHANGELOG.md +40 -0
- package/dist/providers/agent_provider.d.ts.map +1 -1
- package/dist/providers/agent_provider.js +1 -12
- package/dist/providers/agent_provider.js.map +1 -1
- package/dist/src/action-proposal-service.d.ts +3 -2
- package/dist/src/action-proposal-service.d.ts.map +1 -1
- package/dist/src/action-proposal-service.js +1 -0
- package/dist/src/action-proposal-service.js.map +1 -1
- package/dist/src/action-proposal-text.d.ts +5 -0
- package/dist/src/action-proposal-text.d.ts.map +1 -1
- package/dist/src/action-proposal-text.js +1 -0
- package/dist/src/action-proposal-text.js.map +1 -1
- package/dist/src/actor-resolver.d.ts +12 -4
- package/dist/src/actor-resolver.d.ts.map +1 -1
- package/dist/src/actor-resolver.js +24 -7
- package/dist/src/actor-resolver.js.map +1 -1
- package/dist/src/ag-ui/adapter.d.ts.map +1 -1
- package/dist/src/ag-ui/adapter.js +32 -6
- package/dist/src/ag-ui/adapter.js.map +1 -1
- package/dist/src/ag-ui/core/encoder.d.ts +2 -1
- package/dist/src/ag-ui/core/encoder.d.ts.map +1 -1
- package/dist/src/ag-ui/core/encoder.js +16 -5
- package/dist/src/ag-ui/core/encoder.js.map +1 -1
- package/dist/src/ag-ui/core/index.d.ts +2 -2
- package/dist/src/ag-ui/core/index.d.ts.map +1 -1
- package/dist/src/ag-ui/core/index.js +2 -2
- package/dist/src/ag-ui/core/index.js.map +1 -1
- package/dist/src/ag-ui/core/input.d.ts +21 -3
- package/dist/src/ag-ui/core/input.d.ts.map +1 -1
- package/dist/src/ag-ui/core/input.js +24 -6
- package/dist/src/ag-ui/core/input.js.map +1 -1
- package/dist/src/ag-ui/core/stream.d.ts +24 -2
- package/dist/src/ag-ui/core/stream.d.ts.map +1 -1
- package/dist/src/ag-ui/core/stream.js +25 -3
- package/dist/src/ag-ui/core/stream.js.map +1 -1
- package/dist/src/ag-ui/core/types.d.ts +2 -2
- package/dist/src/ag-ui/core/types.d.ts.map +1 -1
- package/dist/src/ag-ui/core/types.js +2 -2
- package/dist/src/ag-ui/core/types.js.map +1 -1
- package/dist/src/ag-ui/frames.d.ts +5 -1
- package/dist/src/ag-ui/frames.d.ts.map +1 -1
- package/dist/src/ag-ui/frames.js +13 -3
- package/dist/src/ag-ui/frames.js.map +1 -1
- package/dist/src/ag-ui/index.d.ts +1 -1
- package/dist/src/ag-ui/index.d.ts.map +1 -1
- package/dist/src/ag-ui/index.js +1 -1
- package/dist/src/ag-ui/index.js.map +1 -1
- package/dist/src/agent-service.d.ts +36 -3
- package/dist/src/agent-service.d.ts.map +1 -1
- package/dist/src/agent-service.js +65 -1
- package/dist/src/agent-service.js.map +1 -1
- package/dist/src/attachment-limits.d.ts +10 -0
- package/dist/src/attachment-limits.d.ts.map +1 -0
- package/dist/src/attachment-limits.js +13 -0
- package/dist/src/attachment-limits.js.map +1 -0
- package/dist/src/channels/adapters/evolution_api.d.ts +58 -0
- package/dist/src/channels/adapters/evolution_api.d.ts.map +1 -0
- package/dist/src/channels/adapters/evolution_api.js +256 -0
- package/dist/src/channels/adapters/evolution_api.js.map +1 -0
- package/dist/src/channels/adapters/telegram.d.ts +34 -0
- package/dist/src/channels/adapters/telegram.d.ts.map +1 -0
- package/dist/src/channels/adapters/telegram.js +196 -0
- package/dist/src/channels/adapters/telegram.js.map +1 -0
- package/dist/src/channels/adapters/whatsapp_cloud.d.ts +31 -0
- package/dist/src/channels/adapters/whatsapp_cloud.d.ts.map +1 -0
- package/dist/src/channels/adapters/whatsapp_cloud.js +177 -0
- package/dist/src/channels/adapters/whatsapp_cloud.js.map +1 -0
- package/dist/src/channels/adapters/whatsmiau.d.ts +26 -0
- package/dist/src/channels/adapters/whatsmiau.d.ts.map +1 -0
- package/dist/src/channels/adapters/whatsmiau.js +18 -0
- package/dist/src/channels/adapters/whatsmiau.js.map +1 -0
- package/dist/src/channels/handler.d.ts +190 -0
- package/dist/src/channels/handler.d.ts.map +1 -0
- package/dist/src/channels/handler.js +626 -0
- package/dist/src/channels/handler.js.map +1 -0
- package/dist/src/channels/http.d.ts +45 -0
- package/dist/src/channels/http.d.ts.map +1 -0
- package/dist/src/channels/http.js +147 -0
- package/dist/src/channels/http.js.map +1 -0
- package/dist/src/channels/index.d.ts +17 -0
- package/dist/src/channels/index.d.ts.map +1 -0
- package/dist/src/channels/index.js +16 -0
- package/dist/src/channels/index.js.map +1 -0
- package/dist/src/channels/markdown.d.ts +12 -0
- package/dist/src/channels/markdown.d.ts.map +1 -0
- package/dist/src/channels/markdown.js +120 -0
- package/dist/src/channels/markdown.js.map +1 -0
- package/dist/src/channels/questions.d.ts +45 -0
- package/dist/src/channels/questions.d.ts.map +1 -0
- package/dist/src/channels/questions.js +131 -0
- package/dist/src/channels/questions.js.map +1 -0
- package/dist/src/channels/split.d.ts +8 -0
- package/dist/src/channels/split.d.ts.map +1 -0
- package/dist/src/channels/split.js +45 -0
- package/dist/src/channels/split.js.map +1 -0
- package/dist/src/channels/store.d.ts +78 -0
- package/dist/src/channels/store.d.ts.map +1 -0
- package/dist/src/channels/store.js +151 -0
- package/dist/src/channels/store.js.map +1 -0
- package/dist/src/channels/types.d.ts +145 -0
- package/dist/src/channels/types.d.ts.map +1 -0
- package/dist/src/channels/types.js +7 -0
- package/dist/src/channels/types.js.map +1 -0
- package/dist/src/genui/builtins.d.ts.map +1 -1
- package/dist/src/genui/builtins.js +65 -6
- package/dist/src/genui/builtins.js.map +1 -1
- package/dist/src/genui/catalog.d.ts +11 -2
- package/dist/src/genui/catalog.d.ts.map +1 -1
- package/dist/src/genui/catalog.js +8 -0
- package/dist/src/genui/catalog.js.map +1 -1
- package/dist/src/genui/text.d.ts +4 -3
- package/dist/src/genui/text.d.ts.map +1 -1
- package/dist/src/genui/text.js +25 -24
- package/dist/src/genui/text.js.map +1 -1
- package/dist/src/genui/tools.d.ts +2 -1
- package/dist/src/genui/tools.d.ts.map +1 -1
- package/dist/src/genui/tools.js +6 -7
- package/dist/src/genui/tools.js.map +1 -1
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/opencode/turns.d.ts +4 -2
- package/dist/src/opencode/turns.d.ts.map +1 -1
- package/dist/src/opencode/turns.js.map +1 -1
- package/dist/src/react/core/ag-ui-backend.d.ts +38 -14
- package/dist/src/react/core/ag-ui-backend.d.ts.map +1 -1
- package/dist/src/react/core/ag-ui-backend.js +182 -17
- package/dist/src/react/core/ag-ui-backend.js.map +1 -1
- package/dist/src/react/core/agent-chat-transport.d.ts.map +1 -1
- package/dist/src/react/core/agent-chat-transport.js +22 -1
- package/dist/src/react/core/agent-chat-transport.js.map +1 -1
- package/dist/src/react/core/backend.d.ts +11 -0
- package/dist/src/react/core/backend.d.ts.map +1 -1
- package/dist/src/react/core/backend.js.map +1 -1
- package/dist/src/react/core/index.d.ts +1 -1
- package/dist/src/react/core/index.d.ts.map +1 -1
- package/dist/src/react/core/index.js.map +1 -1
- package/dist/src/stores/lucid-schema.d.ts +24 -6
- package/dist/src/stores/lucid-schema.d.ts.map +1 -1
- package/dist/src/stores/lucid-schema.js +47 -6
- package/dist/src/stores/lucid-schema.js.map +1 -1
- package/dist/src/stores/lucid.d.ts +2 -0
- package/dist/src/stores/lucid.d.ts.map +1 -1
- package/dist/src/stores/lucid.js +4 -0
- package/dist/src/stores/lucid.js.map +1 -1
- package/package.json +6 -1
- package/skills/agent-setup/SKILL.md +40 -3
- package/skills/agent-tools/SKILL.md +3 -0
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { ChannelDeliveryError, ChannelMediaTooLargeError, fetchBytes, postJson, record, safeEqual, sizeOf, str, } from '../http.js';
|
|
2
|
+
import { unescapeTelegramMarkdown } from '../markdown.js';
|
|
3
|
+
/** Telegram's limits: message text, buttons we put in one keyboard. */
|
|
4
|
+
const MAX_TEXT = 4096;
|
|
5
|
+
const MAX_BUTTONS = 8;
|
|
6
|
+
/** The file a message carries: the largest photo size, a document, a voice note, audio, video, a sticker. */
|
|
7
|
+
function mediaOf(message) {
|
|
8
|
+
const photo = Array.isArray(message.photo) ? record(message.photo.at(-1)) : undefined;
|
|
9
|
+
const candidates = [
|
|
10
|
+
['image', photo, 'image/jpeg'],
|
|
11
|
+
['document', record(message.document), undefined],
|
|
12
|
+
['audio', record(message.voice), 'audio/ogg'],
|
|
13
|
+
['audio', record(message.audio), undefined],
|
|
14
|
+
['video', record(message.video), 'video/mp4'],
|
|
15
|
+
['video', record(message.video_note), 'video/mp4'],
|
|
16
|
+
[
|
|
17
|
+
'sticker',
|
|
18
|
+
record(message.sticker),
|
|
19
|
+
record(message.sticker)?.is_animated === true
|
|
20
|
+
? 'application/x-tgsticker'
|
|
21
|
+
: record(message.sticker)?.is_video === true
|
|
22
|
+
? 'video/webm'
|
|
23
|
+
: 'image/webp',
|
|
24
|
+
],
|
|
25
|
+
];
|
|
26
|
+
for (const [kind, body, implied] of candidates) {
|
|
27
|
+
const fileId = str(body?.file_id);
|
|
28
|
+
if (!body || fileId === undefined)
|
|
29
|
+
continue;
|
|
30
|
+
const contentType = str(body.mime_type) ?? implied;
|
|
31
|
+
const filename = str(body.file_name);
|
|
32
|
+
const sizeBytes = sizeOf(body.file_size);
|
|
33
|
+
return {
|
|
34
|
+
kind,
|
|
35
|
+
ref: fileId,
|
|
36
|
+
...(contentType !== undefined ? { contentType } : {}),
|
|
37
|
+
...(filename !== undefined ? { filename } : {}),
|
|
38
|
+
...(sizeBytes !== undefined ? { sizeBytes } : {}),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
/** The label of the inline button with `data` on the message it was pressed on. */
|
|
44
|
+
function pressedLabel(message, data) {
|
|
45
|
+
const rows = record(message?.reply_markup)?.inline_keyboard;
|
|
46
|
+
if (!Array.isArray(rows))
|
|
47
|
+
return undefined;
|
|
48
|
+
for (const row of rows) {
|
|
49
|
+
if (!Array.isArray(row))
|
|
50
|
+
continue;
|
|
51
|
+
for (const button of row) {
|
|
52
|
+
if (record(button)?.callback_data === data)
|
|
53
|
+
return str(record(button)?.text);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* A Telegram bot over the [Bot API](https://core.telegram.org/bots/api) webhook. Register it with
|
|
60
|
+
* `setWebhook({ url, secret_token, allowed_updates: ['message', 'callback_query'] })`.
|
|
61
|
+
*
|
|
62
|
+
* Reads text messages, media (photos, documents, voice notes, audio, video, stickers — downloaded
|
|
63
|
+
* with `getFile`, which serves up to 20 MB) and inline-keyboard presses (`callback_query`, answered with
|
|
64
|
+
* `answerCallbackQuery` and the keyboard removed so it cannot be pressed twice); ignores bots and
|
|
65
|
+
* (unless `groups`) group chats. Sends `sendMessage` in MarkdownV2 — when Telegram refuses the
|
|
66
|
+
* formatting, the same text goes again as plain text.
|
|
67
|
+
*/
|
|
68
|
+
export function telegram(options) {
|
|
69
|
+
const name = options.name ?? 'telegram';
|
|
70
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
71
|
+
const timeoutMs = options.timeoutMs ?? 20_000;
|
|
72
|
+
const markdown = options.markdown !== false;
|
|
73
|
+
const origin = (options.apiUrl ?? 'https://api.telegram.org').replace(/\/+$/, '');
|
|
74
|
+
const api = `${origin}/bot${options.botToken}`;
|
|
75
|
+
const call = (method, body) => postJson(name, fetcher, `${api}/${method}`, {}, body, timeoutMs);
|
|
76
|
+
const privateOnly = (chat) => options.groups === true || chat?.type === 'private';
|
|
77
|
+
return {
|
|
78
|
+
name,
|
|
79
|
+
capabilities: {
|
|
80
|
+
buttons: MAX_BUTTONS,
|
|
81
|
+
markdown: markdown ? 'telegram' : 'none',
|
|
82
|
+
maxLength: MAX_TEXT,
|
|
83
|
+
},
|
|
84
|
+
verify(request) {
|
|
85
|
+
return safeEqual(request.header('x-telegram-bot-api-secret-token'), options.secretToken);
|
|
86
|
+
},
|
|
87
|
+
parse(body) {
|
|
88
|
+
const update = record(body);
|
|
89
|
+
const updateId = update?.update_id;
|
|
90
|
+
if (typeof updateId !== 'number' && typeof updateId !== 'string')
|
|
91
|
+
return null;
|
|
92
|
+
const id = String(updateId);
|
|
93
|
+
const message = record(update?.message);
|
|
94
|
+
if (message) {
|
|
95
|
+
const chat = record(message.chat);
|
|
96
|
+
const from = record(message.from);
|
|
97
|
+
const media = mediaOf(message);
|
|
98
|
+
const text = (str(message.text) ?? str(message.caption) ?? '').trim();
|
|
99
|
+
if (!chat || !from || from.is_bot === true || !privateOnly(chat))
|
|
100
|
+
return null;
|
|
101
|
+
if (text === '' && !media)
|
|
102
|
+
return null;
|
|
103
|
+
return {
|
|
104
|
+
id,
|
|
105
|
+
from: String(from.id),
|
|
106
|
+
conversation: String(chat.id),
|
|
107
|
+
text,
|
|
108
|
+
...(media ? { media: [media] } : {}),
|
|
109
|
+
raw: update,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const query = record(update?.callback_query);
|
|
113
|
+
if (query) {
|
|
114
|
+
const from = record(query.from);
|
|
115
|
+
const pressedOn = record(query.message);
|
|
116
|
+
const chat = record(pressedOn?.chat);
|
|
117
|
+
const data = str(query.data);
|
|
118
|
+
if (!from || !chat || !data || from.is_bot === true || !privateOnly(chat))
|
|
119
|
+
return null;
|
|
120
|
+
return {
|
|
121
|
+
id,
|
|
122
|
+
from: String(from.id),
|
|
123
|
+
conversation: String(chat.id),
|
|
124
|
+
text: pressedLabel(pressedOn, data) ?? data,
|
|
125
|
+
buttonId: data,
|
|
126
|
+
raw: update,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
return null;
|
|
130
|
+
},
|
|
131
|
+
async acknowledge(message) {
|
|
132
|
+
const query = record(record(message.raw)?.callback_query);
|
|
133
|
+
const queryId = str(query?.id);
|
|
134
|
+
if (queryId === undefined)
|
|
135
|
+
return;
|
|
136
|
+
await call('answerCallbackQuery', { callback_query_id: queryId }).catch(() => { });
|
|
137
|
+
const pressedOn = record(query?.message);
|
|
138
|
+
if (pressedOn?.message_id !== undefined) {
|
|
139
|
+
await call('editMessageReplyMarkup', {
|
|
140
|
+
chat_id: message.conversation,
|
|
141
|
+
message_id: pressedOn.message_id,
|
|
142
|
+
reply_markup: { inline_keyboard: [] },
|
|
143
|
+
}).catch(() => { });
|
|
144
|
+
}
|
|
145
|
+
},
|
|
146
|
+
async download(media, { maxBytes }) {
|
|
147
|
+
if (media.sizeBytes !== undefined && media.sizeBytes > maxBytes) {
|
|
148
|
+
throw new ChannelMediaTooLargeError(maxBytes);
|
|
149
|
+
}
|
|
150
|
+
const answer = record(await call('getFile', { file_id: media.ref }));
|
|
151
|
+
const path = str(record(answer?.result)?.file_path);
|
|
152
|
+
if (path === undefined) {
|
|
153
|
+
// The Bot API serves files up to 20 MB; a larger one has no path.
|
|
154
|
+
throw new ChannelDeliveryError(name, null, `${name}: the file could not be downloaded`);
|
|
155
|
+
}
|
|
156
|
+
const file = await fetchBytes(name, fetcher, `${origin}/file/bot${options.botToken}/${path}`, {}, timeoutMs, maxBytes);
|
|
157
|
+
return {
|
|
158
|
+
data: file.data,
|
|
159
|
+
contentType: media.contentType ?? file.contentType ?? 'application/octet-stream',
|
|
160
|
+
...(media.filename !== undefined ? { filename: media.filename } : {}),
|
|
161
|
+
};
|
|
162
|
+
},
|
|
163
|
+
async send(conversation, message) {
|
|
164
|
+
const body = {
|
|
165
|
+
chat_id: conversation,
|
|
166
|
+
text: message.text,
|
|
167
|
+
link_preview_options: { is_disabled: true },
|
|
168
|
+
...(message.buttons !== undefined && message.buttons.length > 0
|
|
169
|
+
? {
|
|
170
|
+
reply_markup: {
|
|
171
|
+
inline_keyboard: [
|
|
172
|
+
message.buttons
|
|
173
|
+
.slice(0, MAX_BUTTONS)
|
|
174
|
+
.map((button) => ({ text: button.label, callback_data: button.id })),
|
|
175
|
+
],
|
|
176
|
+
},
|
|
177
|
+
}
|
|
178
|
+
: {}),
|
|
179
|
+
};
|
|
180
|
+
if (!markdown) {
|
|
181
|
+
await call('sendMessage', body);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
try {
|
|
185
|
+
await call('sendMessage', { ...body, parse_mode: 'MarkdownV2' });
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
// "can't parse entities": the same words, unformatted, beat no answer.
|
|
189
|
+
if (!(error instanceof ChannelDeliveryError) || error.status !== 400)
|
|
190
|
+
throw error;
|
|
191
|
+
await call('sendMessage', { ...body, text: unescapeTelegramMarkdown(message.text) });
|
|
192
|
+
}
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=telegram.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../../../src/channels/adapters/telegram.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { type ChannelFetch } from '../http.js';
|
|
2
|
+
import type { ChannelAdapter } from '../types.js';
|
|
3
|
+
export interface WhatsappCloudOptions {
|
|
4
|
+
/** The business phone number's id (WhatsApp Manager → API setup) — not the number itself. */
|
|
5
|
+
phoneNumberId: string;
|
|
6
|
+
/** A system-user (or temporary) access token with `whatsapp_business_messaging`. */
|
|
7
|
+
accessToken: string;
|
|
8
|
+
/** The Meta app's secret: `X-Hub-Signature-256` is an HMAC of the raw body under it. */
|
|
9
|
+
appSecret: string;
|
|
10
|
+
/** The "Verify token" typed into the app's webhook settings, echoed by the subscription check. */
|
|
11
|
+
verifyToken: string;
|
|
12
|
+
/** Graph API version. Default `'v23.0'`. */
|
|
13
|
+
graphVersion?: string;
|
|
14
|
+
/** The adapter's name — the dedupe prefix and the decision's `via`. Default `'whatsapp'`. */
|
|
15
|
+
name?: string;
|
|
16
|
+
/** Per-request timeout. Default 20 s. */
|
|
17
|
+
timeoutMs?: number;
|
|
18
|
+
fetch?: ChannelFetch;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* WhatsApp through Meta's [Cloud API](https://developers.facebook.com/docs/whatsapp/cloud-api).
|
|
22
|
+
* Route both `GET` (the subscription check) and `POST` (messages) to the same handler, and subscribe
|
|
23
|
+
* the app to the `messages` field.
|
|
24
|
+
*
|
|
25
|
+
* Verifies `X-Hub-Signature-256` over the raw body; reads text, interactive button/list replies,
|
|
26
|
+
* template quick replies and media (image, audio, video, document, sticker — downloaded through the
|
|
27
|
+
* Graph API media endpoint) addressed to `phoneNumberId` (status updates are ignored); sends text and
|
|
28
|
+
* interactive reply buttons (at most 3, 20-character titles).
|
|
29
|
+
*/
|
|
30
|
+
export declare function whatsappCloud(options: WhatsappCloudOptions): ChannelAdapter;
|
|
31
|
+
//# sourceMappingURL=whatsapp_cloud.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp_cloud.d.ts","sourceRoot":"","sources":["../../../../src/channels/adapters/whatsapp_cloud.ts"],"names":[],"mappings":"AACA,OAAO,EAEL,KAAK,YAAY,EASlB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,cAAc,EAKf,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,oBAAoB;IACnC,6FAA6F;IAC7F,aAAa,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,WAAW,EAAE,MAAM,CAAC;IACpB,wFAAwF;IACxF,SAAS,EAAE,MAAM,CAAC;IAClB,kGAAkG;IAClG,WAAW,EAAE,MAAM,CAAC;IACpB,4CAA4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAwDD;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,cAAc,CAmI3E"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { createHmac } from 'node:crypto';
|
|
2
|
+
import { ChannelDeliveryError, ChannelMediaTooLargeError, fetchBytes, postJson, queryParam, record, safeEqual, sizeOf, str, } from '../http.js';
|
|
3
|
+
/** Cloud API limits: text body, interactive body, button title. */
|
|
4
|
+
const MAX_TEXT = 4096;
|
|
5
|
+
const MAX_INTERACTIVE_BODY = 1024;
|
|
6
|
+
const MAX_BUTTON_TITLE = 20;
|
|
7
|
+
const MAX_BUTTONS = 3;
|
|
8
|
+
const MEDIA_TYPES = ['image', 'audio', 'video', 'document', 'sticker'];
|
|
9
|
+
/** The file a Cloud API message carries (`{ id, mime_type, caption?, filename? }`), and its caption. */
|
|
10
|
+
function mediaOf(message) {
|
|
11
|
+
const kind = MEDIA_TYPES.find((type) => type === message.type);
|
|
12
|
+
const body = kind === undefined ? undefined : record(message[kind]);
|
|
13
|
+
const mediaId = str(body?.id);
|
|
14
|
+
if (kind === undefined || !body || mediaId === undefined)
|
|
15
|
+
return undefined;
|
|
16
|
+
const contentType = str(body.mime_type);
|
|
17
|
+
const filename = str(body.filename);
|
|
18
|
+
return {
|
|
19
|
+
media: {
|
|
20
|
+
kind,
|
|
21
|
+
ref: mediaId,
|
|
22
|
+
...(contentType !== undefined ? { contentType } : {}),
|
|
23
|
+
...(filename !== undefined ? { filename } : {}),
|
|
24
|
+
},
|
|
25
|
+
caption: str(body.caption),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function parseMessage(message) {
|
|
29
|
+
const id = str(message.id);
|
|
30
|
+
const from = str(message.from);
|
|
31
|
+
if (!id || !from)
|
|
32
|
+
return null;
|
|
33
|
+
const interactive = record(message.interactive);
|
|
34
|
+
const reply = record(interactive?.button_reply) ?? record(interactive?.list_reply);
|
|
35
|
+
// A template's quick-reply button.
|
|
36
|
+
const button = record(message.button);
|
|
37
|
+
const buttonId = str(reply?.id) ?? str(button?.payload);
|
|
38
|
+
const file = mediaOf(message);
|
|
39
|
+
const text = file
|
|
40
|
+
? (file.caption ?? '')
|
|
41
|
+
: (str(record(message.text)?.body) ?? str(reply?.title) ?? str(button?.text) ?? buttonId);
|
|
42
|
+
if (text === undefined || (text.trim() === '' && !file))
|
|
43
|
+
return null;
|
|
44
|
+
return {
|
|
45
|
+
id,
|
|
46
|
+
from,
|
|
47
|
+
conversation: from,
|
|
48
|
+
text: text.trim(),
|
|
49
|
+
...(buttonId !== undefined ? { buttonId } : {}),
|
|
50
|
+
...(file ? { media: [file.media] } : {}),
|
|
51
|
+
raw: message,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* WhatsApp through Meta's [Cloud API](https://developers.facebook.com/docs/whatsapp/cloud-api).
|
|
56
|
+
* Route both `GET` (the subscription check) and `POST` (messages) to the same handler, and subscribe
|
|
57
|
+
* the app to the `messages` field.
|
|
58
|
+
*
|
|
59
|
+
* Verifies `X-Hub-Signature-256` over the raw body; reads text, interactive button/list replies,
|
|
60
|
+
* template quick replies and media (image, audio, video, document, sticker — downloaded through the
|
|
61
|
+
* Graph API media endpoint) addressed to `phoneNumberId` (status updates are ignored); sends text and
|
|
62
|
+
* interactive reply buttons (at most 3, 20-character titles).
|
|
63
|
+
*/
|
|
64
|
+
export function whatsappCloud(options) {
|
|
65
|
+
const name = options.name ?? 'whatsapp';
|
|
66
|
+
const fetcher = options.fetch ?? globalThis.fetch;
|
|
67
|
+
const timeoutMs = options.timeoutMs ?? 20_000;
|
|
68
|
+
const graphVersion = options.graphVersion ?? 'v23.0';
|
|
69
|
+
const endpoint = `https://graph.facebook.com/${graphVersion}/${encodeURIComponent(options.phoneNumberId)}/messages`;
|
|
70
|
+
const post = (body) => postJson(name, fetcher, endpoint, { authorization: `Bearer ${options.accessToken}` }, { messaging_product: 'whatsapp', recipient_type: 'individual', ...body }, timeoutMs);
|
|
71
|
+
const sendText = (to, body) => post({ to, type: 'text', text: { body, preview_url: false } });
|
|
72
|
+
return {
|
|
73
|
+
name,
|
|
74
|
+
capabilities: { buttons: MAX_BUTTONS, markdown: 'whatsapp', maxLength: MAX_TEXT },
|
|
75
|
+
challenge(request) {
|
|
76
|
+
if (request.method !== 'GET')
|
|
77
|
+
return null;
|
|
78
|
+
const mode = queryParam(request.url, 'hub.mode');
|
|
79
|
+
const token = queryParam(request.url, 'hub.verify_token');
|
|
80
|
+
const challenge = queryParam(request.url, 'hub.challenge');
|
|
81
|
+
if (mode === 'subscribe' && challenge !== undefined && safeEqual(token, options.verifyToken))
|
|
82
|
+
return { status: 200, body: challenge, contentType: 'text/plain' };
|
|
83
|
+
return { status: 403, body: 'Forbidden', contentType: 'text/plain' };
|
|
84
|
+
},
|
|
85
|
+
verify(request) {
|
|
86
|
+
const signature = request.header('x-hub-signature-256');
|
|
87
|
+
if (request.rawBody === null || signature === undefined)
|
|
88
|
+
return false;
|
|
89
|
+
const expected = `sha256=${createHmac('sha256', options.appSecret).update(request.rawBody, 'utf8').digest('hex')}`;
|
|
90
|
+
return safeEqual(signature, expected);
|
|
91
|
+
},
|
|
92
|
+
parse(body) {
|
|
93
|
+
const envelope = record(body);
|
|
94
|
+
if (envelope?.object !== 'whatsapp_business_account' || !Array.isArray(envelope.entry))
|
|
95
|
+
return null;
|
|
96
|
+
const messages = [];
|
|
97
|
+
for (const entry of envelope.entry) {
|
|
98
|
+
const changes = record(entry)?.changes;
|
|
99
|
+
if (!Array.isArray(changes))
|
|
100
|
+
continue;
|
|
101
|
+
for (const change of changes) {
|
|
102
|
+
const value = record(record(change)?.value);
|
|
103
|
+
if (record(change)?.field !== 'messages' || !value)
|
|
104
|
+
continue;
|
|
105
|
+
if (str(record(value.metadata)?.phone_number_id) !== options.phoneNumberId)
|
|
106
|
+
continue;
|
|
107
|
+
if (!Array.isArray(value.messages))
|
|
108
|
+
continue;
|
|
109
|
+
for (const message of value.messages) {
|
|
110
|
+
const parsed = record(message) ? parseMessage(record(message)) : null;
|
|
111
|
+
if (parsed)
|
|
112
|
+
messages.push(parsed);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return messages;
|
|
117
|
+
},
|
|
118
|
+
async download(media, { maxBytes }) {
|
|
119
|
+
const auth = { authorization: `Bearer ${options.accessToken}` };
|
|
120
|
+
// The media id resolves to a short-lived url, which wants the same token.
|
|
121
|
+
const lookup = await fetchBytes(name, fetcher, `https://graph.facebook.com/${graphVersion}/${encodeURIComponent(String(media.ref))}`, auth, timeoutMs, 64 * 1024);
|
|
122
|
+
let info;
|
|
123
|
+
try {
|
|
124
|
+
info = record(JSON.parse(lookup.data.toString('utf8')));
|
|
125
|
+
}
|
|
126
|
+
catch {
|
|
127
|
+
info = undefined;
|
|
128
|
+
}
|
|
129
|
+
const url = str(info?.url);
|
|
130
|
+
if (url === undefined) {
|
|
131
|
+
throw new ChannelDeliveryError(name, null, `${name}: the media could not be resolved`);
|
|
132
|
+
}
|
|
133
|
+
const declared = sizeOf(info?.file_size);
|
|
134
|
+
if (declared !== undefined && declared > maxBytes)
|
|
135
|
+
throw new ChannelMediaTooLargeError(maxBytes);
|
|
136
|
+
const file = await fetchBytes(name, fetcher, url, auth, timeoutMs, maxBytes);
|
|
137
|
+
return {
|
|
138
|
+
data: file.data,
|
|
139
|
+
contentType: media.contentType ??
|
|
140
|
+
str(info?.mime_type) ??
|
|
141
|
+
file.contentType ??
|
|
142
|
+
'application/octet-stream',
|
|
143
|
+
...(media.filename !== undefined ? { filename: media.filename } : {}),
|
|
144
|
+
};
|
|
145
|
+
},
|
|
146
|
+
async send(conversation, message) {
|
|
147
|
+
if (message.buttons === undefined || message.buttons.length === 0) {
|
|
148
|
+
await sendText(conversation, message.buttons === undefined ? message.text : message.fallbackText);
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
let body = message.text;
|
|
152
|
+
if (body.length > MAX_INTERACTIVE_BODY) {
|
|
153
|
+
// The interactive body is short: the text goes first, the buttons under its last paragraph.
|
|
154
|
+
const cut = body.lastIndexOf('\n\n', body.length - 1);
|
|
155
|
+
const tail = cut > 0 ? body.slice(cut + 2) : '';
|
|
156
|
+
const head = tail.length > 0 && tail.length <= MAX_INTERACTIVE_BODY ? body.slice(0, cut) : body;
|
|
157
|
+
await sendText(conversation, head);
|
|
158
|
+
body = head === body ? '…' : tail;
|
|
159
|
+
}
|
|
160
|
+
await post({
|
|
161
|
+
to: conversation,
|
|
162
|
+
type: 'interactive',
|
|
163
|
+
interactive: {
|
|
164
|
+
type: 'button',
|
|
165
|
+
body: { text: body },
|
|
166
|
+
action: {
|
|
167
|
+
buttons: message.buttons.slice(0, MAX_BUTTONS).map((button) => ({
|
|
168
|
+
type: 'reply',
|
|
169
|
+
reply: { id: button.id, title: button.label.slice(0, MAX_BUTTON_TITLE) },
|
|
170
|
+
})),
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
});
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=whatsapp_cloud.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsapp_cloud.js","sourceRoot":"","sources":["../../../../src/channels/adapters/whatsapp_cloud.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ChannelAdapter } from '../types.js';
|
|
2
|
+
import { type EvolutionApiOptions } from './evolution_api.js';
|
|
3
|
+
export interface WhatsmiauOptions extends EvolutionApiOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The Whatsmiau server, host only — `http://whatsmiau:8080`. The route prefix is added for you:
|
|
6
|
+
* `/v1` (self-hosted Whatsmiau serves Evolution's routes there). A url that already ends in a
|
|
7
|
+
* version (`https://api.whatsmiau.dev/v2`, the hosted service) is used as is.
|
|
8
|
+
*/
|
|
9
|
+
url: string;
|
|
10
|
+
/**
|
|
11
|
+
* Send proposals with reply buttons (`POST /v1/message/sendButtons/{instance}`). Default `true`:
|
|
12
|
+
* Whatsmiau runs on whatsmeow, whose buttons WhatsApp renders. The buttons message carries the
|
|
13
|
+
* text instruction too; a 4xx from that endpoint falls back to the text-only message.
|
|
14
|
+
*/
|
|
15
|
+
buttons?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* WhatsApp through [Whatsmiau](https://github.com/verbeux-ai/whatsmiau) — an Evolution-compatible
|
|
19
|
+
* server built on whatsmeow (verbeux-ai's fork). The same webhook, routes and options as
|
|
20
|
+
* `evolutionApi()`, with two differences: the route prefix (`/v1`) is added to `url`, and reply
|
|
21
|
+
* buttons are on by default — Whatsmiau's render on the phone, where Evolution's (Baileys) did not in
|
|
22
|
+
* our test. Point the instance's webhook (`POST /v1/webhook/set/{instance}`, event
|
|
23
|
+
* `MESSAGES_UPSERT`) at the route, with the token.
|
|
24
|
+
*/
|
|
25
|
+
export declare function whatsmiau(options: WhatsmiauOptions): ChannelAdapter;
|
|
26
|
+
//# sourceMappingURL=whatsmiau.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsmiau.d.ts","sourceRoot":"","sources":["../../../../src/channels/adapters/whatsmiau.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,KAAK,mBAAmB,EAA0B,MAAM,oBAAoB,CAAC;AAEtF,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D;;;;OAIG;IACH,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAQD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,cAAc,CAEnE"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { evolutionFormatAdapter } from './evolution_api.js';
|
|
2
|
+
/** `http://host:8080` → `http://host:8080/v1`; a url ending in `/v1`, `/v2`… as is. */
|
|
3
|
+
function whatsmiauBase(url) {
|
|
4
|
+
const trimmed = url.replace(/\/+$/, '');
|
|
5
|
+
return /\/v\d+$/.test(trimmed) ? trimmed : `${trimmed}/v1`;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* WhatsApp through [Whatsmiau](https://github.com/verbeux-ai/whatsmiau) — an Evolution-compatible
|
|
9
|
+
* server built on whatsmeow (verbeux-ai's fork). The same webhook, routes and options as
|
|
10
|
+
* `evolutionApi()`, with two differences: the route prefix (`/v1`) is added to `url`, and reply
|
|
11
|
+
* buttons are on by default — Whatsmiau's render on the phone, where Evolution's (Baileys) did not in
|
|
12
|
+
* our test. Point the instance's webhook (`POST /v1/webhook/set/{instance}`, event
|
|
13
|
+
* `MESSAGES_UPSERT`) at the route, with the token.
|
|
14
|
+
*/
|
|
15
|
+
export function whatsmiau(options) {
|
|
16
|
+
return evolutionFormatAdapter({ ...options, url: whatsmiauBase(options.url) }, { buttons: true });
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=whatsmiau.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whatsmiau.js","sourceRoot":"","sources":["../../../../src/channels/adapters/whatsmiau.ts"],"names":[],"mappings":"AACA,OAAO,EAA4B,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAiBtF,uFAAuF;AACvF,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IACxC,OAAO,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,CAAC;AAC7D,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,SAAS,CAAC,OAAyB;IACjD,OAAO,sBAAsB,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,aAAa,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;AACpG,CAAC"}
|