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