Skip to content

Commit

Permalink
enable image tweet on twitter
Browse files Browse the repository at this point in the history
  • Loading branch information
tcm390 committed Dec 13, 2024
1 parent 9192179 commit 0c13bfe
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 2 deletions.
3 changes: 2 additions & 1 deletion packages/client-twitter/src/interactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,8 @@ export class TwitterInteractionClient {
await this.runtime.processActions(
message,
responseMessages,
state
state,
callback
);

const responseInfo = `Context:\n\n${context}\n\nSelected Post: ${tweet.id} - ${tweet.username}: ${tweet.text}\nAgent's Output:\n${response.text}`;
Expand Down
46 changes: 45 additions & 1 deletion packages/client-twitter/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { stringToUuid } from "@ai16z/eliza";
import { ClientBase } from "./base";
import { elizaLogger } from "@ai16z/eliza";
import { DEFAULT_MAX_TWEET_LENGTH } from "./environment";
import fs from "fs";
import path from "path";

export const wait = (minTime: number = 1000, maxTime: number = 3000) => {
const waitTime =
Expand Down Expand Up @@ -162,6 +164,28 @@ export async function buildConversationThread(
return thread;
}

export function getMediaType(filePath: string) {
const extension = filePath.split('.').pop().toLowerCase();
switch (extension) {
case 'png':
case 'jpg':
case 'jpeg':
return 'image';
case 'mp4':
return 'video';
default:
throw new Error(`Unsupported media type: ${extension}`);
}
}
type Attachment = {
id: string;
url: string; // Path to the file
title?: string;
source?: string;
description?: string;
text?: string;
};

export async function sendTweet(
client: ClientBase,
content: Content,
Expand All @@ -178,11 +202,31 @@ export async function sendTweet(
let previousTweetId = inReplyTo;

for (const chunk of tweetChunks) {
let mediaData: { data: Buffer; mediaType: string }[] | undefined;

if (content.attachments && content.attachments.length > 0) {
mediaData = await Promise.all(
content.attachments.map(async (attachment:Attachment) => {
if (fs.existsSync(attachment.url)) {
const mediaBuffer = await fs.promises.readFile(
path.resolve(attachment.url)
);
const mediaType = getMediaType(attachment.url);
return { data: mediaBuffer, mediaType };
} else {
throw new Error(
`File not found: ${attachment.url}. Make sure the path is correct.`
);
}
})
);
}
const result = await client.requestQueue.add(
async () =>
await client.twitterClient.sendTweet(
chunk.trim(),
previousTweetId
previousTweetId,
mediaData
)
);
const body = await result.json();
Expand Down

5 comments on commit 0c13bfe

@ShreyGanatra
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add for PostTweet also?

@tcm390
Copy link
Collaborator Author

@tcm390 tcm390 commented on 0c13bfe Jan 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing 😊 is it possible to make an issue for it?

@ShreyGanatra
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did it... actually there is lot of repeated code in post.ts, utils.ts and interactions.ts

@ShreyGanatra
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had to modify the promptTemplate so that the response has action GENERATE_IMAGE

@yohairosen
Copy link

@yohairosen yohairosen commented on 0c13bfe Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, do you mean like that?

const twitterPostTemplate = `
# Areas of Expertise
{{knowledge}}

# About {{agentName}} (@{{twitterUserName}}):
{{bio}}
{{lore}}
{{topics}}

{{providers}}

{{characterPostExamples}}

{{postDirections}}

# Task: Generate a post in the voice and style and perspective of {{agentName}} @{{twitterUserName}}.
Write a post that is {{adjective}} about {{topic}} (without mentioning {{topic}} directly), from the perspective of {{agentName}}. Do not add commentary or acknowledge this request, just write the post.
Your response should be 1, 2, or 3 sentences (choose the length at random).
Your response should not contain any questions. Brief, concise statements only. The total character count MUST be less than {{maxTweetLength}}. No emojis. Use \\n\\n (double spaces) between statements if there are multiple statements in your response.

[GENERATE_IMAGE]
`;

Please sign in to comment.