import { Converter } from "megalodon"; import Router from "@koa/router"; import axios from "axios"; import { argsToBools, convertPaginationArgsIds, limitToInt, normalizeUrlQuery } from "./timeline.js"; import { convertAccountId, convertSearchIds, convertStatusIds } from "../converters.js"; import authenticate from "@/server/api/authenticate.js"; import { UserHelpers } from "@/server/api/mastodon/helpers/user.js"; import { SearchHelpers } from "@/server/api/mastodon/helpers/search.js"; export function setupEndpointsSearch(router: Router): void { router.get("/v1/search", async (ctx) => { try { const auth = await authenticate(ctx.headers.authorization, null); const user = auth[0] ?? undefined; if (!user) { ctx.status = 401; return; } const args = normalizeUrlQuery(convertPaginationArgsIds(argsToBools(limitToInt(ctx.query), ['resolve', 'following', 'exclude_unreviewed']))); const cache = UserHelpers.getFreshAccountCache(); const result = await SearchHelpers.search(user, args.q, args.type, args.resolve, args.following, args.account_id, args['exclude_unreviewed'], args.max_id, args.min_id, args.limit, args.offset, cache); ctx.body = { ...convertSearchIds(result), hashtags: result.hashtags.map(p => p.name), }; } catch (e: any) { console.error(e); ctx.status = 400; ctx.body = {error: e.message}; } }); router.get("/v2/search", async (ctx) => { try { const auth = await authenticate(ctx.headers.authorization, null); const user = auth[0] ?? undefined; if (!user) { ctx.status = 401; return; } const args = normalizeUrlQuery(convertPaginationArgsIds(argsToBools(limitToInt(ctx.query), ['resolve', 'following', 'exclude_unreviewed']))); const cache = UserHelpers.getFreshAccountCache(); const result = await SearchHelpers.search(user, args.q, args.type, args.resolve, args.following, args.account_id, args['exclude_unreviewed'], args.max_id, args.min_id, args.limit, args.offset, cache); ctx.body = convertSearchIds(result); } catch (e: any) { console.error(e); ctx.status = 400; ctx.body = {error: e.message}; } }); router.get("/v1/trends/statuses", async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.headers.authorization; try { const data = await getHighlight( BASE_URL, ctx.request.hostname, accessTokens, ); ctx.body = data.map((status) => convertStatusIds(status)); } catch (e: any) { console.error(e); ctx.status = 401; ctx.body = e.response.data; } }); router.get("/v2/suggestions", async (ctx) => { const BASE_URL = `${ctx.request.protocol}://${ctx.request.hostname}`; const accessTokens = ctx.headers.authorization; try { const query: any = ctx.query; let data = await getFeaturedUser( BASE_URL, ctx.request.hostname, accessTokens, query.limit || 20, ); data = data.map((suggestion) => { suggestion.account = convertAccountId(suggestion.account); return suggestion; }); console.log(data); ctx.body = data; } catch (e: any) { console.error(e); ctx.status = 401; ctx.body = e.response.data; } }); } async function getHighlight( BASE_URL: string, domain: string, accessTokens: string | undefined, ) { const accessTokenArr = accessTokens?.split(" ") ?? [null]; const accessToken = accessTokenArr[accessTokenArr.length - 1]; try { const api = await axios.post(`${BASE_URL}/api/notes/featured`, { i: accessToken, }); const data: MisskeyEntity.Note[] = api.data; return data.map((note) => new Converter(BASE_URL).note(note, domain)); } catch (e: any) { console.log(e); console.log(e.response.data); return []; } } async function getFeaturedUser( BASE_URL: string, host: string, accessTokens: string | undefined, limit: number, ) { const accessTokenArr = accessTokens?.split(" ") ?? [null]; const accessToken = accessTokenArr[accessTokenArr.length - 1]; try { const api = await axios.post(`${BASE_URL}/api/users`, { i: accessToken, limit, origin: "local", sort: "+follower", state: "alive", }); const data: MisskeyEntity.UserDetail[] = api.data; console.log(data); return data.map((u) => { return { source: "past_interactions", account: new Converter(BASE_URL).userDetail(u, host), }; }); } catch (e: any) { console.log(e); console.log(e.response.data); return []; } }