Skip to content

Commit 392efc6

Browse files
authored
Merge pull request #1220 from ai16z/tcm-telegram-image
fix: Allow the bot to post messages with images generated by the imageGenerationPlugin on Telegram.
2 parents d3d6198 + cd5fc2f commit 392efc6

File tree

3 files changed

+109
-67
lines changed

3 files changed

+109
-67
lines changed

packages/client-telegram/src/messageManager.ts

+106-54
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
ModelClass,
1313
State,
1414
UUID,
15+
Media,
1516
} from "@ai16z/eliza";
1617
import { stringToUuid } from "@ai16z/eliza";
1718

@@ -26,6 +27,8 @@ import {
2627
TEAM_COORDINATION
2728
} from "./constants";
2829

30+
import fs from "fs";
31+
2932
const MAX_MESSAGE_LENGTH = 4096; // Telegram's max message length
3033

3134
const telegramShouldRespondTemplate =
@@ -580,29 +583,77 @@ export class MessageManager {
580583
// Send long messages in chunks
581584
private async sendMessageInChunks(
582585
ctx: Context,
583-
content: string,
586+
content: Content,
584587
replyToMessageId?: number
585588
): Promise<Message.TextMessage[]> {
586-
const chunks = this.splitMessage(content);
587-
const sentMessages: Message.TextMessage[] = [];
588-
589-
for (let i = 0; i < chunks.length; i++) {
590-
const chunk = chunks[i];
591-
const sentMessage = (await ctx.telegram.sendMessage(
592-
ctx.chat.id,
593-
chunk,
594-
{
595-
reply_parameters:
596-
i === 0 && replyToMessageId
597-
? { message_id: replyToMessageId }
598-
: undefined,
589+
if (content.attachments && content.attachments.length > 0) {
590+
content.attachments.map(async (attachment: Media) => {
591+
if (attachment.contentType.startsWith("image")) {
592+
this.sendImage(ctx, attachment.url, attachment.description);
599593
}
600-
)) as Message.TextMessage;
594+
});
595+
} else {
596+
const chunks = this.splitMessage(content.text);
597+
const sentMessages: Message.TextMessage[] = [];
598+
599+
for (let i = 0; i < chunks.length; i++) {
600+
const chunk = chunks[i];
601+
const sentMessage = (await ctx.telegram.sendMessage(
602+
ctx.chat.id,
603+
chunk,
604+
{
605+
reply_parameters:
606+
i === 0 && replyToMessageId
607+
? { message_id: replyToMessageId }
608+
: undefined,
609+
}
610+
)) as Message.TextMessage;
611+
612+
sentMessages.push(sentMessage);
613+
}
601614

602-
sentMessages.push(sentMessage);
615+
return sentMessages;
603616
}
617+
}
604618

605-
return sentMessages;
619+
private async sendImage(
620+
ctx: Context,
621+
imagePath: string,
622+
caption?: string
623+
): Promise<void> {
624+
try {
625+
if (/^(http|https):\/\//.test(imagePath)) {
626+
// Handle HTTP URLs
627+
await ctx.telegram.sendPhoto(
628+
ctx.chat.id,
629+
imagePath,
630+
{
631+
caption,
632+
}
633+
);
634+
} else {
635+
// Handle local file paths
636+
if (!fs.existsSync(imagePath)) {
637+
throw new Error(`File not found: ${imagePath}`);
638+
}
639+
640+
const fileStream = fs.createReadStream(imagePath);
641+
642+
await ctx.telegram.sendPhoto(
643+
ctx.chat.id,
644+
{
645+
source: fileStream,
646+
},
647+
{
648+
caption,
649+
}
650+
);
651+
}
652+
653+
elizaLogger.info(`Image sent successfully: ${imagePath}`);
654+
} catch (error) {
655+
elizaLogger.error("Error sending image:", error);
656+
}
606657
}
607658

608659
// Split message into smaller parts
@@ -906,46 +957,47 @@ export class MessageManager {
906957
const callback: HandlerCallback = async (content: Content) => {
907958
const sentMessages = await this.sendMessageInChunks(
908959
ctx,
909-
content.text,
960+
content,
910961
message.message_id
911962
);
912-
913-
const memories: Memory[] = [];
914-
915-
// Create memories for each sent message
916-
for (let i = 0; i < sentMessages.length; i++) {
917-
const sentMessage = sentMessages[i];
918-
const isLastMessage = i === sentMessages.length - 1;
919-
920-
const memory: Memory = {
921-
id: stringToUuid(
922-
sentMessage.message_id.toString() +
923-
"-" +
924-
this.runtime.agentId
925-
),
926-
agentId,
927-
userId: agentId,
928-
roomId,
929-
content: {
930-
...content,
931-
text: sentMessage.text,
932-
inReplyTo: messageId,
933-
},
934-
createdAt: sentMessage.date * 1000,
935-
embedding: getEmbeddingZeroVector(),
936-
};
937-
938-
// Set action to CONTINUE for all messages except the last one
939-
// For the last message, use the original action from the response content
940-
memory.content.action = !isLastMessage
941-
? "CONTINUE"
942-
: content.action;
943-
944-
await this.runtime.messageManager.createMemory(memory);
945-
memories.push(memory);
963+
if (sentMessages) {
964+
const memories: Memory[] = [];
965+
966+
// Create memories for each sent message
967+
for (let i = 0; i < sentMessages.length; i++) {
968+
const sentMessage = sentMessages[i];
969+
const isLastMessage = i === sentMessages.length - 1;
970+
971+
const memory: Memory = {
972+
id: stringToUuid(
973+
sentMessage.message_id.toString() +
974+
"-" +
975+
this.runtime.agentId
976+
),
977+
agentId,
978+
userId: agentId,
979+
roomId,
980+
content: {
981+
...content,
982+
text: sentMessage.text,
983+
inReplyTo: messageId,
984+
},
985+
createdAt: sentMessage.date * 1000,
986+
embedding: getEmbeddingZeroVector(),
987+
};
988+
989+
// Set action to CONTINUE for all messages except the last one
990+
// For the last message, use the original action from the response content
991+
memory.content.action = !isLastMessage
992+
? "CONTINUE"
993+
: content.action;
994+
995+
await this.runtime.messageManager.createMemory(memory);
996+
memories.push(memory);
997+
}
998+
999+
return memories;
9461000
}
947-
948-
return memories;
9491001
};
9501002

9511003
// Execute callback to send messages and log memories

packages/client-twitter/src/utils.ts

+2-12
Original file line numberDiff line numberDiff line change
@@ -165,16 +165,6 @@ export async function buildConversationThread(
165165
return thread;
166166
}
167167

168-
export function getMediaType(attachment: Media) {
169-
if (attachment.contentType?.startsWith("video")) {
170-
return "video";
171-
} else if (attachment.contentType?.startsWith("image")) {
172-
return "image";
173-
} else {
174-
throw new Error(`Unsupported media type`);
175-
}
176-
}
177-
178168
export async function sendTweet(
179169
client: ClientBase,
180170
content: Content,
@@ -207,14 +197,14 @@ export async function sendTweet(
207197
const mediaBuffer = Buffer.from(
208198
await response.arrayBuffer()
209199
);
210-
const mediaType = getMediaType(attachment);
200+
const mediaType = attachment.contentType;
211201
return { data: mediaBuffer, mediaType };
212202
} else if (fs.existsSync(attachment.url)) {
213203
// Handle local file paths
214204
const mediaBuffer = await fs.promises.readFile(
215205
path.resolve(attachment.url)
216206
);
217-
const mediaType = getMediaType(attachment);
207+
const mediaType = attachment.contentType;
218208
return { data: mediaBuffer, mediaType };
219209
} else {
220210
throw new Error(

packages/plugin-image-generation/src/index.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ const imageGeneration: Action = {
207207
source: "imageGeneration",
208208
description: "...", //caption.title,
209209
text: "...", //caption.description,
210-
contentType: "image",
210+
contentType: "image/png",
211211
},
212212
],
213213
},

0 commit comments

Comments
 (0)