62 lines
1.6 KiB
TypeScript
62 lines
1.6 KiB
TypeScript
|
|
import { rankAndDedupe, type RankedPost, type RawPost } from "@/lib/ranking";
|
||
|
|
import { threadsGraphGet } from "./client";
|
||
|
|
import type { ThreadsApiCredentials } from "./types";
|
||
|
|
|
||
|
|
interface ThreadsSearchItem {
|
||
|
|
id?: string;
|
||
|
|
text?: string;
|
||
|
|
permalink?: string;
|
||
|
|
username?: string;
|
||
|
|
timestamp?: string;
|
||
|
|
like_count?: number;
|
||
|
|
reply_count?: number;
|
||
|
|
repost_count?: number;
|
||
|
|
quote_count?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
interface ThreadsSearchResponse {
|
||
|
|
data?: ThreadsSearchItem[];
|
||
|
|
paging?: {
|
||
|
|
next?: string;
|
||
|
|
cursors?: { after?: string };
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
function toRawPost(item: ThreadsSearchItem): RawPost | null {
|
||
|
|
if (!item.text?.trim()) return null;
|
||
|
|
|
||
|
|
return {
|
||
|
|
externalId: item.id,
|
||
|
|
text: item.text.trim(),
|
||
|
|
permalink: item.permalink,
|
||
|
|
authorName: item.username,
|
||
|
|
postedAt: item.timestamp ? new Date(item.timestamp) : undefined,
|
||
|
|
likeCount: item.like_count,
|
||
|
|
replyCount: item.reply_count,
|
||
|
|
repostCount: item.repost_count,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function keywordSearchViaThreadsApi(
|
||
|
|
credentials: ThreadsApiCredentials,
|
||
|
|
input: {
|
||
|
|
query: string;
|
||
|
|
limit?: number;
|
||
|
|
searchType?: "TOP" | "RECENT";
|
||
|
|
}
|
||
|
|
): Promise<RankedPost[]> {
|
||
|
|
const json = await threadsGraphGet<ThreadsSearchResponse>("/keyword_search", {
|
||
|
|
access_token: credentials.accessToken,
|
||
|
|
q: input.query,
|
||
|
|
search_type: input.searchType ?? "TOP",
|
||
|
|
fields:
|
||
|
|
"id,text,permalink,username,timestamp,like_count,reply_count,repost_count,quote_count",
|
||
|
|
});
|
||
|
|
|
||
|
|
const posts = (json.data ?? [])
|
||
|
|
.map(toRawPost)
|
||
|
|
.filter((post): post is RawPost => !!post);
|
||
|
|
|
||
|
|
return rankAndDedupe(posts, input.limit ?? 20);
|
||
|
|
}
|