summary refs log tree commit diff
path: root/api/src/routes/guilds/#guild_id/messages/search.ts
diff options
context:
space:
mode:
Diffstat (limited to 'api/src/routes/guilds/#guild_id/messages/search.ts')
-rw-r--r--api/src/routes/guilds/#guild_id/messages/search.ts87
1 files changed, 87 insertions, 0 deletions
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<Message> = {
+		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