MCPcopy
hub / github.com/virattt/dexter / searchTweets

Function searchTweets

src/tools/search/x-search.ts:121–165  ·  view source on GitHub ↗
(
  query: string,
  opts: {
    pages?: number;
    maxResults?: number;
    sortOrder?: 'relevancy' | 'recency';
    since?: string;
  } = {},
)

Source from the content-addressed store, hash-verified

119}
120
121async function searchTweets(
122 query: string,
123 opts: {
124 pages?: number;
125 maxResults?: number;
126 sortOrder?: 'relevancy' | 'recency';
127 since?: string;
128 } = {},
129): Promise<XTweet[]> {
130 const pages = Math.min(opts.pages ?? 1, 5);
131 const maxResults = Math.max(Math.min(opts.maxResults ?? 100, 100), 10);
132 const sort = opts.sortOrder ?? 'relevancy';
133 const encoded = encodeURIComponent(query);
134
135 let timeFilter = '';
136 if (opts.since) {
137 const startTime = parseSince(opts.since);
138 if (startTime) timeFilter = `&start_time=${startTime}`;
139 }
140
141 const allTweets: XTweet[] = [];
142 let nextToken: string | undefined;
143
144 for (let page = 0; page < pages; page++) {
145 const pagination = nextToken ? `&pagination_token=${nextToken}` : '';
146 const url =
147 `${X_API_BASE}/tweets/search/recent?query=${encoded}` +
148 `&max_results=${maxResults}&${TWEET_FIELDS}` +
149 `&sort_order=${sort}${timeFilter}${pagination}`;
150
151 const raw = await xApiGet(url);
152 allTweets.push(...parseTweets(raw));
153 nextToken = raw.meta?.next_token;
154 if (!nextToken) break;
155 if (page < pages - 1) await sleep(RATE_DELAY_MS);
156 }
157
158 // Deduplicate
159 const seen = new Set<string>();
160 return allTweets.filter((t) => {
161 if (seen.has(t.id)) return false;
162 seen.add(t.id);
163 return true;
164 });
165}
166
167async function getProfile(
168 username: string,

Callers 3

getProfileFunction · 0.85
getThreadFunction · 0.85
x-search.tsFile · 0.85

Calls 5

parseSinceFunction · 0.85
xApiGetFunction · 0.85
parseTweetsFunction · 0.85
sleepFunction · 0.85
addMethod · 0.45

Tested by

no test coverage detected