import { searchParams } from "https://esm.town/v/stevekrouse/searchParams";
import { twitterJSON } from "https://esm.town/v/stevekrouse/twitterJSON";
import { twitterUser } from "https://esm.town/v/stevekrouse/twitterUser";
export async function twitterSearch({
query,
start_time,
bearerToken,
...rest
}: {
query?: string;
start_time?: Date;
bearerToken: string;
}): Promise<TweetResult[]> {
const res = await twitterJSON({
url: `https://api.twitter.com/2/tweets/search/recent?query=${await searchParams(
{
query,
start_time: start_time?.toISOString(),
expansions: ["author_id"],
["tweet.fields"]: ["public_metrics", "referenced_tweets"],
...rest,
},
)}`,
bearerToken: bearerToken,
});
if (res.errors) {
console.error("twitterSearch error", JSON.stringify(res));
throw new Error(JSON.stringify(res.errors));
}
return Promise.all(
(res.data || []).map(async (tweet) => {
const { data: author } = await twitterUser({
id: tweet.author_id,
bearerToken,
});
return {
...tweet,
author_name: author?.name,
author_username: author?.username,
public_metrics: tweet.public_metrics,
referenced_tweets: tweet.referenced_tweets,
is_retweet: tweet.referenced_tweets?.some(ref => ref.type === "retweeted") ?? false,
is_reply: tweet.referenced_tweets?.some(ref => ref.type === "replied_to") ?? false,
is_quote: tweet.referenced_tweets?.some(ref => ref.type === "quoted") ?? false,
};
}),
);
}
interface TweetResult {
author_id: string;
text: string;
id: string;
edit_history_tweet_ids: string[];
author_name?: string;
author_username?: string;
public_metrics?: {
retweet_count: number;
reply_count: number;
like_count: number;
quote_count: number;
};
referenced_tweets?: {
type: "retweeted" | "quoted" | "replied_to";
id: string;
}[];
is_retweet?: boolean;
is_reply?: boolean;
is_quote?: boolean;
}