@elizaos/plugin-telegram 1.0.0-alpha.2 → 1.0.0-alpha.21
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/index.js +531 -103
- package/dist/index.js.map +1 -1
- package/package.json +7 -5
- package/dist/index.d.ts +0 -33
package/dist/index.js
CHANGED
|
@@ -1,10 +1,28 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
2
|
import {
|
|
3
|
+
ChannelType as ChannelType2,
|
|
4
|
+
EventTypes as EventTypes2,
|
|
5
|
+
Role,
|
|
3
6
|
Service,
|
|
7
|
+
createUniqueUuid as createUniqueUuid2,
|
|
4
8
|
logger as logger3
|
|
5
9
|
} from "@elizaos/core";
|
|
6
10
|
import { Telegraf } from "telegraf";
|
|
7
11
|
|
|
12
|
+
// src/constants.ts
|
|
13
|
+
var MESSAGE_CONSTANTS = {
|
|
14
|
+
MAX_MESSAGES: 50,
|
|
15
|
+
RECENT_MESSAGE_COUNT: 5,
|
|
16
|
+
CHAT_HISTORY_COUNT: 10,
|
|
17
|
+
DEFAULT_SIMILARITY_THRESHOLD: 0.6,
|
|
18
|
+
DEFAULT_SIMILARITY_THRESHOLD_FOLLOW_UPS: 0.4,
|
|
19
|
+
INTEREST_DECAY_TIME: 5 * 60 * 1e3,
|
|
20
|
+
// 5 minutes
|
|
21
|
+
PARTIAL_INTEREST_DECAY: 3 * 60 * 1e3
|
|
22
|
+
// 3 minutes
|
|
23
|
+
};
|
|
24
|
+
var TELEGRAM_SERVICE_NAME = "telegram";
|
|
25
|
+
|
|
8
26
|
// ../../node_modules/zod/lib/index.mjs
|
|
9
27
|
var util;
|
|
10
28
|
(function(util2) {
|
|
@@ -4074,10 +4092,10 @@ ${errorMessages}`
|
|
|
4074
4092
|
// src/messageManager.ts
|
|
4075
4093
|
import {
|
|
4076
4094
|
ChannelType,
|
|
4077
|
-
|
|
4078
|
-
logger,
|
|
4095
|
+
EventTypes,
|
|
4079
4096
|
ModelTypes,
|
|
4080
|
-
|
|
4097
|
+
createUniqueUuid,
|
|
4098
|
+
logger
|
|
4081
4099
|
} from "@elizaos/core";
|
|
4082
4100
|
|
|
4083
4101
|
// src/utils.ts
|
|
@@ -4106,11 +4124,23 @@ var getChannelType = (chat) => {
|
|
|
4106
4124
|
var MessageManager = class {
|
|
4107
4125
|
bot;
|
|
4108
4126
|
runtime;
|
|
4127
|
+
/**
|
|
4128
|
+
* Constructor for creating a new instance of a BotAgent.
|
|
4129
|
+
*
|
|
4130
|
+
* @param {Telegraf<Context>} bot - The Telegraf instance used for interacting with the bot platform.
|
|
4131
|
+
* @param {IAgentRuntime} runtime - The runtime environment for the agent.
|
|
4132
|
+
*/
|
|
4109
4133
|
constructor(bot, runtime) {
|
|
4110
4134
|
this.bot = bot;
|
|
4111
4135
|
this.runtime = runtime;
|
|
4112
4136
|
}
|
|
4113
4137
|
// Process image messages and generate descriptions
|
|
4138
|
+
/**
|
|
4139
|
+
* Process an image from a Telegram message to extract the image URL and description.
|
|
4140
|
+
*
|
|
4141
|
+
* @param {Message} message - The Telegram message object containing the image.
|
|
4142
|
+
* @returns {Promise<{ description: string } | null>} The description of the processed image or null if no image found.
|
|
4143
|
+
*/
|
|
4114
4144
|
async processImage(message) {
|
|
4115
4145
|
var _a, _b, _c;
|
|
4116
4146
|
try {
|
|
@@ -4140,6 +4170,14 @@ ${description}]` };
|
|
|
4140
4170
|
return null;
|
|
4141
4171
|
}
|
|
4142
4172
|
// Send long messages in chunks
|
|
4173
|
+
/**
|
|
4174
|
+
* Sends a message in chunks, handling attachments and splitting the message if necessary
|
|
4175
|
+
*
|
|
4176
|
+
* @param {Context} ctx - The context object representing the current state of the bot
|
|
4177
|
+
* @param {Content} content - The content of the message to be sent
|
|
4178
|
+
* @param {number} [replyToMessageId] - The ID of the message to reply to, if any
|
|
4179
|
+
* @returns {Promise<Message.TextMessage[]>} - An array of TextMessage objects representing the messages sent
|
|
4180
|
+
*/
|
|
4143
4181
|
async sendMessageInChunks(ctx, content, replyToMessageId) {
|
|
4144
4182
|
if (content.attachments && content.attachments.length > 0) {
|
|
4145
4183
|
content.attachments.map(async (attachment) => {
|
|
@@ -4187,6 +4225,16 @@ ${description}]` };
|
|
|
4187
4225
|
return sentMessages;
|
|
4188
4226
|
}
|
|
4189
4227
|
}
|
|
4228
|
+
/**
|
|
4229
|
+
* Sends media to a chat using the Telegram API.
|
|
4230
|
+
*
|
|
4231
|
+
* @param {Context} ctx - The context object containing information about the current chat.
|
|
4232
|
+
* @param {string} mediaPath - The path to the media to be sent, either a URL or a local file path.
|
|
4233
|
+
* @param {MediaType} type - The type of media being sent (PHOTO, VIDEO, DOCUMENT, AUDIO, or ANIMATION).
|
|
4234
|
+
* @param {string} [caption] - Optional caption for the media being sent.
|
|
4235
|
+
*
|
|
4236
|
+
* @returns {Promise<void>} A Promise that resolves when the media is successfully sent.
|
|
4237
|
+
*/
|
|
4190
4238
|
async sendMedia(ctx, mediaPath, type, caption) {
|
|
4191
4239
|
try {
|
|
4192
4240
|
const isUrl = /^(http|https):\/\//.test(mediaPath);
|
|
@@ -4226,6 +4274,12 @@ ${description}]` };
|
|
|
4226
4274
|
}
|
|
4227
4275
|
}
|
|
4228
4276
|
// Split message into smaller parts
|
|
4277
|
+
/**
|
|
4278
|
+
* Splits a given text into an array of strings based on the maximum message length.
|
|
4279
|
+
*
|
|
4280
|
+
* @param {string} text - The text to split into chunks.
|
|
4281
|
+
* @returns {string[]} An array of strings with each element representing a chunk of the original text.
|
|
4282
|
+
*/
|
|
4229
4283
|
splitMessage(text) {
|
|
4230
4284
|
const chunks = [];
|
|
4231
4285
|
let currentChunk = "";
|
|
@@ -4242,6 +4296,11 @@ ${description}]` };
|
|
|
4242
4296
|
return chunks;
|
|
4243
4297
|
}
|
|
4244
4298
|
// Main handler for incoming messages
|
|
4299
|
+
/**
|
|
4300
|
+
* Handle incoming messages from Telegram and process them accordingly.
|
|
4301
|
+
* @param {Context} ctx - The context object containing information about the message.
|
|
4302
|
+
* @returns {Promise<void>}
|
|
4303
|
+
*/
|
|
4245
4304
|
async handleMessage(ctx) {
|
|
4246
4305
|
var _a, _b;
|
|
4247
4306
|
if (!ctx.message || !ctx.from) return;
|
|
@@ -4267,28 +4326,11 @@ ${description}]` };
|
|
|
4267
4326
|
}
|
|
4268
4327
|
const fullText = imageInfo ? `${messageText} ${imageInfo.description}` : messageText;
|
|
4269
4328
|
if (!fullText) return;
|
|
4270
|
-
const memory = {
|
|
4271
|
-
id: messageId,
|
|
4272
|
-
entityId,
|
|
4273
|
-
agentId: this.runtime.agentId,
|
|
4274
|
-
roomId,
|
|
4275
|
-
content: {
|
|
4276
|
-
text: fullText,
|
|
4277
|
-
source: "telegram",
|
|
4278
|
-
channelType: getChannelType(message.chat),
|
|
4279
|
-
// name: userName,
|
|
4280
|
-
// userName: userName,
|
|
4281
|
-
// Safely access reply_to_message with type guard
|
|
4282
|
-
inReplyTo: "reply_to_message" in message && message.reply_to_message ? createUniqueUuid(
|
|
4283
|
-
this.runtime,
|
|
4284
|
-
message.reply_to_message.message_id.toString()
|
|
4285
|
-
) : void 0
|
|
4286
|
-
},
|
|
4287
|
-
createdAt: message.date * 1e3
|
|
4288
|
-
};
|
|
4289
4329
|
const chat = message.chat;
|
|
4290
|
-
const
|
|
4330
|
+
const channelType = getChannelType(chat);
|
|
4331
|
+
const worldName = chat.type === "supergroup" ? chat.title : chat.type === "channel" ? chat.title : chat.type === "private" ? `Chat with ${chat.first_name || "Unknown"}` : "Telegram";
|
|
4291
4332
|
const roomName = chat.type === "private" ? chat.first_name : chat.type === "supergroup" ? chat.title : chat.type === "channel" ? chat.title : chat.type === "group" ? chat.title : "Unknown Group";
|
|
4333
|
+
const worldId = createUniqueUuid(this.runtime, chat.id.toString());
|
|
4292
4334
|
await this.runtime.ensureConnection({
|
|
4293
4335
|
entityId,
|
|
4294
4336
|
roomId,
|
|
@@ -4297,10 +4339,9 @@ ${description}]` };
|
|
|
4297
4339
|
source: "telegram",
|
|
4298
4340
|
channelId: ctx.chat.id.toString(),
|
|
4299
4341
|
serverId: chat.id.toString(),
|
|
4300
|
-
type:
|
|
4342
|
+
type: channelType,
|
|
4343
|
+
worldId
|
|
4301
4344
|
});
|
|
4302
|
-
const channelType = getChannelType(chat);
|
|
4303
|
-
const worldId = createUniqueUuid(this.runtime, chat.id.toString());
|
|
4304
4345
|
const room = {
|
|
4305
4346
|
id: roomId,
|
|
4306
4347
|
name: roomName,
|
|
@@ -4310,24 +4351,23 @@ ${description}]` };
|
|
|
4310
4351
|
serverId: ctx.chat.id.toString(),
|
|
4311
4352
|
worldId
|
|
4312
4353
|
};
|
|
4313
|
-
const ownerId = chat.id;
|
|
4314
|
-
if (channelType === ChannelType.GROUP) {
|
|
4315
|
-
await this.runtime.ensureWorldExists({
|
|
4316
|
-
id: worldId,
|
|
4317
|
-
name: worldName,
|
|
4318
|
-
serverId: chat.id.toString(),
|
|
4319
|
-
agentId: this.runtime.agentId,
|
|
4320
|
-
metadata: {
|
|
4321
|
-
ownership: chat.type === "supergroup" ? { ownerId: chat.id.toString() } : void 0,
|
|
4322
|
-
roles: {
|
|
4323
|
-
// TODO: chat.id is probably wrong key for this
|
|
4324
|
-
[ownerId]: Role.OWNER
|
|
4325
|
-
}
|
|
4326
|
-
}
|
|
4327
|
-
});
|
|
4328
|
-
room.worldId = worldId;
|
|
4329
|
-
}
|
|
4330
4354
|
await this.runtime.ensureRoomExists(room);
|
|
4355
|
+
const memory = {
|
|
4356
|
+
id: messageId,
|
|
4357
|
+
entityId,
|
|
4358
|
+
agentId: this.runtime.agentId,
|
|
4359
|
+
roomId,
|
|
4360
|
+
content: {
|
|
4361
|
+
text: fullText,
|
|
4362
|
+
source: "telegram",
|
|
4363
|
+
channelType,
|
|
4364
|
+
inReplyTo: "reply_to_message" in message && message.reply_to_message ? createUniqueUuid(
|
|
4365
|
+
this.runtime,
|
|
4366
|
+
message.reply_to_message.message_id.toString()
|
|
4367
|
+
) : void 0
|
|
4368
|
+
},
|
|
4369
|
+
createdAt: message.date * 1e3
|
|
4370
|
+
};
|
|
4331
4371
|
const callback = async (content, _files) => {
|
|
4332
4372
|
try {
|
|
4333
4373
|
const sentMessages = await this.sendMessageInChunks(
|
|
@@ -4352,7 +4392,7 @@ ${description}]` };
|
|
|
4352
4392
|
...content,
|
|
4353
4393
|
text: sentMessage.text,
|
|
4354
4394
|
inReplyTo: messageId,
|
|
4355
|
-
channelType
|
|
4395
|
+
channelType
|
|
4356
4396
|
},
|
|
4357
4397
|
createdAt: sentMessage.date * 1e3
|
|
4358
4398
|
};
|
|
@@ -4366,11 +4406,23 @@ ${description}]` };
|
|
|
4366
4406
|
}
|
|
4367
4407
|
};
|
|
4368
4408
|
this.runtime.emitEvent(
|
|
4369
|
-
|
|
4409
|
+
EventTypes.MESSAGE_RECEIVED,
|
|
4410
|
+
{
|
|
4411
|
+
runtime: this.runtime,
|
|
4412
|
+
message: memory,
|
|
4413
|
+
callback,
|
|
4414
|
+
source: "telegram"
|
|
4415
|
+
}
|
|
4416
|
+
);
|
|
4417
|
+
this.runtime.emitEvent(
|
|
4418
|
+
"TELEGRAM_MESSAGE_RECEIVED" /* MESSAGE_RECEIVED */,
|
|
4370
4419
|
{
|
|
4371
4420
|
runtime: this.runtime,
|
|
4372
4421
|
message: memory,
|
|
4373
|
-
callback
|
|
4422
|
+
callback,
|
|
4423
|
+
source: "telegram",
|
|
4424
|
+
ctx,
|
|
4425
|
+
originalMessage: message
|
|
4374
4426
|
}
|
|
4375
4427
|
);
|
|
4376
4428
|
} catch (error) {
|
|
@@ -4379,6 +4431,11 @@ ${description}]` };
|
|
|
4379
4431
|
throw error;
|
|
4380
4432
|
}
|
|
4381
4433
|
}
|
|
4434
|
+
/**
|
|
4435
|
+
* Handles the reaction event triggered by a user reacting to a message.
|
|
4436
|
+
* * @param {NarrowedContext<Context<Update>, Update.MessageReactionUpdate>} ctx The context of the message reaction update
|
|
4437
|
+
* @returns {Promise<void>} A Promise that resolves when the reaction handling is complete
|
|
4438
|
+
*/
|
|
4382
4439
|
async handleReaction(ctx) {
|
|
4383
4440
|
if (!ctx.update.message_reaction || !ctx.from) return;
|
|
4384
4441
|
const reaction = ctx.update.message_reaction;
|
|
@@ -4390,6 +4447,7 @@ ${description}]` };
|
|
|
4390
4447
|
ctx.from.id.toString()
|
|
4391
4448
|
);
|
|
4392
4449
|
const roomId = createUniqueUuid(this.runtime, ctx.chat.id.toString());
|
|
4450
|
+
const worldId = createUniqueUuid(this.runtime, ctx.chat.id.toString());
|
|
4393
4451
|
const reactionId = createUniqueUuid(
|
|
4394
4452
|
this.runtime,
|
|
4395
4453
|
`${reaction.message_id}-${ctx.from.id}-${Date.now()}`
|
|
@@ -4403,8 +4461,6 @@ ${description}]` };
|
|
|
4403
4461
|
channelType: getChannelType(reaction.chat),
|
|
4404
4462
|
text: `Reacted with: ${reactionType === "emoji" ? reactionEmoji : reactionType}`,
|
|
4405
4463
|
source: "telegram",
|
|
4406
|
-
// name: ctx.from.first_name,
|
|
4407
|
-
// userName: ctx.from.username,
|
|
4408
4464
|
inReplyTo: createUniqueUuid(
|
|
4409
4465
|
this.runtime,
|
|
4410
4466
|
reaction.message_id.toString()
|
|
@@ -4412,7 +4468,6 @@ ${description}]` };
|
|
|
4412
4468
|
},
|
|
4413
4469
|
createdAt: Date.now()
|
|
4414
4470
|
};
|
|
4415
|
-
await this.runtime.getMemoryManager("messages").createMemory(memory);
|
|
4416
4471
|
const callback = async (content) => {
|
|
4417
4472
|
try {
|
|
4418
4473
|
const sentMessage = await ctx.reply(content.text);
|
|
@@ -4437,17 +4492,94 @@ ${description}]` };
|
|
|
4437
4492
|
}
|
|
4438
4493
|
};
|
|
4439
4494
|
this.runtime.emitEvent(
|
|
4440
|
-
|
|
4495
|
+
EventTypes.REACTION_RECEIVED,
|
|
4496
|
+
{
|
|
4497
|
+
runtime: this.runtime,
|
|
4498
|
+
message: memory,
|
|
4499
|
+
callback,
|
|
4500
|
+
source: "telegram"
|
|
4501
|
+
}
|
|
4502
|
+
);
|
|
4503
|
+
this.runtime.emitEvent(
|
|
4504
|
+
"TELEGRAM_REACTION_RECEIVED" /* REACTION_RECEIVED */,
|
|
4441
4505
|
{
|
|
4442
4506
|
runtime: this.runtime,
|
|
4443
4507
|
message: memory,
|
|
4444
|
-
callback
|
|
4508
|
+
callback,
|
|
4509
|
+
source: "telegram",
|
|
4510
|
+
ctx,
|
|
4511
|
+
reactionString: reactionType === "emoji" ? reactionEmoji : reactionType,
|
|
4512
|
+
originalReaction: reaction.new_reaction[0]
|
|
4445
4513
|
}
|
|
4446
4514
|
);
|
|
4447
4515
|
} catch (error) {
|
|
4448
4516
|
logger.error("Error handling reaction:", error);
|
|
4449
4517
|
}
|
|
4450
4518
|
}
|
|
4519
|
+
/**
|
|
4520
|
+
* Sends a message to a Telegram chat and emits appropriate events
|
|
4521
|
+
* @param {number | string} chatId - The Telegram chat ID to send the message to
|
|
4522
|
+
* @param {Content} content - The content to send
|
|
4523
|
+
* @param {number} [replyToMessageId] - Optional message ID to reply to
|
|
4524
|
+
* @returns {Promise<Message.TextMessage[]>} The sent messages
|
|
4525
|
+
*/
|
|
4526
|
+
async sendMessage(chatId, content, replyToMessageId) {
|
|
4527
|
+
try {
|
|
4528
|
+
const ctx = {
|
|
4529
|
+
chat: { id: chatId },
|
|
4530
|
+
telegram: this.bot.telegram
|
|
4531
|
+
};
|
|
4532
|
+
const sentMessages = await this.sendMessageInChunks(
|
|
4533
|
+
ctx,
|
|
4534
|
+
content,
|
|
4535
|
+
replyToMessageId
|
|
4536
|
+
);
|
|
4537
|
+
if (!(sentMessages == null ? void 0 : sentMessages.length)) return [];
|
|
4538
|
+
const roomId = createUniqueUuid(this.runtime, chatId.toString());
|
|
4539
|
+
const memories = [];
|
|
4540
|
+
for (const sentMessage of sentMessages) {
|
|
4541
|
+
const memory = {
|
|
4542
|
+
id: createUniqueUuid(this.runtime, sentMessage.message_id.toString()),
|
|
4543
|
+
entityId: this.runtime.agentId,
|
|
4544
|
+
agentId: this.runtime.agentId,
|
|
4545
|
+
roomId,
|
|
4546
|
+
content: {
|
|
4547
|
+
...content,
|
|
4548
|
+
text: sentMessage.text,
|
|
4549
|
+
source: "telegram",
|
|
4550
|
+
channelType: getChannelType({
|
|
4551
|
+
id: typeof chatId === "string" ? Number.parseInt(chatId, 10) : chatId,
|
|
4552
|
+
type: "private"
|
|
4553
|
+
// Default to private, will be overridden if in context
|
|
4554
|
+
})
|
|
4555
|
+
},
|
|
4556
|
+
createdAt: sentMessage.date * 1e3
|
|
4557
|
+
};
|
|
4558
|
+
await this.runtime.getMemoryManager("messages").createMemory(memory);
|
|
4559
|
+
memories.push(memory);
|
|
4560
|
+
}
|
|
4561
|
+
this.runtime.emitEvent(
|
|
4562
|
+
EventTypes.MESSAGE_SENT,
|
|
4563
|
+
{
|
|
4564
|
+
runtime: this.runtime,
|
|
4565
|
+
messages: memories,
|
|
4566
|
+
roomId,
|
|
4567
|
+
source: "telegram"
|
|
4568
|
+
}
|
|
4569
|
+
);
|
|
4570
|
+
this.runtime.emitEvent(
|
|
4571
|
+
"TELEGRAM_MESSAGE_SENT" /* MESSAGE_SENT */,
|
|
4572
|
+
{
|
|
4573
|
+
originalMessages: sentMessages,
|
|
4574
|
+
chatId
|
|
4575
|
+
}
|
|
4576
|
+
);
|
|
4577
|
+
return sentMessages;
|
|
4578
|
+
} catch (error) {
|
|
4579
|
+
logger.error("Error sending message to Telegram:", error);
|
|
4580
|
+
return [];
|
|
4581
|
+
}
|
|
4582
|
+
}
|
|
4451
4583
|
};
|
|
4452
4584
|
|
|
4453
4585
|
// src/tests.ts
|
|
@@ -4459,6 +4591,14 @@ var TelegramTestSuite = class {
|
|
|
4459
4591
|
bot = null;
|
|
4460
4592
|
messageManager = null;
|
|
4461
4593
|
tests;
|
|
4594
|
+
/**
|
|
4595
|
+
* Constructor for initializing a set of test cases for a Telegram bot.
|
|
4596
|
+
*
|
|
4597
|
+
* @constructor
|
|
4598
|
+
* @property {Array<Object>} tests - An array of test cases with name and corresponding test functions.
|
|
4599
|
+
* @property {string} tests.name - The name of the test case.
|
|
4600
|
+
* @property {function} tests.fn - The test function to be executed.
|
|
4601
|
+
*/
|
|
4462
4602
|
constructor() {
|
|
4463
4603
|
this.tests = [
|
|
4464
4604
|
{
|
|
@@ -4489,6 +4629,13 @@ var TelegramTestSuite = class {
|
|
|
4489
4629
|
* Reference on getting the Telegram chat ID:
|
|
4490
4630
|
* https://stackoverflow.com/a/32572159
|
|
4491
4631
|
*/
|
|
4632
|
+
/**
|
|
4633
|
+
* Validates the chat ID by checking if it is set in the runtime settings or environment variables.
|
|
4634
|
+
* If not set, an error is thrown with a message instructing to provide a valid chat ID.
|
|
4635
|
+
* @param {IAgentRuntime} runtime - The runtime object that provides access to the settings and environment variables.
|
|
4636
|
+
* @throws {Error} If TELEGRAM_TEST_CHAT_ID is not set in the runtime settings or environment variables.
|
|
4637
|
+
* @returns {string} The validated chat ID.
|
|
4638
|
+
*/
|
|
4492
4639
|
validateChatId(runtime) {
|
|
4493
4640
|
const testChatId = runtime.getSetting("TELEGRAM_TEST_CHAT_ID") || process.env.TELEGRAM_TEST_CHAT_ID;
|
|
4494
4641
|
if (!testChatId) {
|
|
@@ -4531,13 +4678,17 @@ var TelegramTestSuite = class {
|
|
|
4531
4678
|
const chat = await this.getChatInfo(runtime);
|
|
4532
4679
|
const mockContext = {
|
|
4533
4680
|
chat,
|
|
4534
|
-
from: { id:
|
|
4681
|
+
from: { id: 123, username: "TestUser" },
|
|
4535
4682
|
telegram: this.bot.telegram
|
|
4536
4683
|
};
|
|
4537
4684
|
const messageContent = {
|
|
4538
4685
|
text: "Here is an image attachment:",
|
|
4539
4686
|
attachments: [
|
|
4540
4687
|
{
|
|
4688
|
+
id: "123",
|
|
4689
|
+
title: "Sample Image",
|
|
4690
|
+
source: TEST_IMAGE_URL,
|
|
4691
|
+
text: "Sample Image",
|
|
4541
4692
|
url: TEST_IMAGE_URL,
|
|
4542
4693
|
contentType: "image/png",
|
|
4543
4694
|
description: "Sample Image"
|
|
@@ -4561,12 +4712,19 @@ var TelegramTestSuite = class {
|
|
|
4561
4712
|
const chat = await this.getChatInfo(runtime);
|
|
4562
4713
|
const mockContext = {
|
|
4563
4714
|
chat,
|
|
4564
|
-
from: {
|
|
4715
|
+
from: {
|
|
4716
|
+
id: 123,
|
|
4717
|
+
username: "TestUser",
|
|
4718
|
+
is_bot: false,
|
|
4719
|
+
first_name: "Test",
|
|
4720
|
+
last_name: "User"
|
|
4721
|
+
},
|
|
4565
4722
|
message: {
|
|
4566
4723
|
message_id: void 0,
|
|
4567
4724
|
text: `@${(_a = this.bot.botInfo) == null ? void 0 : _a.username}! Hello!`,
|
|
4568
4725
|
date: Math.floor(Date.now() / 1e3),
|
|
4569
4726
|
chat
|
|
4727
|
+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
|
4570
4728
|
},
|
|
4571
4729
|
telegram: this.bot.telegram
|
|
4572
4730
|
};
|
|
@@ -4586,13 +4744,12 @@ var TelegramTestSuite = class {
|
|
|
4586
4744
|
const fileId = await this.getFileId(chatId, TEST_IMAGE_URL);
|
|
4587
4745
|
const mockMessage = {
|
|
4588
4746
|
message_id: void 0,
|
|
4747
|
+
chat: { id: chatId },
|
|
4589
4748
|
date: Math.floor(Date.now() / 1e3),
|
|
4590
4749
|
photo: [{ file_id: fileId }],
|
|
4591
4750
|
text: `@${(_a = this.bot.botInfo) == null ? void 0 : _a.username}!`
|
|
4592
4751
|
};
|
|
4593
|
-
const { description } = await this.messageManager.processImage(
|
|
4594
|
-
mockMessage
|
|
4595
|
-
);
|
|
4752
|
+
const { description } = await this.messageManager.processImage(mockMessage);
|
|
4596
4753
|
if (!description) {
|
|
4597
4754
|
throw new Error("Error processing Telegram image");
|
|
4598
4755
|
}
|
|
@@ -4612,20 +4769,6 @@ var TelegramTestSuite = class {
|
|
|
4612
4769
|
}
|
|
4613
4770
|
};
|
|
4614
4771
|
|
|
4615
|
-
// src/constants.ts
|
|
4616
|
-
var MESSAGE_CONSTANTS = {
|
|
4617
|
-
MAX_MESSAGES: 50,
|
|
4618
|
-
RECENT_MESSAGE_COUNT: 5,
|
|
4619
|
-
CHAT_HISTORY_COUNT: 10,
|
|
4620
|
-
DEFAULT_SIMILARITY_THRESHOLD: 0.6,
|
|
4621
|
-
DEFAULT_SIMILARITY_THRESHOLD_FOLLOW_UPS: 0.4,
|
|
4622
|
-
INTEREST_DECAY_TIME: 5 * 60 * 1e3,
|
|
4623
|
-
// 5 minutes
|
|
4624
|
-
PARTIAL_INTEREST_DECAY: 3 * 60 * 1e3
|
|
4625
|
-
// 3 minutes
|
|
4626
|
-
};
|
|
4627
|
-
var TELEGRAM_SERVICE_NAME = "telegram";
|
|
4628
|
-
|
|
4629
4772
|
// src/index.ts
|
|
4630
4773
|
var TelegramService = class _TelegramService extends Service {
|
|
4631
4774
|
static serviceType = TELEGRAM_SERVICE_NAME;
|
|
@@ -4633,6 +4776,11 @@ var TelegramService = class _TelegramService extends Service {
|
|
|
4633
4776
|
bot;
|
|
4634
4777
|
messageManager;
|
|
4635
4778
|
options;
|
|
4779
|
+
knownChats = /* @__PURE__ */ new Map();
|
|
4780
|
+
/**
|
|
4781
|
+
* Constructor for TelegramService class.
|
|
4782
|
+
* @param {IAgentRuntime} runtime - The runtime object for the agent.
|
|
4783
|
+
*/
|
|
4636
4784
|
constructor(runtime) {
|
|
4637
4785
|
super(runtime);
|
|
4638
4786
|
logger3.log("\u{1F4F1} Constructing new TelegramService...");
|
|
@@ -4646,68 +4794,234 @@ var TelegramService = class _TelegramService extends Service {
|
|
|
4646
4794
|
this.messageManager = new MessageManager(this.bot, this.runtime);
|
|
4647
4795
|
logger3.log("\u2705 TelegramService constructor completed");
|
|
4648
4796
|
}
|
|
4797
|
+
/**
|
|
4798
|
+
* Starts the Telegram service for the given runtime.
|
|
4799
|
+
*
|
|
4800
|
+
* @param {IAgentRuntime} runtime - The agent runtime to start the Telegram service for.
|
|
4801
|
+
* @returns {Promise<TelegramService>} A promise that resolves with the initialized TelegramService.
|
|
4802
|
+
*/
|
|
4649
4803
|
static async start(runtime) {
|
|
4650
4804
|
await validateTelegramConfig(runtime);
|
|
4651
|
-
const
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
)
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4805
|
+
const maxRetries = 5;
|
|
4806
|
+
let retryCount = 0;
|
|
4807
|
+
let lastError = null;
|
|
4808
|
+
while (retryCount < maxRetries) {
|
|
4809
|
+
try {
|
|
4810
|
+
const service = new _TelegramService(runtime);
|
|
4811
|
+
logger3.success(
|
|
4812
|
+
`\u2705 Telegram client successfully started for character ${runtime.character.name}`
|
|
4813
|
+
);
|
|
4814
|
+
logger3.log("\u{1F680} Starting Telegram bot...");
|
|
4815
|
+
await service.initializeBot();
|
|
4816
|
+
service.setupMessageHandlers();
|
|
4817
|
+
await service.bot.telegram.getMe();
|
|
4818
|
+
return service;
|
|
4819
|
+
} catch (error) {
|
|
4820
|
+
lastError = error instanceof Error ? error : new Error(String(error));
|
|
4821
|
+
logger3.error(`Telegram initialization attempt ${retryCount + 1} failed: ${lastError.message}`);
|
|
4822
|
+
retryCount++;
|
|
4823
|
+
if (retryCount < maxRetries) {
|
|
4824
|
+
const delay = 2 ** retryCount * 1e3;
|
|
4825
|
+
logger3.info(`Retrying Telegram initialization in ${delay / 1e3} seconds...`);
|
|
4826
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
4827
|
+
}
|
|
4828
|
+
}
|
|
4662
4829
|
}
|
|
4663
|
-
|
|
4830
|
+
throw new Error(`Telegram initialization failed after ${maxRetries} attempts. Last error: ${lastError == null ? void 0 : lastError.message}`);
|
|
4664
4831
|
}
|
|
4832
|
+
/**
|
|
4833
|
+
* Stops the agent runtime.
|
|
4834
|
+
* @param {IAgentRuntime} runtime - The agent runtime to stop
|
|
4835
|
+
*/
|
|
4665
4836
|
static async stop(runtime) {
|
|
4666
4837
|
const tgClient = runtime.getService(TELEGRAM_SERVICE_NAME);
|
|
4667
4838
|
if (tgClient) {
|
|
4668
4839
|
await tgClient.stop();
|
|
4669
4840
|
}
|
|
4670
4841
|
}
|
|
4842
|
+
/**
|
|
4843
|
+
* Asynchronously stops the bot.
|
|
4844
|
+
*
|
|
4845
|
+
* @returns A Promise that resolves once the bot has stopped.
|
|
4846
|
+
*/
|
|
4671
4847
|
async stop() {
|
|
4672
4848
|
this.bot.stop();
|
|
4673
4849
|
}
|
|
4850
|
+
/**
|
|
4851
|
+
* Initializes the Telegram bot by launching it, getting bot info, and setting up message manager.
|
|
4852
|
+
* @returns {Promise<void>} A Promise that resolves when the initialization is complete.
|
|
4853
|
+
*/
|
|
4674
4854
|
async initializeBot() {
|
|
4675
4855
|
this.bot.launch({
|
|
4676
4856
|
dropPendingUpdates: true,
|
|
4677
4857
|
allowedUpdates: ["message", "message_reaction"]
|
|
4678
4858
|
});
|
|
4679
|
-
logger3.log("\u2728 Telegram bot successfully launched and is running!");
|
|
4680
4859
|
const botInfo = await this.bot.telegram.getMe();
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4860
|
+
logger3.log(`Bot info: ${JSON.stringify(botInfo)}`);
|
|
4861
|
+
process.once("SIGINT", () => this.bot.stop("SIGINT"));
|
|
4862
|
+
process.once("SIGTERM", () => this.bot.stop("SIGTERM"));
|
|
4684
4863
|
}
|
|
4864
|
+
/**
|
|
4865
|
+
* Checks if a group is authorized, based on the TELEGRAM_ALLOWED_CHATS setting.
|
|
4866
|
+
* @param {Context} ctx - The context of the incoming update.
|
|
4867
|
+
* @returns {Promise<boolean>} A Promise that resolves with a boolean indicating if the group is authorized.
|
|
4868
|
+
*/
|
|
4685
4869
|
async isGroupAuthorized(ctx) {
|
|
4686
|
-
var _a
|
|
4687
|
-
const
|
|
4688
|
-
if (
|
|
4689
|
-
|
|
4870
|
+
var _a;
|
|
4871
|
+
const chatId = (_a = ctx.chat) == null ? void 0 : _a.id.toString();
|
|
4872
|
+
if (!chatId) return false;
|
|
4873
|
+
if (!this.knownChats.has(chatId)) {
|
|
4874
|
+
await this.handleNewChat(ctx);
|
|
4690
4875
|
}
|
|
4691
|
-
|
|
4876
|
+
const allowedChats = this.runtime.getSetting("TELEGRAM_ALLOWED_CHATS");
|
|
4877
|
+
if (!allowedChats) {
|
|
4692
4878
|
return true;
|
|
4693
4879
|
}
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
4697
|
-
|
|
4880
|
+
try {
|
|
4881
|
+
const allowedChatsList = JSON.parse(allowedChats);
|
|
4882
|
+
return allowedChatsList.includes(chatId);
|
|
4883
|
+
} catch (error) {
|
|
4884
|
+
logger3.error("Error parsing TELEGRAM_ALLOWED_CHATS:", error);
|
|
4885
|
+
return false;
|
|
4886
|
+
}
|
|
4887
|
+
}
|
|
4888
|
+
/**
|
|
4889
|
+
* Handles new chat discovery and emits WORLD_JOINED event
|
|
4890
|
+
* @param {Context} ctx - The context of the incoming update
|
|
4891
|
+
*/
|
|
4892
|
+
async handleNewChat(ctx) {
|
|
4893
|
+
if (!ctx.chat) return;
|
|
4894
|
+
const chat = ctx.chat;
|
|
4895
|
+
const chatId = chat.id.toString();
|
|
4896
|
+
this.knownChats.set(chatId, chat);
|
|
4897
|
+
let chatTitle;
|
|
4898
|
+
let channelType;
|
|
4899
|
+
switch (chat.type) {
|
|
4900
|
+
case "private":
|
|
4901
|
+
chatTitle = `Chat with ${chat.first_name || "Unknown User"}`;
|
|
4902
|
+
channelType = ChannelType2.DM;
|
|
4903
|
+
break;
|
|
4904
|
+
case "group":
|
|
4905
|
+
chatTitle = chat.title || "Unknown Group";
|
|
4906
|
+
channelType = ChannelType2.GROUP;
|
|
4907
|
+
break;
|
|
4908
|
+
case "supergroup":
|
|
4909
|
+
chatTitle = chat.title || "Unknown Supergroup";
|
|
4910
|
+
channelType = ChannelType2.GROUP;
|
|
4911
|
+
break;
|
|
4912
|
+
case "channel":
|
|
4913
|
+
chatTitle = chat.title || "Unknown Channel";
|
|
4914
|
+
channelType = ChannelType2.FEED;
|
|
4915
|
+
break;
|
|
4916
|
+
default:
|
|
4917
|
+
chatTitle = "Unknown Chat";
|
|
4918
|
+
channelType = ChannelType2.GROUP;
|
|
4919
|
+
}
|
|
4920
|
+
const worldId = createUniqueUuid2(this.runtime, chatId);
|
|
4921
|
+
const roomId = createUniqueUuid2(this.runtime, chatId);
|
|
4922
|
+
const world = {
|
|
4923
|
+
id: worldId,
|
|
4924
|
+
name: chatTitle,
|
|
4925
|
+
agentId: this.runtime.agentId,
|
|
4926
|
+
serverId: chatId,
|
|
4927
|
+
metadata: {
|
|
4928
|
+
source: "telegram",
|
|
4929
|
+
ownership: { ownerId: chatId },
|
|
4930
|
+
roles: {
|
|
4931
|
+
[chatId]: Role.OWNER
|
|
4932
|
+
}
|
|
4933
|
+
}
|
|
4934
|
+
};
|
|
4935
|
+
const room = {
|
|
4936
|
+
id: roomId,
|
|
4937
|
+
name: chatTitle,
|
|
4938
|
+
source: "telegram",
|
|
4939
|
+
type: channelType,
|
|
4940
|
+
channelId: chatId,
|
|
4941
|
+
serverId: chatId,
|
|
4942
|
+
worldId
|
|
4943
|
+
};
|
|
4944
|
+
const users = [];
|
|
4945
|
+
if (chat.type === "private" && chat.id) {
|
|
4946
|
+
const userId = createUniqueUuid2(this.runtime, chat.id.toString());
|
|
4947
|
+
users.push({
|
|
4948
|
+
id: userId,
|
|
4949
|
+
names: [chat.first_name || "Unknown User"],
|
|
4950
|
+
agentId: this.runtime.agentId,
|
|
4951
|
+
metadata: {
|
|
4952
|
+
telegram: {
|
|
4953
|
+
id: chat.id.toString(),
|
|
4954
|
+
username: chat.username || "unknown",
|
|
4955
|
+
name: chat.first_name || "Unknown User"
|
|
4956
|
+
},
|
|
4957
|
+
source: "telegram"
|
|
4958
|
+
}
|
|
4959
|
+
});
|
|
4960
|
+
} else if (chat.type === "group" || chat.type === "supergroup") {
|
|
4698
4961
|
try {
|
|
4699
|
-
await
|
|
4700
|
-
|
|
4962
|
+
const admins = await this.bot.telegram.getChatAdministrators(chat.id);
|
|
4963
|
+
if (admins && admins.length > 0) {
|
|
4964
|
+
for (const admin of admins) {
|
|
4965
|
+
const userId = createUniqueUuid2(this.runtime, admin.user.id.toString());
|
|
4966
|
+
users.push({
|
|
4967
|
+
id: userId,
|
|
4968
|
+
names: [admin.user.first_name || admin.user.username || "Unknown Admin"],
|
|
4969
|
+
agentId: this.runtime.agentId,
|
|
4970
|
+
metadata: {
|
|
4971
|
+
telegram: {
|
|
4972
|
+
id: admin.user.id.toString(),
|
|
4973
|
+
username: admin.user.username || "unknown",
|
|
4974
|
+
name: admin.user.first_name || "Unknown Admin",
|
|
4975
|
+
isAdmin: true,
|
|
4976
|
+
adminTitle: admin.custom_title || (admin.status === "creator" ? "Owner" : "Admin")
|
|
4977
|
+
},
|
|
4978
|
+
source: "telegram",
|
|
4979
|
+
roles: [admin.status === "creator" ? Role.OWNER : Role.ADMIN]
|
|
4980
|
+
}
|
|
4981
|
+
});
|
|
4982
|
+
}
|
|
4983
|
+
}
|
|
4984
|
+
try {
|
|
4985
|
+
const chatInfo = await this.bot.telegram.getChat(chat.id);
|
|
4986
|
+
if (chatInfo && "member_count" in chatInfo) {
|
|
4987
|
+
world.metadata.memberCount = chatInfo.member_count;
|
|
4988
|
+
}
|
|
4989
|
+
} catch (countError) {
|
|
4990
|
+
logger3.warn(`Could not get member count for chat ${chatId}: ${countError}`);
|
|
4991
|
+
}
|
|
4701
4992
|
} catch (error) {
|
|
4702
|
-
logger3.error
|
|
4703
|
-
`Error leaving unauthorized group ${currentGroupId}:`,
|
|
4704
|
-
error
|
|
4705
|
-
);
|
|
4993
|
+
logger3.warn(`Could not fetch administrators for chat ${chatId}: ${error}`);
|
|
4706
4994
|
}
|
|
4707
|
-
return false;
|
|
4708
4995
|
}
|
|
4709
|
-
|
|
4996
|
+
const worldPayload = {
|
|
4997
|
+
runtime: this.runtime,
|
|
4998
|
+
world,
|
|
4999
|
+
rooms: [room],
|
|
5000
|
+
entities: users,
|
|
5001
|
+
source: "telegram"
|
|
5002
|
+
};
|
|
5003
|
+
const telegramWorldPayload = {
|
|
5004
|
+
...worldPayload,
|
|
5005
|
+
chat
|
|
5006
|
+
};
|
|
5007
|
+
this.runtime.emitEvent(
|
|
5008
|
+
EventTypes2.WORLD_JOINED,
|
|
5009
|
+
worldPayload
|
|
5010
|
+
);
|
|
5011
|
+
this.runtime.emitEvent(
|
|
5012
|
+
"TELEGRAM_WORLD_JOINED" /* WORLD_JOINED */,
|
|
5013
|
+
telegramWorldPayload
|
|
5014
|
+
);
|
|
5015
|
+
if (chat.type === "group" || chat.type === "supergroup") {
|
|
5016
|
+
this.setupEntityTracking(chat.id);
|
|
5017
|
+
}
|
|
4710
5018
|
}
|
|
5019
|
+
/**
|
|
5020
|
+
* Sets up message and reaction handlers for the bot.
|
|
5021
|
+
*
|
|
5022
|
+
* @private
|
|
5023
|
+
* @returns {void}
|
|
5024
|
+
*/
|
|
4711
5025
|
setupMessageHandlers() {
|
|
4712
5026
|
this.bot.on("message", async (ctx) => {
|
|
4713
5027
|
try {
|
|
@@ -4726,6 +5040,120 @@ var TelegramService = class _TelegramService extends Service {
|
|
|
4726
5040
|
}
|
|
4727
5041
|
});
|
|
4728
5042
|
}
|
|
5043
|
+
/**
|
|
5044
|
+
* Sets up tracking for new entities in a group chat to sync them as entities
|
|
5045
|
+
* @param {number} chatId - The Telegram chat ID to track entities for
|
|
5046
|
+
*/
|
|
5047
|
+
setupEntityTracking(chatId) {
|
|
5048
|
+
const syncedEntityIds = /* @__PURE__ */ new Set();
|
|
5049
|
+
this.bot.on("message", async (ctx) => {
|
|
5050
|
+
if (!ctx.chat || ctx.chat.id !== chatId || !ctx.from) return;
|
|
5051
|
+
const entityId = ctx.from.id.toString();
|
|
5052
|
+
if (syncedEntityIds.has(entityId)) return;
|
|
5053
|
+
syncedEntityIds.add(entityId);
|
|
5054
|
+
const entityUuid = createUniqueUuid2(this.runtime, entityId);
|
|
5055
|
+
const worldId = createUniqueUuid2(this.runtime, chatId.toString());
|
|
5056
|
+
const chatIdStr = chatId.toString();
|
|
5057
|
+
try {
|
|
5058
|
+
await this.runtime.ensureConnection({
|
|
5059
|
+
entityId: entityUuid,
|
|
5060
|
+
roomId: createUniqueUuid2(this.runtime, chatIdStr),
|
|
5061
|
+
userName: ctx.from.username || ctx.from.first_name || "Unknown Entity",
|
|
5062
|
+
name: ctx.from.first_name || ctx.from.username || "Unknown Entity",
|
|
5063
|
+
source: "telegram",
|
|
5064
|
+
channelId: chatIdStr,
|
|
5065
|
+
serverId: chatIdStr,
|
|
5066
|
+
type: ChannelType2.GROUP,
|
|
5067
|
+
worldId
|
|
5068
|
+
});
|
|
5069
|
+
const entityJoinedPayload = {
|
|
5070
|
+
runtime: this.runtime,
|
|
5071
|
+
entityId: entityUuid,
|
|
5072
|
+
entity: {
|
|
5073
|
+
id: entityId,
|
|
5074
|
+
username: ctx.from.username || ctx.from.first_name || "Unknown Entity",
|
|
5075
|
+
displayName: ctx.from.first_name || ctx.from.username || "Unknown Entity"
|
|
5076
|
+
},
|
|
5077
|
+
worldId,
|
|
5078
|
+
source: "telegram",
|
|
5079
|
+
metadata: {
|
|
5080
|
+
joinedAt: Date.now()
|
|
5081
|
+
}
|
|
5082
|
+
};
|
|
5083
|
+
const telegramEntityJoinedPayload = {
|
|
5084
|
+
...entityJoinedPayload,
|
|
5085
|
+
telegramUser: {
|
|
5086
|
+
id: ctx.from.id,
|
|
5087
|
+
username: ctx.from.username,
|
|
5088
|
+
first_name: ctx.from.first_name
|
|
5089
|
+
}
|
|
5090
|
+
};
|
|
5091
|
+
this.runtime.emitEvent(
|
|
5092
|
+
EventTypes2.ENTITY_JOINED,
|
|
5093
|
+
entityJoinedPayload
|
|
5094
|
+
);
|
|
5095
|
+
this.runtime.emitEvent(
|
|
5096
|
+
"TELEGRAM_ENTITY_JOINED" /* ENTITY_JOINED */,
|
|
5097
|
+
telegramEntityJoinedPayload
|
|
5098
|
+
);
|
|
5099
|
+
logger3.info(`Tracked new Telegram entity: ${ctx.from.username || ctx.from.first_name || entityId}`);
|
|
5100
|
+
} catch (error) {
|
|
5101
|
+
logger3.error(`Error syncing new Telegram entity ${entityId} from chat ${chatId}:`, error);
|
|
5102
|
+
}
|
|
5103
|
+
});
|
|
5104
|
+
this.bot.on("left_chat_member", async (ctx) => {
|
|
5105
|
+
var _a, _b;
|
|
5106
|
+
if (!((_a = ctx.message) == null ? void 0 : _a.left_chat_member) || ((_b = ctx.chat) == null ? void 0 : _b.id) !== chatId) return;
|
|
5107
|
+
const leftUser = ctx.message.left_chat_member;
|
|
5108
|
+
const entityId = createUniqueUuid2(this.runtime, leftUser.id.toString());
|
|
5109
|
+
const chatIdStr = chatId.toString();
|
|
5110
|
+
const worldId = createUniqueUuid2(this.runtime, chatIdStr);
|
|
5111
|
+
try {
|
|
5112
|
+
const entity = await this.runtime.getEntityById(entityId);
|
|
5113
|
+
if (entity) {
|
|
5114
|
+
entity.metadata = {
|
|
5115
|
+
...entity.metadata,
|
|
5116
|
+
status: "INACTIVE",
|
|
5117
|
+
leftAt: Date.now()
|
|
5118
|
+
};
|
|
5119
|
+
await this.runtime.updateEntity(entity);
|
|
5120
|
+
const entityLeftPayload = {
|
|
5121
|
+
runtime: this.runtime,
|
|
5122
|
+
entityId,
|
|
5123
|
+
entity: {
|
|
5124
|
+
id: leftUser.id.toString(),
|
|
5125
|
+
username: leftUser.username || leftUser.first_name || "Unknown Entity",
|
|
5126
|
+
displayName: leftUser.first_name || leftUser.username || "Unknown Entity"
|
|
5127
|
+
},
|
|
5128
|
+
worldId,
|
|
5129
|
+
source: "telegram",
|
|
5130
|
+
metadata: {
|
|
5131
|
+
leftAt: Date.now()
|
|
5132
|
+
}
|
|
5133
|
+
};
|
|
5134
|
+
const telegramEntityLeftPayload = {
|
|
5135
|
+
...entityLeftPayload,
|
|
5136
|
+
telegramUser: {
|
|
5137
|
+
id: leftUser.id,
|
|
5138
|
+
username: leftUser.username,
|
|
5139
|
+
first_name: leftUser.first_name
|
|
5140
|
+
}
|
|
5141
|
+
};
|
|
5142
|
+
this.runtime.emitEvent(
|
|
5143
|
+
EventTypes2.ENTITY_LEFT,
|
|
5144
|
+
entityLeftPayload
|
|
5145
|
+
);
|
|
5146
|
+
this.runtime.emitEvent(
|
|
5147
|
+
"TELEGRAM_ENTITY_LEFT" /* ENTITY_LEFT */,
|
|
5148
|
+
telegramEntityLeftPayload
|
|
5149
|
+
);
|
|
5150
|
+
logger3.info(`Entity ${leftUser.username || leftUser.first_name || leftUser.id} left chat ${chatId}`);
|
|
5151
|
+
}
|
|
5152
|
+
} catch (error) {
|
|
5153
|
+
logger3.error(`Error handling Telegram entity leaving chat ${chatId}:`, error);
|
|
5154
|
+
}
|
|
5155
|
+
});
|
|
5156
|
+
}
|
|
4729
5157
|
};
|
|
4730
5158
|
var telegramPlugin = {
|
|
4731
5159
|
name: TELEGRAM_SERVICE_NAME,
|