@zhin.js/adapter-telegram 1.0.68 → 1.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.
Files changed (78) hide show
  1. package/CHANGELOG.md +825 -16
  2. package/README.md +106 -77
  3. package/adapters/telegram.js +34 -0
  4. package/adapters/telegram.ts +39 -0
  5. package/agent/PERMITS.md +24 -0
  6. package/agent/tools/create_invite.ts +18 -0
  7. package/agent/tools/list_admins.ts +24 -0
  8. package/agent/tools/member_count.ts +16 -0
  9. package/agent/tools/pin_message.ts +19 -0
  10. package/agent/tools/react.ts +18 -0
  11. package/agent/tools/send_poll.ts +32 -0
  12. package/agent/tools/send_sticker.ts +17 -0
  13. package/agent/tools/set_description.ts +17 -0
  14. package/agent/tools/set_permissions.ts +31 -0
  15. package/agent/tools/unpin_message.ts +19 -0
  16. package/commands/endpoint/add/[id].js +3 -0
  17. package/commands/endpoint/add/[id].ts +3 -0
  18. package/commands/endpoint/list.js +3 -0
  19. package/commands/endpoint/list.ts +3 -0
  20. package/commands/endpoint/remove/[id].js +3 -0
  21. package/commands/endpoint/remove/[id].ts +3 -0
  22. package/lib/client.d.ts +12 -0
  23. package/lib/client.js +2 -0
  24. package/lib/endpoint.d.ts +112 -0
  25. package/lib/endpoint.js +535 -0
  26. package/lib/index.d.ts +4 -18
  27. package/lib/index.js +4 -455
  28. package/lib/markdown-to-html.d.ts +9 -0
  29. package/lib/markdown-to-html.js +75 -0
  30. package/lib/platform-permit.d.ts +17 -0
  31. package/lib/platform-permit.js +51 -0
  32. package/lib/polling.d.ts +9 -0
  33. package/lib/polling.js +57 -0
  34. package/lib/protocol.d.ts +299 -0
  35. package/lib/protocol.js +474 -0
  36. package/lib/telegram-endpoint-commands.d.ts +1 -0
  37. package/lib/telegram-endpoint-commands.js +16 -0
  38. package/lib/telegram-runtime-state.d.ts +1 -0
  39. package/lib/telegram-runtime-state.js +6 -0
  40. package/lib/webhook.d.ts +12 -0
  41. package/lib/webhook.js +55 -0
  42. package/package.json +59 -28
  43. package/plugin.js +19 -0
  44. package/schema.json +110 -0
  45. package/src/client.ts +16 -0
  46. package/src/endpoint.ts +679 -0
  47. package/src/index.ts +39 -426
  48. package/src/markdown-to-html.ts +86 -0
  49. package/src/platform-permit.ts +65 -0
  50. package/src/polling.ts +76 -0
  51. package/src/protocol.ts +767 -0
  52. package/src/telegram-endpoint-commands.ts +17 -0
  53. package/src/telegram-runtime-state.ts +7 -0
  54. package/src/webhook.ts +75 -0
  55. package/client/Dashboard.tsx +0 -295
  56. package/client/index.tsx +0 -11
  57. package/client/tsconfig.json +0 -7
  58. package/client/utils/api.ts +0 -17
  59. package/dist/index.js +0 -32
  60. package/lib/adapter.d.ts +0 -18
  61. package/lib/adapter.d.ts.map +0 -1
  62. package/lib/adapter.js +0 -55
  63. package/lib/adapter.js.map +0 -1
  64. package/lib/bot.d.ts +0 -140
  65. package/lib/bot.d.ts.map +0 -1
  66. package/lib/bot.js +0 -866
  67. package/lib/bot.js.map +0 -1
  68. package/lib/index.d.ts.map +0 -1
  69. package/lib/index.js.map +0 -1
  70. package/lib/types.d.ts +0 -29
  71. package/lib/types.d.ts.map +0 -1
  72. package/lib/types.js +0 -2
  73. package/lib/types.js.map +0 -1
  74. package/plugin.yml +0 -3
  75. package/src/adapter.ts +0 -64
  76. package/src/bot.ts +0 -983
  77. package/src/types.ts +0 -32
  78. /package/{skills/telegram/SKILL.md → agent/skills/telegram.md} +0 -0
