Skip to content

Commit

Permalink
fix: remove twitter profile caching (elizaOS#1638)
Browse files Browse the repository at this point in the history
  • Loading branch information
augchan42 committed Jan 4, 2025
1 parent cddc9ee commit 6df4ea6
Showing 1 changed file with 49 additions and 61 deletions.
110 changes: 49 additions & 61 deletions packages/client-twitter/src/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export class ClientBase extends EventEmitter {
);
}

constructor(runtime: IAgentRuntime, twitterConfig:TwitterConfig) {
constructor(runtime: IAgentRuntime, twitterConfig: TwitterConfig) {
super();
this.runtime = runtime;
this.twitterConfig = twitterConfig;
Expand All @@ -159,7 +159,7 @@ export class ClientBase extends EventEmitter {
const username = this.twitterConfig.TWITTER_USERNAME;
const password = this.twitterConfig.TWITTER_PASSWORD;
const email = this.twitterConfig.TWITTER_EMAIL;
let retries = this.twitterConfig.TWITTER_RETRY_LIMIT
let retries = this.twitterConfig.TWITTER_RETRY_LIMIT;
const twitter2faSecret = this.twitterConfig.TWITTER_2FA_SECRET;

if (!username) {
Expand All @@ -176,7 +176,8 @@ export class ClientBase extends EventEmitter {
elizaLogger.log("Waiting for Twitter login");
while (retries > 0) {
try {
if (await this.twitterClient.isLoggedIn()) { // cookies are valid, no login required
if (await this.twitterClient.isLoggedIn()) {
// cookies are valid, no login required
elizaLogger.info("Successfully logged in.");
break;
} else {
Expand All @@ -186,7 +187,8 @@ export class ClientBase extends EventEmitter {
email,
twitter2faSecret
);
if (await this.twitterClient.isLoggedIn()) { // fresh login, store new cookies
if (await this.twitterClient.isLoggedIn()) {
// fresh login, store new cookies
elizaLogger.info("Successfully logged in.");
elizaLogger.info("Caching cookies");
await this.cacheCookies(
Expand Down Expand Up @@ -251,7 +253,10 @@ export class ClientBase extends EventEmitter {
/**
* Fetch timeline for twitter account, optionally only from followed accounts
*/
async fetchHomeTimeline(count: number, following?: boolean): Promise<Tweet[]> {
async fetchHomeTimeline(
count: number,
following?: boolean
): Promise<Tweet[]> {
elizaLogger.debug("fetching home timeline");
const homeTimeline = following
? await this.twitterClient.fetchFollowingTimeline(count, [])
Expand Down Expand Up @@ -288,13 +293,14 @@ export class ClientBase extends EventEmitter {
hashtags: tweet.hashtags ?? tweet.legacy?.entities.hashtags,
mentions:
tweet.mentions ?? tweet.legacy?.entities.user_mentions,
photos: tweet.legacy?.entities?.media?.filter(
(media) => media.type === "photo"
).map(media => ({
id: media.id_str,
url: media.media_url_https, // Store media_url_https as url
alt_text: media.alt_text
})) || [],
photos:
tweet.legacy?.entities?.media
?.filter((media) => media.type === "photo")
.map((media) => ({
id: media.id_str,
url: media.media_url_https, // Store media_url_https as url
alt_text: media.alt_text,
})) || [],
thread: tweet.thread || [],
urls: tweet.urls ?? tweet.legacy?.entities.urls,
videos:
Expand All @@ -314,38 +320,41 @@ export class ClientBase extends EventEmitter {
async fetchTimelineForActions(count: number): Promise<Tweet[]> {
elizaLogger.debug("fetching timeline for actions");

const agentUsername = this.twitterConfig.TWITTER_USERNAME
const agentUsername = this.twitterConfig.TWITTER_USERNAME;
const homeTimeline = await this.twitterClient.fetchHomeTimeline(
count,
[]
);

return homeTimeline.map((tweet) => ({
id: tweet.rest_id,
name: tweet.core?.user_results?.result?.legacy?.name,
username: tweet.core?.user_results?.result?.legacy?.screen_name,
text: tweet.legacy?.full_text,
inReplyToStatusId: tweet.legacy?.in_reply_to_status_id_str,
timestamp: new Date(tweet.legacy?.created_at).getTime() / 1000,
userId: tweet.legacy?.user_id_str,
conversationId: tweet.legacy?.conversation_id_str,
permanentUrl: `https://twitter.com/${tweet.core?.user_results?.result?.legacy?.screen_name}/status/${tweet.rest_id}`,
hashtags: tweet.legacy?.entities?.hashtags || [],
mentions: tweet.legacy?.entities?.user_mentions || [],
photos: tweet.legacy?.entities?.media?.filter(
(media) => media.type === "photo"
).map(media => ({
id: media.id_str,
url: media.media_url_https, // Store media_url_https as url
alt_text: media.alt_text
})) || [],
thread: tweet.thread || [],
urls: tweet.legacy?.entities?.urls || [],
videos:
tweet.legacy?.entities?.media?.filter(
(media) => media.type === "video"
) || [],
})).filter(tweet => tweet.username !== agentUsername); // do not perform action on self-tweets
return homeTimeline
.map((tweet) => ({
id: tweet.rest_id,
name: tweet.core?.user_results?.result?.legacy?.name,
username: tweet.core?.user_results?.result?.legacy?.screen_name,
text: tweet.legacy?.full_text,
inReplyToStatusId: tweet.legacy?.in_reply_to_status_id_str,
timestamp: new Date(tweet.legacy?.created_at).getTime() / 1000,
userId: tweet.legacy?.user_id_str,
conversationId: tweet.legacy?.conversation_id_str,
permanentUrl: `https://twitter.com/${tweet.core?.user_results?.result?.legacy?.screen_name}/status/${tweet.rest_id}`,
hashtags: tweet.legacy?.entities?.hashtags || [],
mentions: tweet.legacy?.entities?.user_mentions || [],
photos:
tweet.legacy?.entities?.media
?.filter((media) => media.type === "photo")
.map((media) => ({
id: media.id_str,
url: media.media_url_https, // Store media_url_https as url
alt_text: media.alt_text,
})) || [],
thread: tweet.thread || [],
urls: tweet.legacy?.entities?.urls || [],
videos:
tweet.legacy?.entities?.media?.filter(
(media) => media.type === "video"
) || [],
}))
.filter((tweet) => tweet.username !== agentUsername); // do not perform action on self-tweets
}

async fetchSearchTweets(
Expand Down Expand Up @@ -720,28 +729,10 @@ export class ClientBase extends EventEmitter {
);
}

async getCachedProfile(username: string) {
return await this.runtime.cacheManager.get<TwitterProfile>(
`twitter/${username}/profile`
);
}

async cacheProfile(profile: TwitterProfile) {
await this.runtime.cacheManager.set(
`twitter/${profile.username}/profile`,
profile
);
}

async fetchProfile(username: string): Promise<TwitterProfile> {
const cached = await this.getCachedProfile(username);

if (cached) return cached;

try {
const profile = await this.requestQueue.add(async () => {
const profile = await this.twitterClient.getProfile(username);
// console.log({ profile });
return {
id: profile.userId,
username,
Expand All @@ -758,13 +749,10 @@ export class ClientBase extends EventEmitter {
} satisfies TwitterProfile;
});

this.cacheProfile(profile);

return profile;
} catch (error) {
console.error("Error fetching Twitter profile:", error);

return undefined;
throw error;
}
}
}

0 comments on commit 6df4ea6

Please sign in to comment.