From b3e589c520c99c0818c0948a211c562947b27fd0 Mon Sep 17 00:00:00 2001 From: Travis Fischer Date: Tue, 4 Jun 2024 22:27:07 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/scratch.ts | 10 +++-- src/services/twitter/twitter-client.ts | 62 +++++++++++++++++++++++--- src/services/twitter/types.ts | 4 ++ 3 files changed, 65 insertions(+), 11 deletions(-) diff --git a/bin/scratch.ts b/bin/scratch.ts index bdc394d..46fbde3 100644 --- a/bin/scratch.ts +++ b/bin/scratch.ts @@ -87,12 +87,14 @@ async function main() { // console.log(res) const client = await createTwitterV2Client({ - // scopes: ['tweet.read', 'users.read', 'offline.access'] + scopes: ['tweet.read', 'users.read', 'offline.access'] }) const twitter = new TwitterClient({ client }) - - const user = await twitter.findUserByUsername({ username: 'transitive_bs' }) - console.log(user) + // const res = await twitter.findUserByUsername({ username: 'transitive_bs' }) + const res = await twitter.searchRecentTweets({ + query: 'open source AI agents' + }) + console.log(res) } try { diff --git a/src/services/twitter/twitter-client.ts b/src/services/twitter/twitter-client.ts index 7d72c2e..8c7ac9d 100644 --- a/src/services/twitter/twitter-client.ts +++ b/src/services/twitter/twitter-client.ts @@ -23,6 +23,7 @@ type TwitterApiMethod = | 'usersIdMentions' | 'findTweetById' | 'findTweetsById' + | 'searchRecentTweets' | 'findUserById' | 'findUserByUsername' @@ -47,15 +48,9 @@ const twitterApiRateLimitsByPlan: Record< // TODO: according to the twitter docs, this shouldn't be allowed on the // free plan, but it seems to work... usersIdMentions: { limit: 1, interval: FIFTEEN_MINUTES_MS }, - - // TODO: according to the twitter docs, this shouldn't be allowed on the - // free plan, but it seems to work... findTweetById: { limit: 1, interval: FIFTEEN_MINUTES_MS }, - - // TODO: according to the twitter docs, this shouldn't be allowed on the - // free plan, but it seems to work... findTweetsById: { limit: 1, interval: FIFTEEN_MINUTES_MS }, - + searchRecentTweets: { limit: 1, interval: FIFTEEN_MINUTES_MS }, findUserById: { limit: 1, interval: FIFTEEN_MINUTES_MS }, findUserByUsername: { limit: 1, interval: FIFTEEN_MINUTES_MS } }, @@ -76,6 +71,10 @@ const twitterApiRateLimitsByPlan: Record< findTweetById: { limit: 15, interval: FIFTEEN_MINUTES_MS }, findTweetsById: { limit: 15, interval: FIFTEEN_MINUTES_MS }, + // 60 per 15m per user + // 60 per 15m per app + searchRecentTweets: { limit: 60, interval: FIFTEEN_MINUTES_MS }, + findUserById: { limit: 100, interval: TWENTY_FOUR_HOURS_MS }, findUserByUsername: { limit: 100, interval: TWENTY_FOUR_HOURS_MS } }, @@ -95,6 +94,11 @@ const twitterApiRateLimitsByPlan: Record< findTweetById: { limit: 450, interval: FIFTEEN_MINUTES_MS }, findTweetsById: { limit: 450, interval: FIFTEEN_MINUTES_MS }, + // TODO: why would the per-user rate-limit be less than the per-app one?! + // 456 per 15m per user + // 300 per 15m per app + searchRecentTweets: { limit: 300, interval: FIFTEEN_MINUTES_MS }, + findUserById: { limit: 300, interval: FIFTEEN_MINUTES_MS }, findUserByUsername: { limit: 300, interval: FIFTEEN_MINUTES_MS } }, @@ -107,6 +111,7 @@ const twitterApiRateLimitsByPlan: Record< usersIdMentions: { limit: 1800, interval: FIFTEEN_MINUTES_MS }, findTweetById: { limit: 4500, interval: FIFTEEN_MINUTES_MS }, findTweetsById: { limit: 4500, interval: FIFTEEN_MINUTES_MS }, + searchRecentTweets: { limit: 3000, interval: FIFTEEN_MINUTES_MS }, findUserById: { limit: 3000, interval: FIFTEEN_MINUTES_MS }, findUserByUsername: { limit: 3000, interval: FIFTEEN_MINUTES_MS } } @@ -143,6 +148,9 @@ export class TwitterClient extends AIFunctionsProvider { const findTweetsByIdThrottle = pThrottle( twitterApiRateLimits.findTweetsById ) + const searchRecentTweetsThrottle = pThrottle( + twitterApiRateLimits.searchRecentTweets + ) const findUserByIdThrottle = pThrottle(twitterApiRateLimits.findUserById) const findUserByUsernameThrottle = pThrottle( twitterApiRateLimits.findUserByUsername @@ -153,6 +161,9 @@ export class TwitterClient extends AIFunctionsProvider { this._findTweetsById = findTweetsByIdThrottle( findTweetsByIdImpl(this.client) ) + this._searchRecentTweets = searchRecentTweetsThrottle( + searchRecentTweetsImpl(this.client) + ) this._findUserById = findUserByIdThrottle(findUserByIdImpl(this.client)) this._findUserByUsername = findUserByUsernameThrottle( findUserByUsernameImpl(this.client) @@ -162,6 +173,7 @@ export class TwitterClient extends AIFunctionsProvider { protected _createTweet: ReturnType protected _findTweetById: ReturnType protected _findTweetsById: ReturnType + protected _searchRecentTweets: ReturnType protected _findUserById: ReturnType protected _findUserByUsername: ReturnType @@ -213,6 +225,26 @@ export class TwitterClient extends AIFunctionsProvider { return this._findTweetsById(ids, params) } + @aiFunction({ + name: 'search_recent_tweets', + description: 'Searches for recent tweets', + inputSchema: z.object({ + query: z.string().min(1), + sort_order: z + .enum(['recency', 'relevancy']) + .default('relevancy') + .optional() + }) + }) + async searchRecentTweets(params: types.SearchRecentTweetsParams) { + assert( + this.twitterApiPlan !== 'free', + 'TwitterClient.searchRecentTweets not supported on free plan' + ) + + return this._searchRecentTweets(params) + } + @aiFunction({ name: 'get_twitter_user_by_id', description: 'Fetch a twitter user by ID', @@ -372,6 +404,22 @@ function findTweetsByIdImpl(client: types.TwitterV2Client) { } } +function searchRecentTweetsImpl(client: types.TwitterV2Client) { + return async (params: types.SearchRecentTweetsParams) => { + try { + return await client.tweets.tweetsRecentSearch({ + ...defaultTweetQueryParams, + ...params + }) + } catch (err: any) { + handleKnownTwitterErrors(err, { + label: `searching tweets query "${params.query}"` + }) + throw err + } + } +} + function findUserByIdImpl(client: types.TwitterV2Client) { return async (userId: string, params?: types.FindUserByIdParams) => { try { diff --git a/src/services/twitter/types.ts b/src/services/twitter/types.ts index 4ee2893..18ebbad 100644 --- a/src/services/twitter/types.ts +++ b/src/services/twitter/types.ts @@ -42,6 +42,10 @@ export type FindTweetsByIdParams = Simplify< Parameters[0] > +export type SearchRecentTweetsParams = Simplify< + Parameters[0] +> + export type FindUserByIdParams = Simplify< Parameters[1] >