Skip to content

Commit faa4d0c

Browse files
committed
feat: extend telegram client multimedia support
- default every other mediaType to document except audio, image, video
1 parent 2f0683a commit faa4d0c

File tree

1 file changed

+102
-49
lines changed

1 file changed

+102
-49
lines changed

packages/client-telegram/src/messageManager.ts

+102-49
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Message } from "@telegraf/types";
22
import { Context, Telegraf } from "telegraf";
3-
import { composeContext, elizaLogger, ServiceType, composeRandomUser } from "@elizaos/core";
3+
4+
import { composeContext, elizaLogger, ServiceType } from "@elizaos/core";
45
import { getEmbeddingZeroVector } from "@elizaos/core";
56
import {
67
Content,
@@ -18,7 +19,7 @@ import { stringToUuid } from "@elizaos/core";
1819
import { generateMessageResponse, generateShouldRespond } from "@elizaos/core";
1920
import { messageCompletionFooter, shouldRespondFooter } from "@elizaos/core";
2021

21-
import { cosineSimilarity, escapeMarkdown } from "./utils";
22+
import { cosineSimilarity } from "./utils";
2223
import {
2324
MESSAGE_CONSTANTS,
2425
TIMING_CONSTANTS,
@@ -296,8 +297,8 @@ export class MessageManager {
296297
"text" in message
297298
? message.text
298299
: "caption" in message
299-
? (message as any).caption
300-
: "";
300+
? (message as any).caption
301+
: "";
301302

302303
if (!messageText) return false;
303304

@@ -359,8 +360,8 @@ export class MessageManager {
359360
"text" in message
360361
? message.text
361362
: "caption" in message
362-
? (message as any).caption
363-
: "";
363+
? (message as any).caption
364+
: "";
364365
if (!messageText) return false;
365366

366367
const isReplyToBot =
@@ -375,7 +376,7 @@ export class MessageManager {
375376
isReplyToBot ||
376377
isMentioned ||
377378
(!this.runtime.character.clientConfig?.telegram
378-
?.shouldRespondOnlyToMentions &&
379+
?.shouldRespondOnlyToMentions &&
379380
hasUsername)
380381
);
381382
}
@@ -507,8 +508,8 @@ export class MessageManager {
507508
"text" in message
508509
? message.text
509510
: "caption" in message
510-
? (message as any).caption
511-
: "";
511+
? (message as any).caption
512+
: "";
512513

513514
// Check if team member has direct interest first
514515
if (
@@ -529,8 +530,8 @@ export class MessageManager {
529530
const randomDelay =
530531
Math.floor(
531532
Math.random() *
532-
(TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MAX -
533-
TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MIN)
533+
(TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MAX -
534+
TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MIN)
534535
) + TIMING_CONSTANTS.TEAM_MEMBER_DELAY_MIN; // 1-3 second random delay
535536
await new Promise((resolve) =>
536537
setTimeout(resolve, randomDelay)
@@ -556,8 +557,8 @@ export class MessageManager {
556557
const leaderResponded = recentMessages.some(
557558
(m) =>
558559
m.userId ===
559-
this.runtime.character.clientConfig?.telegram
560-
?.teamLeaderId &&
560+
this.runtime.character.clientConfig?.telegram
561+
?.teamLeaderId &&
561562
Date.now() - chatState.lastMessageSent < 3000
562563
);
563564

@@ -578,8 +579,8 @@ export class MessageManager {
578579
const randomDelay =
579580
Math.floor(
580581
Math.random() *
581-
(TIMING_CONSTANTS.LEADER_DELAY_MAX -
582-
TIMING_CONSTANTS.LEADER_DELAY_MIN)
582+
(TIMING_CONSTANTS.LEADER_DELAY_MAX -
583+
TIMING_CONSTANTS.LEADER_DELAY_MIN)
583584
) + TIMING_CONSTANTS.LEADER_DELAY_MIN; // 2-4 second random delay
584585
await new Promise((resolve) =>
585586
setTimeout(resolve, randomDelay)
@@ -617,7 +618,7 @@ export class MessageManager {
617618
if (chatState?.currentHandler) {
618619
if (
619620
chatState.currentHandler !==
620-
this.bot.botInfo?.id.toString() &&
621+
this.bot.botInfo?.id.toString() &&
621622
this._isTeamMember(chatState.currentHandler)
622623
) {
623624
return false;
@@ -628,7 +629,7 @@ export class MessageManager {
628629
if (!this._isMessageForMe(message) && this.interestChats[chatId]) {
629630
const recentMessages = this.interestChats[
630631
chatId
631-
].messages.slice(-MESSAGE_CONSTANTS.CHAT_HISTORY_COUNT);
632+
].messages.slice(-MESSAGE_CONSTANTS.CHAT_HISTORY_COUNT);
632633
const ourMessageCount = recentMessages.filter(
633634
(m) => m.userId === this.runtime.agentId
634635
).length;
@@ -660,7 +661,7 @@ export class MessageManager {
660661
this.runtime.character.templates
661662
?.telegramShouldRespondTemplate ||
662663
this.runtime.character?.templates?.shouldRespondTemplate ||
663-
composeRandomUser(telegramShouldRespondTemplate, 2),
664+
telegramShouldRespondTemplate,
664665
});
665666

666667
const response = await generateShouldRespond({
@@ -684,15 +685,25 @@ export class MessageManager {
684685
if (content.attachments && content.attachments.length > 0) {
685686
content.attachments.map(async (attachment: Media) => {
686687
if (attachment.contentType.startsWith("image")) {
687-
this.sendImage(ctx, attachment.url, attachment.description);
688+
await this.sendImage(ctx, attachment.url, attachment.description);
689+
} else if (attachment.contentType.startsWith("doc")) {
690+
await this.sendDocument(
691+
ctx,
692+
attachment.url,
693+
attachment.description
694+
);
695+
} else if (attachment.contentType.startsWith("video")) {
696+
await this.sendVideo(ctx, attachment.url, attachment.description);
697+
} else if (attachment.contentType.startsWith("audio")) {
698+
await this.sendAudio(ctx, attachment.url, attachment.description);
688699
}
689700
});
690701
} else {
691702
const chunks = this.splitMessage(content.text);
692703
const sentMessages: Message.TextMessage[] = [];
693704

694705
for (let i = 0; i < chunks.length; i++) {
695-
const chunk = escapeMarkdown(chunks[i]);
706+
const chunk = chunks[i];
696707
const sentMessage = (await ctx.telegram.sendMessage(
697708
ctx.chat.id,
698709
chunk,
@@ -712,42 +723,84 @@ export class MessageManager {
712723
}
713724
}
714725

715-
private async sendImage(
726+
private async sendMedia(
716727
ctx: Context,
717-
imagePath: string,
728+
mediaPath: string,
729+
type: "photo" | "video" | "document" | "audio",
718730
caption?: string
719731
): Promise<void> {
720732
try {
721-
if (/^(http|https):\/\//.test(imagePath)) {
733+
const isUrl = /^(http|https):\/\//.test(mediaPath);
734+
const sendFunctionMap = {
735+
photo: ctx.telegram.sendPhoto.bind(ctx.telegram),
736+
video: ctx.telegram.sendVideo.bind(ctx.telegram),
737+
document: ctx.telegram.sendDocument.bind(ctx.telegram),
738+
audio: ctx.telegram.sendAudio.bind(ctx.telegram),
739+
};
740+
741+
if (!sendFunctionMap[type]) {
742+
throw new Error(`Unsupported media type: ${type}`);
743+
}
744+
745+
const sendFunction = sendFunctionMap[type];
746+
747+
if (isUrl) {
722748
// Handle HTTP URLs
723-
await ctx.telegram.sendPhoto(ctx.chat.id, imagePath, {
724-
caption,
725-
});
749+
await sendFunction(ctx.chat.id, mediaPath, { caption });
726750
} else {
727751
// Handle local file paths
728-
if (!fs.existsSync(imagePath)) {
729-
throw new Error(`File not found: ${imagePath}`);
752+
if (!fs.existsSync(mediaPath)) {
753+
throw new Error(`File not found: ${mediaPath}`);
730754
}
731755

732-
const fileStream = fs.createReadStream(imagePath);
733-
734-
await ctx.telegram.sendPhoto(
756+
const fileStream = fs.createReadStream(mediaPath);
757+
await sendFunction(
735758
ctx.chat.id,
736-
{
737-
source: fileStream,
738-
},
739-
{
740-
caption,
741-
}
759+
{ source: fileStream },
760+
{ caption }
742761
);
743762
}
744763

745-
elizaLogger.info(`Image sent successfully: ${imagePath}`);
764+
elizaLogger.info(
765+
`${type.charAt(0).toUpperCase() + type.slice(1)} sent successfully: ${mediaPath}`
766+
);
746767
} catch (error) {
747-
elizaLogger.error("Error sending image:", error);
768+
elizaLogger.error(`Error sending ${type}:`, error);
748769
}
749770
}
750771

772+
private async sendImage(
773+
ctx: Context,
774+
imagePath: string,
775+
caption?: string
776+
): Promise<void> {
777+
await this.sendMedia(ctx, imagePath, "photo", caption);
778+
}
779+
780+
private async sendVideo(
781+
ctx: Context,
782+
videoPath: string,
783+
caption?: string
784+
): Promise<void> {
785+
await this.sendMedia(ctx, videoPath, "video", caption);
786+
}
787+
788+
private async sendDocument(
789+
ctx: Context,
790+
documentPath: string,
791+
caption?: string
792+
): Promise<void> {
793+
await this.sendMedia(ctx, documentPath, "document", caption);
794+
}
795+
796+
private async sendAudio(
797+
ctx: Context,
798+
audioPath: string,
799+
caption?: string
800+
): Promise<void> {
801+
await this.sendMedia(ctx, audioPath, "audio", caption);
802+
}
803+
751804
// Split message into smaller parts
752805
private splitMessage(text: string): string[] {
753806
const chunks: string[] = [];
@@ -823,8 +876,8 @@ export class MessageManager {
823876
"text" in message
824877
? message.text
825878
: "caption" in message
826-
? (message as any).caption
827-
: "";
879+
? (message as any).caption
880+
: "";
828881

829882
// Add team handling at the start
830883
if (
@@ -914,7 +967,7 @@ export class MessageManager {
914967
if (
915968
hasInterest ||
916969
this.interestChats[chatId]?.currentHandler ===
917-
this.bot.botInfo?.id.toString()
970+
this.bot.botInfo?.id.toString()
918971
) {
919972
delete this.interestChats[chatId];
920973

@@ -953,7 +1006,7 @@ export class MessageManager {
9531006
) {
9541007
this.interestChats[chatId].messages = this.interestChats[
9551008
chatId
956-
].messages.slice(-MESSAGE_CONSTANTS.MAX_MESSAGES);
1009+
].messages.slice(-MESSAGE_CONSTANTS.MAX_MESSAGES);
9571010
}
9581011
}
9591012
}
@@ -1018,10 +1071,10 @@ export class MessageManager {
10181071
inReplyTo:
10191072
"reply_to_message" in message && message.reply_to_message
10201073
? stringToUuid(
1021-
message.reply_to_message.message_id.toString() +
1022-
"-" +
1023-
this.runtime.agentId
1024-
)
1074+
message.reply_to_message.message_id.toString() +
1075+
"-" +
1076+
this.runtime.agentId
1077+
)
10251078
: undefined,
10261079
};
10271080

@@ -1084,8 +1137,8 @@ export class MessageManager {
10841137
const memory: Memory = {
10851138
id: stringToUuid(
10861139
sentMessage.message_id.toString() +
1087-
"-" +
1088-
this.runtime.agentId
1140+
"-" +
1141+
this.runtime.agentId
10891142
),
10901143
agentId,
10911144
userId: agentId,

0 commit comments

Comments
 (0)