From 664e3c649768a711f1a939e05a1008267ac125b6 Mon Sep 17 00:00:00 2001 From: Madeline <46743919+MaddyUnderStars@users.noreply.github.com> Date: Fri, 2 Sep 2022 20:37:10 +1000 Subject: Message searching in guilds --- api/src/routes/guilds/#guild_id/messages/search.ts | 87 ++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 api/src/routes/guilds/#guild_id/messages/search.ts diff --git a/api/src/routes/guilds/#guild_id/messages/search.ts b/api/src/routes/guilds/#guild_id/messages/search.ts new file mode 100644 index 00000000..a7516ebd --- /dev/null +++ b/api/src/routes/guilds/#guild_id/messages/search.ts @@ -0,0 +1,87 @@ +import { Request, Response, Router } from "express"; +import { route } from "@fosscord/api"; +import { getPermission, FieldErrors, Message } from "@fosscord/util"; +import { HTTPError } from "lambert-server"; +import { FindManyOptions, Like } from "typeorm"; + +const router: Router = Router(); + +router.get("/", route({}), async (req: Request, res: Response) => { + const { + channel_id, + content, + include_nsfw, // TODO + offset, + sort_order, + sort_by, // TODO: Handle 'relevance' + limit, + author_id, + } = req.query; + + const parsedLimit = Number(limit) || 50; + if (parsedLimit < 1 || parsedLimit > 100) throw new HTTPError("limit must be between 1 and 100", 422); + + if (sort_order) { + if (typeof sort_order != "string" + || ["desc", "asc"].indexOf(sort_order) == -1) + throw FieldErrors({ sort_order: { message: "Value must be one of ('desc', 'asc').", code: "BASE_TYPE_CHOICES" } }); // todo this is wrong + } + + const permissions = await getPermission(req.user_id, req.params.guild_id, channel_id as string); + permissions.hasThrow("VIEW_CHANNEL"); + if (!permissions.has("READ_MESSAGE_HISTORY")) return res.json({ messages: [], total_results: 0 }); + + var query: FindManyOptions = { + order: { timestamp: sort_order ? sort_order.toUpperCase() as "ASC" | "DESC" : "DESC" }, + take: parsedLimit || 0, + where: { + guild: { + id: req.params.guild_id, + }, + }, + relations: ["author", "webhook", "application", "mentions", "mention_roles", "mention_channels", "sticker_items", "attachments"], + skip: offset ? Number(offset) : 0, + }; + //@ts-ignore + if (channel_id) query.where!.channel = { id: channel_id }; + //@ts-ignore + if (author_id) query.where!.author = { id: author_id }; + //@ts-ignore + if (content) query.where!.content = Like(`%${content}%`); + + const messages: Message[] = await Message.find(query); + + const messagesDto = messages.map(x => [{ + id: x.id, + type: x.type, + content: x.content, + channel_id: x.channel_id, + author: { + id: x.author?.id, + username: x.author?.username, + avatar: x.author?.avatar, + avatar_decoration: null, + discriminator: x.author?.discriminator, + public_flags: x.author?.public_flags, + }, + attachments: x.attachments, + embeds: x.embeds, + mentions: x.mentions, + mention_roles: x.mention_roles, + pinned: x.pinned, + mention_everyone: x.mention_everyone, + tts: x.tts, + timestamp: x.timestamp, + edited_timestamp: x.edited_timestamp, + flags: x.flags, + components: x.components, + hit: true, + }]); + + return res.json({ + messages: messagesDto, + total_results: messages.length, + }); +}); + +export default router; \ No newline at end of file -- cgit 1.4.1