package/lib/bot.js DELETED
@@ -1,866 +0,0 @@
1
- /**
2
- * Telegram Bot 实现
3
- */
4
- import { Telegraf } from "telegraf";
5
- import { Message, segment, } from "zhin.js";
6
- export class TelegramBot extends Telegraf {
7
- adapter;
8
- $config;
9
- $connected = false;
10
- get pluginLogger() {
11
- return this.adapter.plugin.logger;
12
- }
13
- get $id() {
14
- return this.$config.name;
15
- }
16
- constructor(adapter, $config) {
17
- super($config.token);
18
- this.adapter = adapter;
19
- this.$config = $config;
20
- }
21
- async $connect() {
22
- try {
23
- // Set up message handler
24
- this.on("message", async (ctx) => {
25
- await this.handleTelegramMessage(ctx);
26
- });
27
- // Set up callback query handler (for inline buttons)
28
- this.on("callback_query", async (ctx) => {
29
- // Handle callback queries as special messages
30
- if (ctx.callbackQuery && "data" in ctx.callbackQuery) {
31
- const message = this.$formatCallbackQuery(ctx);
32
- this.adapter.emit("message.receive", message);
33
- this.pluginLogger.debug(`${this.$config.name} recv callback ${message.$channel.type}(${message.$channel.id}): ${segment.raw(message.$content)}`);
34
- }
35
- });
36
- // Start bot with polling or webhook
37
- if (this.$config.polling !== false) {
38
- // Use polling by default
39
- await this.launch({
40
- allowedUpdates: this.$config.allowedUpdates,
41
- });
42
- }
43
- else if (this.$config.webhook) {
44
- // Use webhook
45
- const { domain, path = "/telegram-webhook", port } = this.$config.webhook;
46
- await this.launch({
47
- webhook: {
48
- domain,
49
- port,
50
- hookPath: path,
51
- },
52
- allowedUpdates: this.$config.allowedUpdates,
53
- });
54
- }
55
- else {
56
- throw new Error("Either polling must be enabled or webhook configuration must be provided");
57
- }
58
- this.$connected = true;
59
- const me = await this.telegram.getMe();
60
- this.pluginLogger.info(`Telegram bot ${this.$config.name} connected successfully as @${me.username}`);
61
- }
62
- catch (error) {
63
- this.pluginLogger.error("Failed to connect Telegram bot:", error);
64
- this.$connected = false;
65
- throw error;
66
- }
67
- }
68
- async $disconnect() {
69
- try {
70
- this.removeAllListeners();
71
- await this.stop();
72
- this.$connected = false;
73
- this.pluginLogger.info(`Telegram bot ${this.$config.name} disconnected`);
74
- }
75
- catch (error) {
76
- this.pluginLogger.error("Error disconnecting Telegram bot:", error);
77
- throw error;
78
- }
79
- }
80
- async handleTelegramMessage(ctx) {
81
- if (!ctx.message)
82
- return;
83
- const message = this.$formatMessage(ctx.message);
84
- this.adapter.emit("message.receive", message);
85
- this.pluginLogger.debug(`${this.$config.name} recv ${message.$channel.type}(${message.$channel.id}): ${segment.raw(message.$content)}`);
86
- }
87
- $formatMessage(msg) {
88
- // Determine channel type
89
- const channelType = msg.chat.type === "private" ? "private" : "group";
90
- const channelId = msg.chat.id.toString();
91
- // Parse message content
92
- const content = this.parseMessageContent(msg);
93
- const result = Message.from(msg, {
94
- $id: msg.message_id.toString(),
95
- $adapter: "telegram",
96
- $bot: this.$config.name,
97
- $sender: {
98
- id: msg.from?.id.toString() || "",
99
- name: msg.from?.username || msg.from?.first_name || "Unknown",
100
- },
101
- $channel: {
102
- id: channelId,
103
- type: channelType,
104
- },
105
- $content: content,
106
- $raw: "text" in msg ? msg.text || "" : "",
107
- $timestamp: msg.date * 1000,
108
- $recall: async () => {
109
- try {
110
- await this.telegram.deleteMessage(parseInt(channelId), parseInt(result.$id));
111
- }
112
- catch (error) {
113
- this.pluginLogger.error("Error recalling Telegram message:", error);
114
- throw error;
115
- }
116
- },
117
- $reply: async (content, quote) => {
118
- if (!Array.isArray(content))
119
- content = [content];
120
- // Handle reply
121
- if (quote) {
122
- const replyToMessageId = typeof quote === "boolean" ? result.$id : quote;
123
- content.unshift({ type: "reply", data: { id: replyToMessageId } });
124
- }
125
- return await this.adapter.sendMessage({
126
- context: "telegram",
127
- bot: this.$config.name,
128
- id: channelId,
129
- type: channelType,
130
- content: content,
131
- });
132
- },
133
- });
134
- return result;
135
- }
136
- $formatCallbackQuery(ctx) {
137
- if (!ctx.callbackQuery || !("data" in ctx.callbackQuery)) {
138
- throw new Error("Invalid callback query");
139
- }
140
- const query = ctx.callbackQuery;
141
- const msg = query.message;
142
- const channelType = msg && "chat" in msg && msg.chat.type === "private" ? "private" : "group";
143
- const channelId = msg && "chat" in msg ? msg.chat.id.toString() : query.from.id.toString();
144
- const result = Message.from(query, {
145
- $id: query.id,
146
- $adapter: "telegram",
147
- $bot: this.$config.name,
148
- $sender: {
149
- id: query.from.id.toString(),
150
- name: query.from.username || query.from.first_name,
151
- },
152
- $channel: {
153
- id: channelId,
154
- type: channelType,
155
- },
156
- $content: [{ type: "text", data: { text: query.data } }],
157
- $raw: query.data,
158
- $timestamp: Date.now(),
159
- $recall: async () => {
160
- // Callback queries cannot be recalled
161
- },
162
- $reply: async (content) => {
163
- if (!Array.isArray(content))
164
- content = [content];
165
- const sentMsg = await this.sendContentToChat(parseInt(channelId), content);
166
- return sentMsg.message_id.toString();
167
- },
168
- });
169
- return result;
170
- }
171
- parseMessageContent(msg) {
172
- const segments = [];
173
- // Handle text messages
174
- if ("text" in msg && msg.text) {
175
- // Check for reply
176
- if (msg.reply_to_message) {
177
- segments.push({
178
- type: "reply",
179
- data: {
180
- id: msg.reply_to_message.message_id.toString(),
181
- },
182
- });
183
- }
184
- // Parse text with entities
185
- if (msg.entities && msg.entities.length > 0) {
186
- segments.push(...this.parseTextWithEntities(msg.text, msg.entities));
187
- }
188
- else {
189
- segments.push({ type: "text", data: { text: msg.text } });
190
- }
191
- }
192
- // Handle photo
193
- if ("photo" in msg && msg.photo) {
194
- const largestPhoto = msg.photo[msg.photo.length - 1];
195
- segments.push({
196
- type: "image",
197
- data: {
198
- file_id: largestPhoto.file_id,
199
- file_unique_id: largestPhoto.file_unique_id,
200
- width: largestPhoto.width,
201
- height: largestPhoto.height,
202
- file_size: largestPhoto.file_size,
203
- },
204
- });
205
- if (msg.caption) {
206
- segments.push({ type: "text", data: { text: msg.caption } });
207
- }
208
- }
209
- // Handle video
210
- if ("video" in msg && msg.video) {
211
- segments.push({
212
- type: "video",
213
- data: {
214
- file_id: msg.video.file_id,
215
- file_unique_id: msg.video.file_unique_id,
216
- width: msg.video.width,
217
- height: msg.video.height,
218
- duration: msg.video.duration,
219
- file_size: msg.video.file_size,
220
- },
221
- });
222
- if (msg.caption) {
223
- segments.push({ type: "text", data: { text: msg.caption } });
224
- }
225
- }
226
- // Handle audio
227
- if ("audio" in msg && msg.audio) {
228
- segments.push({
229
- type: "audio",
230
- data: {
231
- file_id: msg.audio.file_id,
232
- file_unique_id: msg.audio.file_unique_id,
233
- duration: msg.audio.duration,
234
- performer: msg.audio.performer,
235
- title: msg.audio.title,
236
- file_size: msg.audio.file_size,
237
- },
238
- });
239
- }
240
- // Handle voice
241
- if ("voice" in msg && msg.voice) {
242
- segments.push({
243
- type: "voice",
244
- data: {
245
- file_id: msg.voice.file_id,
246
- file_unique_id: msg.voice.file_unique_id,
247
- duration: msg.voice.duration,
248
- file_size: msg.voice.file_size,
249
- },
250
- });
251
- }
252
- // Handle document
253
- if ("document" in msg && msg.document) {
254
- segments.push({
255
- type: "file",
256
- data: {
257
- file_id: msg.document.file_id,
258
- file_unique_id: msg.document.file_unique_id,
259
- file_name: msg.document.file_name,
260
- mime_type: msg.document.mime_type,
261
- file_size: msg.document.file_size,
262
- },
263
- });
264
- }
265
- // Handle sticker
266
- if ("sticker" in msg && msg.sticker) {
267
- segments.push({
268
- type: "sticker",
269
- data: {
270
- file_id: msg.sticker.file_id,
271
- file_unique_id: msg.sticker.file_unique_id,
272
- width: msg.sticker.width,
273
- height: msg.sticker.height,
274
- is_animated: msg.sticker.is_animated,
275
- is_video: msg.sticker.is_video,
276
- emoji: msg.sticker.emoji,
277
- },
278
- });
279
- }
280
- // Handle location
281
- if ("location" in msg && msg.location) {
282
- segments.push({
283
- type: "location",
284
- data: {
285
- longitude: msg.location.longitude,
286
- latitude: msg.location.latitude,
287
- },
288
- });
289
- }
290
- return segments.length > 0
291
- ? segments
292
- : [{ type: "text", data: { text: "" } }];
293
- }
294
- parseTextWithEntities(text, entities) {
295
- const segments = [];
296
- let lastOffset = 0;
297
- for (const entity of entities) {
298
- // Add text before entity
299
- if (entity.offset > lastOffset) {
300
- const beforeText = text.slice(lastOffset, entity.offset);
301
- if (beforeText) {
302
- segments.push({ type: "text", data: { text: beforeText } });
303
- }
304
- }
305
- const entityText = text.slice(entity.offset, entity.offset + entity.length);
306
- switch (entity.type) {
307
- case "mention":
308
- case "text_mention":
309
- segments.push({
310
- type: "at",
311
- data: {
312
- id: ("user" in entity && entity.user?.id.toString()) || entityText.slice(1),
313
- name: ("user" in entity && entity.user?.username) || entityText,
314
- text: entityText,
315
- },
316
- });
317
- break;
318
- case "url":
319
- case "text_link":
320
- segments.push({
321
- type: "link",
322
- data: {
323
- url: ("url" in entity && entity.url) || entityText,
324
- text: entityText,
325
- },
326
- });
327
- break;
328
- case "hashtag":
329
- segments.push({
330
- type: "text",
331
- data: { text: entityText },
332
- });
333
- break;
334
- case "bold":
335
- case "italic":
336
- case "code":
337
- case "pre":
338
- case "underline":
339
- case "strikethrough":
340
- segments.push({
341
- type: "text",
342
- data: { text: entityText, format: entity.type },
343
- });
344
- break;
345
- default:
346
- segments.push({ type: "text", data: { text: entityText } });
347
- }
348
- lastOffset = entity.offset + entity.length;
349
- }
350
- // Add remaining text
351
- if (lastOffset < text.length) {
352
- const remainingText = text.slice(lastOffset);
353
- if (remainingText) {
354
- segments.push({ type: "text", data: { text: remainingText } });
355
- }
356
- }
357
- return segments;
358
- }
359
- async $sendMessage(options) {
360
- try {
361
- const chatId = parseInt(options.id);
362
- const result = await this.sendContentToChat(chatId, options.content);
363
- this.pluginLogger.debug(`${this.$config.name} send ${options.type}(${options.id}): ${segment.raw(options.content)}`);
364
- return result.message_id.toString();
365
- }
366
- catch (error) {
367
- this.pluginLogger.error("Failed to send Telegram message:", error);
368
- throw error;
369
- }
370
- }
371
- async sendContentToChat(chatId, content, extraOptions = {}) {
372
- if (!Array.isArray(content))
373
- content = [content];
374
- let textContent = "";
375
- let hasMedia = false;
376
- for (const segment of content) {
377
- if (typeof segment === "string") {
378
- textContent += segment;
379
- continue;
380
- }
381
- const { type, data } = segment;
382
- switch (type) {
383
- case "text":
384
- textContent += data.text || "";
385
- break;
386
- case "at":
387
- if (data.id) {
388
- textContent += `@${data.name || data.id}`;
389
- }
390
- break;
391
- case "image":
392
- hasMedia = true;
393
- if (data.file_id) {
394
- // Send by file_id
395
- return await this.telegram.sendPhoto(chatId, data.file_id, {
396
- caption: textContent || undefined,
397
- ...extraOptions,
398
- });
399
- }
400
- else if (data.url) {
401
- // Send by URL
402
- return await this.telegram.sendPhoto(chatId, data.url, {
403
- caption: textContent || undefined,
404
- ...extraOptions,
405
- });
406
- }
407
- else if (data.file) {
408
- // Send by file path
409
- return await this.telegram.sendPhoto(chatId, { source: data.file }, {
410
- caption: textContent || undefined,
411
- ...extraOptions,
412
- });
413
- }
414
- break;
415
- case "video":
416
- hasMedia = true;
417
- if (data.file_id) {
418
- return await this.telegram.sendVideo(chatId, data.file_id, {
419
- caption: textContent || undefined,
420
- ...extraOptions,
421
- });
422
- }
423
- else if (data.url) {
424
- return await this.telegram.sendVideo(chatId, data.url, {
425
- caption: textContent || undefined,
426
- ...extraOptions,
427
- });
428
- }
429
- else if (data.file) {
430
- return await this.telegram.sendVideo(chatId, { source: data.file }, {
431
- caption: textContent || undefined,
432
- ...extraOptions,
433
- });
434
- }
435
- break;
436
- case "audio":
437
- hasMedia = true;
438
- if (data.file_id) {
439
- return await this.telegram.sendAudio(chatId, data.file_id, {
440
- caption: textContent || undefined,
441
- ...extraOptions,
442
- });
443
- }
444
- else if (data.url) {
445
- return await this.telegram.sendAudio(chatId, data.url, {
446
- caption: textContent || undefined,
447
- ...extraOptions,
448
- });
449
- }
450
- else if (data.file) {
451
- return await this.telegram.sendAudio(chatId, { source: data.file }, {
452
- caption: textContent || undefined,
453
- ...extraOptions,
454
- });
455
- }
456
- break;
457
- case "voice":
458
- hasMedia = true;
459
- if (data.file_id) {
460
- return await this.telegram.sendVoice(chatId, data.file_id, {
461
- caption: textContent || undefined,
462
- ...extraOptions,
463
- });
464
- }
465
- else if (data.url) {
466
- return await this.telegram.sendVoice(chatId, data.url, {
467
- caption: textContent || undefined,
468
- ...extraOptions,
469
- });
470
- }
471
- else if (data.file) {
472
- return await this.telegram.sendVoice(chatId, { source: data.file }, {
473
- caption: textContent || undefined,
474
- ...extraOptions,
475
- });
476
- }
477
- break;
478
- case "file":
479
- hasMedia = true;
480
- if (data.file_id) {
481
- return await this.telegram.sendDocument(chatId, data.file_id, {
482
- caption: textContent || undefined,
483
- ...extraOptions,
484
- });
485
- }
486
- else if (data.url) {
487
- return await this.telegram.sendDocument(chatId, data.url, {
488
- caption: textContent || undefined,
489
- ...extraOptions,
490
- });
491
- }
492
- else if (data.file) {
493
- return await this.telegram.sendDocument(chatId, { source: data.file }, {
494
- caption: textContent || undefined,
495
- ...extraOptions,
496
- });
497
- }
498
- break;
499
- case "sticker":
500
- if (data.file_id) {
501
- hasMedia = true;
502
- return await this.telegram.sendSticker(chatId, data.file_id, extraOptions);
503
- }
504
- break;
505
- case "location":
506
- return await this.telegram.sendLocation(chatId, data.latitude, data.longitude, extraOptions);
507
- case "reply":
508
- return await this.telegram.sendMessage(chatId, data.id, {
509
- reply_parameters: { message_id: parseInt(data.id) },
510
- ...extraOptions,
511
- });
512
- default:
513
- // Unknown segment type, add as text
514
- textContent += data.text || `[${type}]`;
515
- }
516
- }
517
- // If no media was sent, send as text message
518
- if (!hasMedia && textContent.trim()) {
519
- return await this.telegram.sendMessage(chatId, textContent.trim(), extraOptions);
520
- }
521
- // If neither media nor text was sent, this is an error
522
- throw new Error("TelegramBot.$sendMessage: No media or text content to send.");
523
- }
524
- async $recallMessage(id) {
525
- // Telegram requires both chat_id and message_id to delete a message
526
- // The Bot interface only provides message_id, making recall impossible
527
- // Users should use message.$recall() instead, which has the full context
528
- throw new Error("TelegramBot.$recallMessage: Message recall not supported without chat_id. " +
529
- "Use message.$recall() method instead, which contains the required context.");
530
- }
531
- // ==================== 群组管理 API ====================
532
- /**
533
- * 踢出用户
534
- * @param chatId 聊天 ID
535
- * @param userId 用户 ID
536
- * @param untilDate 封禁截止时间(Unix 时间戳),0 表示永久
537
- */
538
- async kickMember(chatId, userId, untilDate) {
539
- try {
540
- await this.telegram.banChatMember(chatId, userId, untilDate);
541
- this.pluginLogger.info(`Telegram Bot ${this.$id} 踢出用户 ${userId} 从聊天 ${chatId}`);
542
- return true;
543
- }
544
- catch (error) {
545
- this.pluginLogger.error(`Telegram Bot ${this.$id} 踢出用户失败:`, error);
546
- throw error;
547
- }
548
- }
549
- /**
550
- * 解除封禁
551
- * @param chatId 聊天 ID
552
- * @param userId 用户 ID
553
- */
554
- async unbanMember(chatId, userId) {
555
- try {
556
- await this.telegram.unbanChatMember(chatId, userId, { only_if_banned: true });
557
- this.pluginLogger.info(`Telegram Bot ${this.$id} 解除用户 ${userId} 的封禁(聊天 ${chatId})`);
558
- return true;
559
- }
560
- catch (error) {
561
- this.pluginLogger.error(`Telegram Bot ${this.$id} 解除封禁失败:`, error);
562
- throw error;
563
- }
564
- }
565
- /**
566
- * 限制用户权限(禁言等)
567
- * @param chatId 聊天 ID
568
- * @param userId 用户 ID
569
- * @param permissions 权限设置
570
- * @param untilDate 限制截止时间
571
- */
572
- async restrictMember(chatId, userId, permissions, untilDate) {
573
- try {
574
- await this.telegram.restrictChatMember(chatId, userId, {
575
- permissions,
576
- until_date: untilDate,
577
- });
578
- this.pluginLogger.info(`Telegram Bot ${this.$id} 限制用户 ${userId} 权限(聊天 ${chatId})`);
579
- return true;
580
- }
581
- catch (error) {
582
- this.pluginLogger.error(`Telegram Bot ${this.$id} 限制权限失败:`, error);
583
- throw error;
584
- }
585
- }
586
- /**
587
- * 禁言用户
588
- * @param chatId 聊天 ID
589
- * @param userId 用户 ID
590
- * @param duration 禁言时长(秒),0 表示解除禁言
591
- */
592
- async muteMember(chatId, userId, duration = 600) {
593
- try {
594
- if (duration === 0) {
595
- // 解除禁言 - 恢复发送消息权限
596
- await this.telegram.restrictChatMember(chatId, userId, {
597
- permissions: {
598
- can_send_messages: true,
599
- can_send_audios: true,
600
- can_send_documents: true,
601
- can_send_photos: true,
602
- can_send_videos: true,
603
- can_send_video_notes: true,
604
- can_send_voice_notes: true,
605
- can_send_polls: true,
606
- can_send_other_messages: true,
607
- can_add_web_page_previews: true,
608
- },
609
- });
610
- this.pluginLogger.info(`Telegram Bot ${this.$id} 解除用户 ${userId} 禁言(聊天 ${chatId})`);
611
- }
612
- else {
613
- const untilDate = Math.floor(Date.now() / 1000) + duration;
614
- await this.telegram.restrictChatMember(chatId, userId, {
615
- permissions: {
616
- can_send_messages: false,
617
- can_send_audios: false,
618
- can_send_documents: false,
619
- can_send_photos: false,
620
- can_send_videos: false,
621
- can_send_video_notes: false,
622
- can_send_voice_notes: false,
623
- can_send_polls: false,
624
- can_send_other_messages: false,
625
- can_add_web_page_previews: false,
626
- },
627
- until_date: untilDate,
628
- });
629
- this.pluginLogger.info(`Telegram Bot ${this.$id} 禁言用户 ${userId} ${duration}秒(聊天 ${chatId})`);
630
- }
631
- return true;
632
- }
633
- catch (error) {
634
- this.pluginLogger.error(`Telegram Bot ${this.$id} 禁言操作失败:`, error);
635
- throw error;
636
- }
637
- }
638
- /**
639
- * 提升/降级管理员
640
- * @param chatId 聊天 ID
641
- * @param userId 用户 ID
642
- * @param promote 是否提升为管理员
643
- */
644
- async setAdmin(chatId, userId, promote = true) {
645
- try {
646
- if (promote) {
647
- await this.telegram.promoteChatMember(chatId, userId, {
648
- can_manage_chat: true,
649
- can_delete_messages: true,
650
- can_manage_video_chats: true,
651
- can_restrict_members: true,
652
- can_promote_members: false,
653
- can_change_info: true,
654
- can_invite_users: true,
655
- can_pin_messages: true,
656
- });
657
- }
658
- else {
659
- await this.telegram.promoteChatMember(chatId, userId, {
660
- can_manage_chat: false,
661
- can_delete_messages: false,
662
- can_manage_video_chats: false,
663
- can_restrict_members: false,
664
- can_promote_members: false,
665
- can_change_info: false,
666
- can_invite_users: false,
667
- can_pin_messages: false,
668
- });
669
- }
670
- this.pluginLogger.info(`Telegram Bot ${this.$id} ${promote ? '提升' : '降级'}用户 ${userId} 为管理员(聊天 ${chatId})`);
671
- return true;
672
- }
673
- catch (error) {
674
- this.pluginLogger.error(`Telegram Bot ${this.$id} 设置管理员失败:`, error);
675
- throw error;
676
- }
677
- }
678
- /**
679
- * 设置聊天标题
680
- * @param chatId 聊天 ID
681
- * @param title 新标题
682
- */
683
- async setChatTitle(chatId, title) {
684
- try {
685
- await this.telegram.setChatTitle(chatId, title);
686
- this.pluginLogger.info(`Telegram Bot ${this.$id} 设置聊天 ${chatId} 标题为 "${title}"`);
687
- return true;
688
- }
689
- catch (error) {
690
- this.pluginLogger.error(`Telegram Bot ${this.$id} 设置标题失败:`, error);
691
- throw error;
692
- }
693
- }
694
- /**
695
- * 设置聊天描述
696
- * @param chatId 聊天 ID
697
- * @param description 新描述
698
- */
699
- async setChatDescription(chatId, description) {
700
- try {
701
- await this.telegram.setChatDescription(chatId, description);
702
- this.pluginLogger.info(`Telegram Bot ${this.$id} 设置聊天 ${chatId} 描述`);
703
- return true;
704
- }
705
- catch (error) {
706
- this.pluginLogger.error(`Telegram Bot ${this.$id} 设置描述失败:`, error);
707
- throw error;
708
- }
709
- }
710
- /**
711
- * 置顶消息
712
- * @param chatId 聊天 ID
713
- * @param messageId 消息 ID
714
- */
715
- async pinMessage(chatId, messageId) {
716
- try {
717
- await this.telegram.pinChatMessage(chatId, messageId);
718
- this.pluginLogger.info(`Telegram Bot ${this.$id} 置顶消息 ${messageId}(聊天 ${chatId})`);
719
- return true;
720
- }
721
- catch (error) {
722
- this.pluginLogger.error(`Telegram Bot ${this.$id} 置顶消息失败:`, error);
723
- throw error;
724
- }
725
- }
726
- /**
727
- * 取消置顶消息
728
- * @param chatId 聊天 ID
729
- * @param messageId 消息 ID(可选,不提供则取消所有置顶)
730
- */
731
- async unpinMessage(chatId, messageId) {
732
- try {
733
- if (messageId) {
734
- await this.telegram.unpinChatMessage(chatId, messageId);
735
- }
736
- else {
737
- await this.telegram.unpinAllChatMessages(chatId);
738
- }
739
- this.pluginLogger.info(`Telegram Bot ${this.$id} 取消置顶消息(聊天 ${chatId})`);
740
- return true;
741
- }
742
- catch (error) {
743
- this.pluginLogger.error(`Telegram Bot ${this.$id} 取消置顶失败:`, error);
744
- throw error;
745
- }
746
- }
747
- /**
748
- * 获取聊天信息
749
- * @param chatId 聊天 ID
750
- */
751
- async getChatInfo(chatId) {
752
- try {
753
- return await this.telegram.getChat(chatId);
754
- }
755
- catch (error) {
756
- this.pluginLogger.error(`Telegram Bot ${this.$id} 获取聊天信息失败:`, error);
757
- throw error;
758
- }
759
- }
760
- /**
761
- * 获取聊天成员
762
- * @param chatId 聊天 ID
763
- * @param userId 用户 ID
764
- */
765
- async getChatMember(chatId, userId) {
766
- try {
767
- return await this.telegram.getChatMember(chatId, userId);
768
- }
769
- catch (error) {
770
- this.pluginLogger.error(`Telegram Bot ${this.$id} 获取成员信息失败:`, error);
771
- throw error;
772
- }
773
- }
774
- /**
775
- * 获取管理员列表
776
- * @param chatId 聊天 ID
777
- */
778
- async getChatAdmins(chatId) {
779
- try {
780
- return await this.telegram.getChatAdministrators(chatId);
781
- }
782
- catch (error) {
783
- this.pluginLogger.error(`Telegram Bot ${this.$id} 获取管理员列表失败:`, error);
784
- throw error;
785
- }
786
- }
787
- /**
788
- * 获取聊天成员数量
789
- * @param chatId 聊天 ID
790
- */
791
- async getChatMemberCount(chatId) {
792
- try {
793
- return await this.telegram.getChatMembersCount(chatId);
794
- }
795
- catch (error) {
796
- this.pluginLogger.error(`Telegram Bot ${this.$id} 获取成员数量失败:`, error);
797
- throw error;
798
- }
799
- }
800
- /**
801
- * 创建邀请链接
802
- * @param chatId 聊天 ID
803
- */
804
- async createInviteLink(chatId) {
805
- try {
806
- const link = await this.telegram.createChatInviteLink(chatId, {});
807
- this.pluginLogger.info(`Telegram Bot ${this.$id} 创建邀请链接(聊天 ${chatId})`);
808
- return link.invite_link;
809
- }
810
- catch (error) {
811
- this.pluginLogger.error(`Telegram Bot ${this.$id} 创建邀请链接失败:`, error);
812
- throw error;
813
- }
814
- }
815
- async sendPoll(chatId, question, options, isAnonymous = true, allowsMultipleAnswers = false) {
816
- try {
817
- const result = await this.telegram.sendPoll(chatId, question, options, {
818
- is_anonymous: isAnonymous,
819
- allows_multiple_answers: allowsMultipleAnswers,
820
- });
821
- this.pluginLogger.info(`Telegram Bot ${this.$id} 发送投票到 ${chatId}`);
822
- return result;
823
- }
824
- catch (error) {
825
- this.pluginLogger.error(`Telegram Bot ${this.$id} 发送投票失败:`, error);
826
- throw error;
827
- }
828
- }
829
- async setMessageReaction(chatId, messageId, reaction) {
830
- try {
831
- await this.telegram.callApi('setMessageReaction', {
832
- chat_id: chatId,
833
- message_id: messageId,
834
- reaction: [{ type: 'emoji', emoji: reaction }],
835
- });
836
- return true;
837
- }
838
- catch (error) {
839
- this.pluginLogger.error(`Telegram Bot ${this.$id} 设置反应失败:`, error);
840
- throw error;
841
- }
842
- }
843
- async sendStickerMessage(chatId, sticker) {
844
- try {
845
- const result = await this.telegram.sendSticker(chatId, sticker);
846
- this.pluginLogger.info(`Telegram Bot ${this.$id} 发送贴纸到 ${chatId}`);
847
- return result;
848
- }
849
- catch (error) {
850
- this.pluginLogger.error(`Telegram Bot ${this.$id} 发送贴纸失败:`, error);
851
- throw error;
852
- }
853
- }
854
- async setChatPermissionsAll(chatId, permissions) {
855
- try {
856
- await this.telegram.setChatPermissions(chatId, permissions);
857
- this.pluginLogger.info(`Telegram Bot ${this.$id} 设置聊天 ${chatId} 权限`);
858
- return true;
859
- }
860
- catch (error) {
861
- this.pluginLogger.error(`Telegram Bot ${this.$id} 设置聊天权限失败:`, error);
862
- throw error;
863
- }
864
- }
865
- }
866
- //# sourceMappingURL=bot.js.map