@aigne/afs-telegram 1.11.0-beta.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +26 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs +11 -0
- package/dist/_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.mjs +10 -0
- package/dist/client.cjs +106 -0
- package/dist/client.d.cts +93 -0
- package/dist/client.d.cts.map +1 -0
- package/dist/client.d.mts +93 -0
- package/dist/client.d.mts.map +1 -0
- package/dist/client.mjs +106 -0
- package/dist/client.mjs.map +1 -0
- package/dist/index.cjs +432 -0
- package/dist/index.d.cts +113 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +113 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +433 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +56 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
const require_client = require('./client.cjs');
|
|
2
|
+
const require_decorate = require('./_virtual/_@oxc-project_runtime@0.108.0/helpers/decorate.cjs');
|
|
3
|
+
let _aigne_afs_provider = require("@aigne/afs/provider");
|
|
4
|
+
let _aigne_afs_messaging = require("@aigne/afs-messaging");
|
|
5
|
+
|
|
6
|
+
//#region src/index.ts
|
|
7
|
+
var AFSTelegram = class extends _aigne_afs_messaging.BaseMessageProvider {
|
|
8
|
+
static manifest() {
|
|
9
|
+
return {
|
|
10
|
+
name: "telegram",
|
|
11
|
+
description: "Telegram Bot API — bidirectional messaging via long-polling.\n- Multi-bot support with per-bot conversations\n- Long-polling for real-time message reception\n- Path: /:bot/conversations/:chatId/messages/:msgId",
|
|
12
|
+
uriTemplate: "telegram://{token}",
|
|
13
|
+
category: "messaging",
|
|
14
|
+
schema: {
|
|
15
|
+
type: "object",
|
|
16
|
+
properties: {
|
|
17
|
+
token: {
|
|
18
|
+
type: "string",
|
|
19
|
+
description: "Telegram Bot API token",
|
|
20
|
+
sensitive: true
|
|
21
|
+
},
|
|
22
|
+
chats: {
|
|
23
|
+
type: "array",
|
|
24
|
+
items: { type: "string" },
|
|
25
|
+
description: "Chat IDs to monitor"
|
|
26
|
+
},
|
|
27
|
+
autoStart: {
|
|
28
|
+
type: "boolean",
|
|
29
|
+
description: "Auto-start long-polling when mounted"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
required: ["token"]
|
|
33
|
+
},
|
|
34
|
+
tags: [
|
|
35
|
+
"telegram",
|
|
36
|
+
"messaging",
|
|
37
|
+
"chat",
|
|
38
|
+
"bot"
|
|
39
|
+
],
|
|
40
|
+
capabilityTags: [
|
|
41
|
+
"read-write",
|
|
42
|
+
"crud",
|
|
43
|
+
"search",
|
|
44
|
+
"auth:token",
|
|
45
|
+
"remote",
|
|
46
|
+
"http",
|
|
47
|
+
"real-time",
|
|
48
|
+
"rate-limited"
|
|
49
|
+
],
|
|
50
|
+
security: {
|
|
51
|
+
riskLevel: "external",
|
|
52
|
+
resourceAccess: ["internet"],
|
|
53
|
+
notes: ["Connects to Telegram Bot API — requires bot token"]
|
|
54
|
+
},
|
|
55
|
+
capabilities: { network: {
|
|
56
|
+
egress: true,
|
|
57
|
+
allowedDomains: ["api.telegram.org"]
|
|
58
|
+
} }
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
static treeSchema() {
|
|
62
|
+
return {
|
|
63
|
+
operations: [
|
|
64
|
+
"list",
|
|
65
|
+
"read",
|
|
66
|
+
"exec",
|
|
67
|
+
"stat",
|
|
68
|
+
"explain"
|
|
69
|
+
],
|
|
70
|
+
tree: {
|
|
71
|
+
"/": {
|
|
72
|
+
kind: "messaging:root",
|
|
73
|
+
operations: ["list", "exec"],
|
|
74
|
+
actions: [
|
|
75
|
+
"add-bot",
|
|
76
|
+
"remove-bot",
|
|
77
|
+
"start",
|
|
78
|
+
"stop",
|
|
79
|
+
"set-commands"
|
|
80
|
+
]
|
|
81
|
+
},
|
|
82
|
+
"/{bot}": {
|
|
83
|
+
kind: "messaging:bot",
|
|
84
|
+
operations: ["list", "read"]
|
|
85
|
+
},
|
|
86
|
+
"/{bot}/ctl": {
|
|
87
|
+
kind: "messaging:status",
|
|
88
|
+
operations: ["read"]
|
|
89
|
+
},
|
|
90
|
+
"/{bot}/conversations": {
|
|
91
|
+
kind: "messaging:conversations",
|
|
92
|
+
operations: ["list"]
|
|
93
|
+
},
|
|
94
|
+
"/{bot}/conversations/{convId}": {
|
|
95
|
+
kind: "messaging:conversation",
|
|
96
|
+
operations: ["list"]
|
|
97
|
+
},
|
|
98
|
+
"/{bot}/conversations/{convId}/messages": {
|
|
99
|
+
kind: "messaging:messages",
|
|
100
|
+
operations: ["list", "exec"],
|
|
101
|
+
actions: ["send"]
|
|
102
|
+
},
|
|
103
|
+
"/{bot}/conversations/{convId}/messages/{msgId}": {
|
|
104
|
+
kind: "messaging:message",
|
|
105
|
+
operations: ["read"]
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
auth: {
|
|
109
|
+
type: "token",
|
|
110
|
+
env: ["TELEGRAM_BOT_TOKEN"]
|
|
111
|
+
},
|
|
112
|
+
bestFor: [
|
|
113
|
+
"bot interactions",
|
|
114
|
+
"notifications",
|
|
115
|
+
"group messaging"
|
|
116
|
+
],
|
|
117
|
+
notFor: ["file storage", "database queries"]
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
providerName = "telegram";
|
|
121
|
+
eventPrefix = "telegram";
|
|
122
|
+
_pollStates = /* @__PURE__ */ new Map();
|
|
123
|
+
_autoStart;
|
|
124
|
+
constructor(options) {
|
|
125
|
+
let bots;
|
|
126
|
+
if (options.bots) {
|
|
127
|
+
bots = options.bots;
|
|
128
|
+
for (const bot of bots) if (!bot.token) throw new Error(`AFSTelegram bot "${bot.name}" requires a token`);
|
|
129
|
+
} else {
|
|
130
|
+
if (!options.token) throw new Error("AFSTelegram requires a token");
|
|
131
|
+
bots = [{
|
|
132
|
+
name: "default",
|
|
133
|
+
token: options.token,
|
|
134
|
+
conversations: options.chats ?? [],
|
|
135
|
+
apiBase: options.apiBase,
|
|
136
|
+
pollTimeout: options.pollTimeout
|
|
137
|
+
}];
|
|
138
|
+
}
|
|
139
|
+
super({
|
|
140
|
+
bots,
|
|
141
|
+
bufferSize: options.bufferSize
|
|
142
|
+
});
|
|
143
|
+
this._autoStart = options.autoStart === true || options.autoStart === "true";
|
|
144
|
+
for (const bot of bots) this._pollStates.set(bot.name, {
|
|
145
|
+
polling: false,
|
|
146
|
+
disposed: false,
|
|
147
|
+
abort: null,
|
|
148
|
+
backoff: 1e3,
|
|
149
|
+
offset: 0
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
getMessageCapabilities() {
|
|
153
|
+
return {
|
|
154
|
+
formats: {
|
|
155
|
+
send: [
|
|
156
|
+
"text",
|
|
157
|
+
"markdown",
|
|
158
|
+
"html"
|
|
159
|
+
],
|
|
160
|
+
receive: ["text"]
|
|
161
|
+
},
|
|
162
|
+
maxMessageLength: 4096,
|
|
163
|
+
features: {
|
|
164
|
+
edit: false,
|
|
165
|
+
delete: false,
|
|
166
|
+
reply: true,
|
|
167
|
+
thread: false,
|
|
168
|
+
reaction: false,
|
|
169
|
+
inlineKeyboard: true
|
|
170
|
+
},
|
|
171
|
+
limits: { messagesPerSecond: 30 }
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
createBotClient(config) {
|
|
175
|
+
return new require_client.TelegramClient({
|
|
176
|
+
token: config.token,
|
|
177
|
+
apiBase: config.apiBase,
|
|
178
|
+
pollTimeout: config.pollTimeout
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
async sendMessage(client, convId, text, opts) {
|
|
182
|
+
const result = await client.sendMessage(convId, text, {
|
|
183
|
+
parseMode: opts?.parseMode,
|
|
184
|
+
replyMarkup: opts?.replyMarkup
|
|
185
|
+
});
|
|
186
|
+
return { messageId: String(result.message_id) };
|
|
187
|
+
}
|
|
188
|
+
async sendTypingIndicator(client, convId) {
|
|
189
|
+
await client.sendChatAction(convId, "typing");
|
|
190
|
+
}
|
|
191
|
+
normalizeMessage(raw) {
|
|
192
|
+
const message = raw;
|
|
193
|
+
return {
|
|
194
|
+
id: String(message.message_id ?? "0"),
|
|
195
|
+
text: String(message.text ?? ""),
|
|
196
|
+
from: this.normalizeSender(message.from ?? {}),
|
|
197
|
+
timestamp: message.date ?? Math.floor(Date.now() / 1e3),
|
|
198
|
+
conversationId: String(message.chat?.id ?? ""),
|
|
199
|
+
platform: { message_id: message.message_id }
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
normalizeSender(raw) {
|
|
203
|
+
return {
|
|
204
|
+
id: String(raw.id ?? "0"),
|
|
205
|
+
name: String(raw.first_name ?? raw.name ?? ""),
|
|
206
|
+
isBot: raw.is_bot
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
setEventSink(sink) {
|
|
210
|
+
super.setEventSink(sink);
|
|
211
|
+
if (sink && this._autoStart) this.start();
|
|
212
|
+
}
|
|
213
|
+
start(botName) {
|
|
214
|
+
const names = botName ? [botName] : [...this._pollStates.keys()];
|
|
215
|
+
for (const name of names) {
|
|
216
|
+
const state = this._pollStates.get(name);
|
|
217
|
+
if (!state || state.polling || state.disposed) continue;
|
|
218
|
+
state.polling = true;
|
|
219
|
+
this._pollLoop(name);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
stop(botName) {
|
|
223
|
+
const names = botName ? [botName] : [...this._pollStates.keys()];
|
|
224
|
+
for (const name of names) {
|
|
225
|
+
const state = this._pollStates.get(name);
|
|
226
|
+
if (!state) continue;
|
|
227
|
+
state.polling = false;
|
|
228
|
+
if (state.abort) {
|
|
229
|
+
state.abort.abort();
|
|
230
|
+
state.abort = null;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
dispose() {
|
|
235
|
+
for (const [, state] of this._pollStates) {
|
|
236
|
+
state.polling = false;
|
|
237
|
+
state.disposed = true;
|
|
238
|
+
if (state.abort) {
|
|
239
|
+
state.abort.abort();
|
|
240
|
+
state.abort = null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
onBotAdded(name) {
|
|
245
|
+
if (!this._pollStates.has(name)) this._pollStates.set(name, {
|
|
246
|
+
polling: false,
|
|
247
|
+
disposed: false,
|
|
248
|
+
abort: null,
|
|
249
|
+
backoff: 1e3,
|
|
250
|
+
offset: 0
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
onBotRemoved(name) {
|
|
254
|
+
const state = this._pollStates.get(name);
|
|
255
|
+
if (state) {
|
|
256
|
+
state.polling = false;
|
|
257
|
+
state.disposed = true;
|
|
258
|
+
if (state.abort) {
|
|
259
|
+
state.abort.abort();
|
|
260
|
+
state.abort = null;
|
|
261
|
+
}
|
|
262
|
+
this._pollStates.delete(name);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
async listRootActions(_ctx) {
|
|
266
|
+
return { data: [
|
|
267
|
+
this.buildEntry("/.actions/add-bot", { meta: { description: "Add a bot instance at runtime" } }),
|
|
268
|
+
this.buildEntry("/.actions/remove-bot", { meta: { description: "Remove a bot instance" } }),
|
|
269
|
+
this.buildEntry("/.actions/start", { meta: { description: "Start long-polling for updates" } }),
|
|
270
|
+
this.buildEntry("/.actions/stop", { meta: { description: "Stop long-polling" } }),
|
|
271
|
+
this.buildEntry("/.actions/set-commands", { meta: { description: "Register bot commands in Telegram" } })
|
|
272
|
+
] };
|
|
273
|
+
}
|
|
274
|
+
async execStart(_ctx) {
|
|
275
|
+
this.start();
|
|
276
|
+
return {
|
|
277
|
+
success: true,
|
|
278
|
+
data: {
|
|
279
|
+
ok: true,
|
|
280
|
+
polling: true
|
|
281
|
+
}
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
async execStop(_ctx) {
|
|
285
|
+
this.stop();
|
|
286
|
+
return {
|
|
287
|
+
success: true,
|
|
288
|
+
data: {
|
|
289
|
+
ok: true,
|
|
290
|
+
polling: false
|
|
291
|
+
}
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
async execSetCommands(_ctx, args) {
|
|
295
|
+
const commands = args.commands;
|
|
296
|
+
const botName = args.botName ?? this._botOrder[0];
|
|
297
|
+
const client = this._getClient(botName);
|
|
298
|
+
if (!client) throw new Error(`Bot "${botName}" not found`);
|
|
299
|
+
await client.setCommands(commands);
|
|
300
|
+
return {
|
|
301
|
+
success: true,
|
|
302
|
+
data: { ok: true }
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
async _pollLoop(botName) {
|
|
306
|
+
const state = this._pollStates.get(botName);
|
|
307
|
+
const client = this._getClient(botName);
|
|
308
|
+
if (!state || !client) return;
|
|
309
|
+
while (state.polling && !state.disposed) try {
|
|
310
|
+
state.abort = new AbortController();
|
|
311
|
+
const updates = await client.poll(state.offset, state.abort.signal);
|
|
312
|
+
for (const update of updates) {
|
|
313
|
+
state.offset = update.update_id + 1;
|
|
314
|
+
this._processUpdate(botName, update);
|
|
315
|
+
}
|
|
316
|
+
state.backoff = 1e3;
|
|
317
|
+
} catch {
|
|
318
|
+
if (state.disposed) break;
|
|
319
|
+
await new Promise((r) => setTimeout(r, state.backoff));
|
|
320
|
+
state.backoff = Math.min(state.backoff * 2, 6e4);
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/** Process a Telegram update — delegates messages to emitMessageReceived(), emits platform events for callbacks/inline. */
|
|
324
|
+
_processUpdate(botName, update) {
|
|
325
|
+
if (update.callback_query) {
|
|
326
|
+
const cb = update.callback_query;
|
|
327
|
+
const chatId$1 = cb.message?.chat ? String(cb.message.chat.id) : "";
|
|
328
|
+
this.emit({
|
|
329
|
+
type: "telegram:callback",
|
|
330
|
+
path: chatId$1 ? `/${botName}/conversations/${chatId$1}` : "/",
|
|
331
|
+
data: {
|
|
332
|
+
botName,
|
|
333
|
+
chatId: chatId$1,
|
|
334
|
+
callbackId: cb.id,
|
|
335
|
+
data: cb.data ?? "",
|
|
336
|
+
from: {
|
|
337
|
+
id: cb.from.id,
|
|
338
|
+
name: cb.from.first_name ?? ""
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
if (update.inline_query) {
|
|
345
|
+
const iq = update.inline_query;
|
|
346
|
+
this.emit({
|
|
347
|
+
type: "telegram:inline",
|
|
348
|
+
path: "/",
|
|
349
|
+
data: {
|
|
350
|
+
botName,
|
|
351
|
+
queryId: iq.id,
|
|
352
|
+
query: iq.query,
|
|
353
|
+
from: {
|
|
354
|
+
id: iq.from.id,
|
|
355
|
+
name: iq.from.first_name ?? ""
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
});
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
const message = update.message;
|
|
362
|
+
if (!message?.text) return;
|
|
363
|
+
const chatId = String(message.chat.id);
|
|
364
|
+
const text = message.text.trim();
|
|
365
|
+
this.emitMessageReceived(botName, {
|
|
366
|
+
id: String(message.message_id),
|
|
367
|
+
text,
|
|
368
|
+
from: this.normalizeSender({
|
|
369
|
+
id: message.from?.id ?? 0,
|
|
370
|
+
first_name: message.from?.first_name ?? "",
|
|
371
|
+
is_bot: message.from?.is_bot
|
|
372
|
+
}),
|
|
373
|
+
timestamp: message.date,
|
|
374
|
+
conversationId: chatId,
|
|
375
|
+
platform: { message_id: message.message_id }
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
/** Add a conversation to a bot. Defaults to first bot. */
|
|
379
|
+
addChat(chatId, botName) {
|
|
380
|
+
const name = botName ?? this._botOrder[0];
|
|
381
|
+
if (!name) return;
|
|
382
|
+
const convs = this._botConversations.get(name);
|
|
383
|
+
if (!convs || convs.has(chatId)) return;
|
|
384
|
+
convs.add(chatId);
|
|
385
|
+
const buffers = this._botBuffers.get(name);
|
|
386
|
+
if (buffers && !buffers.has(chatId)) buffers.set(chatId, []);
|
|
387
|
+
}
|
|
388
|
+
/** Remove a conversation from a bot. */
|
|
389
|
+
removeChat(chatId, botName) {
|
|
390
|
+
const name = botName ?? this._botOrder[0];
|
|
391
|
+
if (!name) return;
|
|
392
|
+
const convs = this._botConversations.get(name);
|
|
393
|
+
if (convs) convs.delete(chatId);
|
|
394
|
+
const buffers = this._botBuffers.get(name);
|
|
395
|
+
if (buffers) buffers.delete(chatId);
|
|
396
|
+
}
|
|
397
|
+
/** Add a message to the ring buffer directly. Public for testing/conformance. */
|
|
398
|
+
_addToBuffer(chatId, msg) {
|
|
399
|
+
const botName = this._botOrder[0] ?? "default";
|
|
400
|
+
const convs = this._botConversations.get(botName);
|
|
401
|
+
if (convs && !convs.has(chatId)) convs.add(chatId);
|
|
402
|
+
let botBuffers = this._botBuffers.get(botName);
|
|
403
|
+
if (!botBuffers) {
|
|
404
|
+
botBuffers = /* @__PURE__ */ new Map();
|
|
405
|
+
this._botBuffers.set(botName, botBuffers);
|
|
406
|
+
}
|
|
407
|
+
let buffer = botBuffers.get(chatId);
|
|
408
|
+
if (!buffer) {
|
|
409
|
+
buffer = [];
|
|
410
|
+
botBuffers.set(chatId, buffer);
|
|
411
|
+
}
|
|
412
|
+
buffer.push({
|
|
413
|
+
id: String(msg.message_id),
|
|
414
|
+
text: msg.text,
|
|
415
|
+
from: {
|
|
416
|
+
id: String(msg.from.id),
|
|
417
|
+
name: msg.from.name
|
|
418
|
+
},
|
|
419
|
+
timestamp: msg.date,
|
|
420
|
+
conversationId: chatId,
|
|
421
|
+
platform: { message_id: msg.message_id }
|
|
422
|
+
});
|
|
423
|
+
while (buffer.length > this._bufferSize) buffer.shift();
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
require_decorate.__decorate([(0, _aigne_afs_provider.Actions)("/")], AFSTelegram.prototype, "listRootActions", null);
|
|
427
|
+
require_decorate.__decorate([_aigne_afs_provider.Actions.Exec("/", "start")], AFSTelegram.prototype, "execStart", null);
|
|
428
|
+
require_decorate.__decorate([_aigne_afs_provider.Actions.Exec("/", "stop")], AFSTelegram.prototype, "execStop", null);
|
|
429
|
+
require_decorate.__decorate([_aigne_afs_provider.Actions.Exec("/", "set-commands")], AFSTelegram.prototype, "execSetCommands", null);
|
|
430
|
+
|
|
431
|
+
//#endregion
|
|
432
|
+
exports.AFSTelegram = AFSTelegram;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { TelegramClient, TelegramUpdate } from "./client.cjs";
|
|
2
|
+
import * as _aigne_afs0 from "@aigne/afs";
|
|
3
|
+
import { AFSExecResult, AFSListResult, ProviderTreeSchema } from "@aigne/afs";
|
|
4
|
+
import { RouteContext } from "@aigne/afs/provider";
|
|
5
|
+
import { BaseMessageProvider, BotConfig, BufferedMessage, MessageCapabilities, MessageSender, SendOptions } from "@aigne/afs-messaging";
|
|
6
|
+
|
|
7
|
+
//#region src/index.d.ts
|
|
8
|
+
interface AFSTelegramOptions {
|
|
9
|
+
/** Multi-bot config */
|
|
10
|
+
bots?: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
token: string;
|
|
13
|
+
conversations?: string[];
|
|
14
|
+
apiBase?: string;
|
|
15
|
+
pollTimeout?: number;
|
|
16
|
+
}>;
|
|
17
|
+
/** Single-bot backward compat: token */
|
|
18
|
+
token?: string;
|
|
19
|
+
/** Single-bot backward compat: chat IDs */
|
|
20
|
+
chats?: string[];
|
|
21
|
+
apiBase?: string;
|
|
22
|
+
pollTimeout?: number;
|
|
23
|
+
bufferSize?: number;
|
|
24
|
+
/** Auto-start long-polling when provider is mounted (event sink set). Default: false */
|
|
25
|
+
autoStart?: boolean;
|
|
26
|
+
}
|
|
27
|
+
declare class AFSTelegram extends BaseMessageProvider {
|
|
28
|
+
static manifest(): {
|
|
29
|
+
name: string;
|
|
30
|
+
description: string;
|
|
31
|
+
uriTemplate: string;
|
|
32
|
+
category: string;
|
|
33
|
+
schema: {
|
|
34
|
+
type: string;
|
|
35
|
+
properties: {
|
|
36
|
+
token: {
|
|
37
|
+
type: string;
|
|
38
|
+
description: string;
|
|
39
|
+
sensitive: boolean;
|
|
40
|
+
};
|
|
41
|
+
chats: {
|
|
42
|
+
type: string;
|
|
43
|
+
items: {
|
|
44
|
+
type: string;
|
|
45
|
+
};
|
|
46
|
+
description: string;
|
|
47
|
+
};
|
|
48
|
+
autoStart: {
|
|
49
|
+
type: string;
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
required: string[];
|
|
54
|
+
};
|
|
55
|
+
tags: string[];
|
|
56
|
+
capabilityTags: string[];
|
|
57
|
+
security: {
|
|
58
|
+
riskLevel: string;
|
|
59
|
+
resourceAccess: string[];
|
|
60
|
+
notes: string[];
|
|
61
|
+
};
|
|
62
|
+
capabilities: {
|
|
63
|
+
network: {
|
|
64
|
+
egress: boolean;
|
|
65
|
+
allowedDomains: string[];
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
static treeSchema(): ProviderTreeSchema;
|
|
70
|
+
readonly providerName = "telegram";
|
|
71
|
+
readonly eventPrefix = "telegram";
|
|
72
|
+
private readonly _pollStates;
|
|
73
|
+
private readonly _autoStart;
|
|
74
|
+
constructor(options: AFSTelegramOptions);
|
|
75
|
+
getMessageCapabilities(): MessageCapabilities;
|
|
76
|
+
createBotClient(config: BotConfig): TelegramClient;
|
|
77
|
+
sendMessage(client: unknown, convId: string, text: string, opts?: SendOptions): Promise<{
|
|
78
|
+
messageId: string;
|
|
79
|
+
}>;
|
|
80
|
+
sendTypingIndicator(client: unknown, convId: string): Promise<void>;
|
|
81
|
+
normalizeMessage(raw: Record<string, unknown>): BufferedMessage;
|
|
82
|
+
normalizeSender(raw: Record<string, unknown>): MessageSender;
|
|
83
|
+
setEventSink(sink: _aigne_afs0.AFSEventSink | null): void;
|
|
84
|
+
start(botName?: string): void;
|
|
85
|
+
stop(botName?: string): void;
|
|
86
|
+
dispose(): void;
|
|
87
|
+
protected onBotAdded(name: string): void;
|
|
88
|
+
protected onBotRemoved(name: string): void;
|
|
89
|
+
listRootActions(_ctx: RouteContext): Promise<AFSListResult>;
|
|
90
|
+
execStart(_ctx: RouteContext): Promise<AFSExecResult>;
|
|
91
|
+
execStop(_ctx: RouteContext): Promise<AFSExecResult>;
|
|
92
|
+
execSetCommands(_ctx: RouteContext, args: Record<string, unknown>): Promise<AFSExecResult>;
|
|
93
|
+
private _pollLoop;
|
|
94
|
+
/** Process a Telegram update — delegates messages to emitMessageReceived(), emits platform events for callbacks/inline. */
|
|
95
|
+
_processUpdate(botName: string, update: TelegramUpdate): void;
|
|
96
|
+
/** Add a conversation to a bot. Defaults to first bot. */
|
|
97
|
+
addChat(chatId: string, botName?: string): void;
|
|
98
|
+
/** Remove a conversation from a bot. */
|
|
99
|
+
removeChat(chatId: string, botName?: string): void;
|
|
100
|
+
/** Add a message to the ring buffer directly. Public for testing/conformance. */
|
|
101
|
+
_addToBuffer(chatId: string, msg: {
|
|
102
|
+
message_id: number;
|
|
103
|
+
text: string;
|
|
104
|
+
from: {
|
|
105
|
+
id: number;
|
|
106
|
+
name: string;
|
|
107
|
+
};
|
|
108
|
+
date: number;
|
|
109
|
+
}): void;
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
export { AFSTelegram, AFSTelegramOptions, type TelegramClient, type TelegramUpdate };
|
|
113
|
+
//# sourceMappingURL=index.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;UAsCiB,kBAAA;EAsGM;EApGrB,IAAA,GAAO,KAAA;IACL,IAAA;IACA,KAAA;IACA,aAAA;IACA,OAAA;IACA,WAAA;EAAA;EAoL8C;EAjLhD,KAAA;EA6L+C;EA3L/C,KAAA;EACA,OAAA;EACA,WAAA;EACA,UAAA;EAiSsB;EA/RtB,SAAA;AAAA;AAAA,cAWW,WAAA,SAAoB,mBAAA;EAAA,OACxB,QAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAsCA,UAAA,CAAA,GAAc,kBAAA;EAAA,SA6BZ,YAAA;EAAA,SACA,WAAA;EAAA,iBAEQ,WAAA;EAAA,iBACA,UAAA;cAEL,OAAA,EAAS,kBAAA;EAqCrB,sBAAA,CAAA,GAA0B,mBAAA;EAqB1B,eAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,cAAA;EAQ9B,WAAA,CACJ,MAAA,WACA,MAAA,UACA,IAAA,UACA,IAAA,GAAO,WAAA,GACN,OAAA;IAAU,SAAA;EAAA;EASP,mBAAA,CAAoB,MAAA,WAAiB,MAAA,WAAiB,OAAA;EAK5D,gBAAA,CAAiB,GAAA,EAAK,MAAA,oBAA0B,eAAA;EAYhD,eAAA,CAAgB,GAAA,EAAK,MAAA,oBAA0B,aAAA;EAUtC,YAAA,CAAa,IAAA,EAVsC,WAAA,CAUX,YAAA;EAUjD,KAAA,CAAM,OAAA;EAUN,IAAA,CAAK,OAAA;EAaL,OAAA,CAAA;EAAA,UAWU,UAAA,CAAW,IAAA;EAAA,UAYX,YAAA,CAAa,IAAA;EAgBjB,eAAA,CAAgB,IAAA,EAAM,YAAA,GAAe,OAAA,CAAQ,aAAA;EAuB7C,SAAA,CAAU,IAAA,EAAM,YAAA,GAAe,OAAA,CAAQ,aAAA;EAMvC,QAAA,CAAS,IAAA,EAAM,YAAA,GAAe,OAAA,CAAQ,aAAA;EAMtC,eAAA,CAAgB,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,MAAA,oBAA0B,OAAA,CAAQ,aAAA;EAAA,QAWpE,SAAA;EAjJY;EA4K1B,cAAA,CAAe,OAAA,UAAiB,MAAA,EAAQ,cAAA;EA5KoB;EAoO5D,OAAA,CAAQ,MAAA,UAAgB,OAAA;EA/NF;EA4OtB,UAAA,CAAW,MAAA,UAAgB,OAAA;EA5OqB;EAsPhD,YAAA,CACE,MAAA,UACA,GAAA;IAAO,UAAA;IAAoB,IAAA;IAAc,IAAA;MAAQ,EAAA;MAAY,IAAA;IAAA;IAAgB,IAAA;EAAA;AAAA"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { TelegramClient, TelegramUpdate } from "./client.mjs";
|
|
2
|
+
import { RouteContext } from "@aigne/afs/provider";
|
|
3
|
+
import { BaseMessageProvider, BotConfig, BufferedMessage, MessageCapabilities, MessageSender, SendOptions } from "@aigne/afs-messaging";
|
|
4
|
+
import * as _aigne_afs0 from "@aigne/afs";
|
|
5
|
+
import { AFSExecResult, AFSListResult, ProviderTreeSchema } from "@aigne/afs";
|
|
6
|
+
|
|
7
|
+
//#region src/index.d.ts
|
|
8
|
+
interface AFSTelegramOptions {
|
|
9
|
+
/** Multi-bot config */
|
|
10
|
+
bots?: Array<{
|
|
11
|
+
name: string;
|
|
12
|
+
token: string;
|
|
13
|
+
conversations?: string[];
|
|
14
|
+
apiBase?: string;
|
|
15
|
+
pollTimeout?: number;
|
|
16
|
+
}>;
|
|
17
|
+
/** Single-bot backward compat: token */
|
|
18
|
+
token?: string;
|
|
19
|
+
/** Single-bot backward compat: chat IDs */
|
|
20
|
+
chats?: string[];
|
|
21
|
+
apiBase?: string;
|
|
22
|
+
pollTimeout?: number;
|
|
23
|
+
bufferSize?: number;
|
|
24
|
+
/** Auto-start long-polling when provider is mounted (event sink set). Default: false */
|
|
25
|
+
autoStart?: boolean;
|
|
26
|
+
}
|
|
27
|
+
declare class AFSTelegram extends BaseMessageProvider {
|
|
28
|
+
static manifest(): {
|
|
29
|
+
name: string;
|
|
30
|
+
description: string;
|
|
31
|
+
uriTemplate: string;
|
|
32
|
+
category: string;
|
|
33
|
+
schema: {
|
|
34
|
+
type: string;
|
|
35
|
+
properties: {
|
|
36
|
+
token: {
|
|
37
|
+
type: string;
|
|
38
|
+
description: string;
|
|
39
|
+
sensitive: boolean;
|
|
40
|
+
};
|
|
41
|
+
chats: {
|
|
42
|
+
type: string;
|
|
43
|
+
items: {
|
|
44
|
+
type: string;
|
|
45
|
+
};
|
|
46
|
+
description: string;
|
|
47
|
+
};
|
|
48
|
+
autoStart: {
|
|
49
|
+
type: string;
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
required: string[];
|
|
54
|
+
};
|
|
55
|
+
tags: string[];
|
|
56
|
+
capabilityTags: string[];
|
|
57
|
+
security: {
|
|
58
|
+
riskLevel: string;
|
|
59
|
+
resourceAccess: string[];
|
|
60
|
+
notes: string[];
|
|
61
|
+
};
|
|
62
|
+
capabilities: {
|
|
63
|
+
network: {
|
|
64
|
+
egress: boolean;
|
|
65
|
+
allowedDomains: string[];
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
};
|
|
69
|
+
static treeSchema(): ProviderTreeSchema;
|
|
70
|
+
readonly providerName = "telegram";
|
|
71
|
+
readonly eventPrefix = "telegram";
|
|
72
|
+
private readonly _pollStates;
|
|
73
|
+
private readonly _autoStart;
|
|
74
|
+
constructor(options: AFSTelegramOptions);
|
|
75
|
+
getMessageCapabilities(): MessageCapabilities;
|
|
76
|
+
createBotClient(config: BotConfig): TelegramClient;
|
|
77
|
+
sendMessage(client: unknown, convId: string, text: string, opts?: SendOptions): Promise<{
|
|
78
|
+
messageId: string;
|
|
79
|
+
}>;
|
|
80
|
+
sendTypingIndicator(client: unknown, convId: string): Promise<void>;
|
|
81
|
+
normalizeMessage(raw: Record<string, unknown>): BufferedMessage;
|
|
82
|
+
normalizeSender(raw: Record<string, unknown>): MessageSender;
|
|
83
|
+
setEventSink(sink: _aigne_afs0.AFSEventSink | null): void;
|
|
84
|
+
start(botName?: string): void;
|
|
85
|
+
stop(botName?: string): void;
|
|
86
|
+
dispose(): void;
|
|
87
|
+
protected onBotAdded(name: string): void;
|
|
88
|
+
protected onBotRemoved(name: string): void;
|
|
89
|
+
listRootActions(_ctx: RouteContext): Promise<AFSListResult>;
|
|
90
|
+
execStart(_ctx: RouteContext): Promise<AFSExecResult>;
|
|
91
|
+
execStop(_ctx: RouteContext): Promise<AFSExecResult>;
|
|
92
|
+
execSetCommands(_ctx: RouteContext, args: Record<string, unknown>): Promise<AFSExecResult>;
|
|
93
|
+
private _pollLoop;
|
|
94
|
+
/** Process a Telegram update — delegates messages to emitMessageReceived(), emits platform events for callbacks/inline. */
|
|
95
|
+
_processUpdate(botName: string, update: TelegramUpdate): void;
|
|
96
|
+
/** Add a conversation to a bot. Defaults to first bot. */
|
|
97
|
+
addChat(chatId: string, botName?: string): void;
|
|
98
|
+
/** Remove a conversation from a bot. */
|
|
99
|
+
removeChat(chatId: string, botName?: string): void;
|
|
100
|
+
/** Add a message to the ring buffer directly. Public for testing/conformance. */
|
|
101
|
+
_addToBuffer(chatId: string, msg: {
|
|
102
|
+
message_id: number;
|
|
103
|
+
text: string;
|
|
104
|
+
from: {
|
|
105
|
+
id: number;
|
|
106
|
+
name: string;
|
|
107
|
+
};
|
|
108
|
+
date: number;
|
|
109
|
+
}): void;
|
|
110
|
+
}
|
|
111
|
+
//#endregion
|
|
112
|
+
export { AFSTelegram, AFSTelegramOptions, type TelegramClient, type TelegramUpdate };
|
|
113
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":";;;;;;;UAsCiB,kBAAA;EAsGM;EApGrB,IAAA,GAAO,KAAA;IACL,IAAA;IACA,KAAA;IACA,aAAA;IACA,OAAA;IACA,WAAA;EAAA;EAoL8C;EAjLhD,KAAA;EA6L+C;EA3L/C,KAAA;EACA,OAAA;EACA,WAAA;EACA,UAAA;EAiSsB;EA/RtB,SAAA;AAAA;AAAA,cAWW,WAAA,SAAoB,mBAAA;EAAA,OACxB,QAAA,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SAsCA,UAAA,CAAA,GAAc,kBAAA;EAAA,SA6BZ,YAAA;EAAA,SACA,WAAA;EAAA,iBAEQ,WAAA;EAAA,iBACA,UAAA;cAEL,OAAA,EAAS,kBAAA;EAqCrB,sBAAA,CAAA,GAA0B,mBAAA;EAqB1B,eAAA,CAAgB,MAAA,EAAQ,SAAA,GAAY,cAAA;EAQ9B,WAAA,CACJ,MAAA,WACA,MAAA,UACA,IAAA,UACA,IAAA,GAAO,WAAA,GACN,OAAA;IAAU,SAAA;EAAA;EASP,mBAAA,CAAoB,MAAA,WAAiB,MAAA,WAAiB,OAAA;EAK5D,gBAAA,CAAiB,GAAA,EAAK,MAAA,oBAA0B,eAAA;EAYhD,eAAA,CAAgB,GAAA,EAAK,MAAA,oBAA0B,aAAA;EAUtC,YAAA,CAAa,IAAA,EAVsC,WAAA,CAUX,YAAA;EAUjD,KAAA,CAAM,OAAA;EAUN,IAAA,CAAK,OAAA;EAaL,OAAA,CAAA;EAAA,UAWU,UAAA,CAAW,IAAA;EAAA,UAYX,YAAA,CAAa,IAAA;EAgBjB,eAAA,CAAgB,IAAA,EAAM,YAAA,GAAe,OAAA,CAAQ,aAAA;EAuB7C,SAAA,CAAU,IAAA,EAAM,YAAA,GAAe,OAAA,CAAQ,aAAA;EAMvC,QAAA,CAAS,IAAA,EAAM,YAAA,GAAe,OAAA,CAAQ,aAAA;EAMtC,eAAA,CAAgB,IAAA,EAAM,YAAA,EAAc,IAAA,EAAM,MAAA,oBAA0B,OAAA,CAAQ,aAAA;EAAA,QAWpE,SAAA;EAjJY;EA4K1B,cAAA,CAAe,OAAA,UAAiB,MAAA,EAAQ,cAAA;EA5KoB;EAoO5D,OAAA,CAAQ,MAAA,UAAgB,OAAA;EA/NF;EA4OtB,UAAA,CAAW,MAAA,UAAgB,OAAA;EA5OqB;EAsPhD,YAAA,CACE,MAAA,UACA,GAAA;IAAO,UAAA;IAAoB,IAAA;IAAc,IAAA;MAAQ,EAAA;MAAY,IAAA;IAAA;IAAgB,IAAA;EAAA;AAAA"}
|