summary refs log tree commit diff
path: root/api
diff options
context:
space:
mode:
Diffstat (limited to 'api')
-rw-r--r--api/src/util/Message.ts74
1 files changed, 59 insertions, 15 deletions
diff --git a/api/src/util/Message.ts b/api/src/util/Message.ts
index a55c3365..803c37dc 100644
--- a/api/src/util/Message.ts
+++ b/api/src/util/Message.ts
@@ -1,9 +1,22 @@
-import { ChannelModel, Embed, emitEvent, Message, MessageCreateEvent, MessageUpdateEvent } from "@fosscord/util";
-import { Snowflake } from "@fosscord/util";
-import { MessageModel } from "@fosscord/util";
-import { PublicMemberProjection } from "@fosscord/util";
-import { toObject } from "@fosscord/util";
-import { getPermission } from "@fosscord/util";
+import {
+	ChannelModel,
+	Embed,
+	emitEvent,
+	Message,
+	MessageCreateEvent,
+	MessageUpdateEvent,
+	getPermission,
+	CHANNEL_MENTION,
+	toObject,
+	MessageModel,
+	Snowflake,
+	PublicMemberProjection,
+	USER_MENTION,
+	ROLE_MENTION,
+	RoleModel,
+	EVERYONE_MENTION,
+	HERE_MENTION
+} from "@fosscord/util";
 import { HTTPError } from "lambert-server";
 import fetch from "node-fetch";
 import cheerio from "cheerio";
@@ -35,11 +48,11 @@ export async function handleMessage(opts: Partial<Message>) {
 	// TODO: are tts messages allowed in dm channels? should permission be checked?
 
 	// @ts-ignore
-	const permissions = await getPermission(opts.author_id, channel.guild_id, opts.channel_id, { channel });
-	permissions.hasThrow("SEND_MESSAGES");
-	if (opts.tts) permissions.hasThrow("SEND_TTS_MESSAGES");
+	const permission = await getPermission(opts.author_id, channel.guild_id, opts.channel_id, { channel });
+	permission.hasThrow("SEND_MESSAGES");
+	if (opts.tts) permission.hasThrow("SEND_TTS_MESSAGES");
 	if (opts.message_reference) {
-		permissions.hasThrow("READ_MESSAGE_HISTORY");
+		permission.hasThrow("READ_MESSAGE_HISTORY");
 		if (opts.message_reference.guild_id !== channel.guild_id) throw new HTTPError("You can only reference messages from this guild");
 		if (opts.message_reference.channel_id !== opts.channel_id) throw new HTTPError("You can only reference messages from this channel");
 		// TODO: should be checked if the referenced message exists?
@@ -51,16 +64,47 @@ export async function handleMessage(opts: Partial<Message>) {
 		throw new HTTPError("Empty messages are not allowed", 50006);
 	}
 
+	var content = opts.content;
+	var mention_channels_ids = [] as string[];
+	var mention_role_ids = [] as string[];
+	var mention_user_ids = [] as string[];
+	var mention_everyone = false;
+	var mention_everyone = false;
+
+	if (content) {
+		content = content.trim();
+		for (const [_, mention] of content.matchAll(CHANNEL_MENTION)) {
+			if (!mention_channels_ids.includes(mention)) mention_channels_ids.push(mention);
+		}
+
+		for (const [_, mention] of content.matchAll(USER_MENTION)) {
+			if (!mention_user_ids.includes(mention)) mention_user_ids.push(mention);
+		}
+
+		await Promise.all(
+			Array.from(content.matchAll(ROLE_MENTION)).map(async ([_, mention]) => {
+				const role = await RoleModel.findOne({ id: mention, guild_id: channel.guild_id }).exec();
+				if (role.mentionable || permission.has("MANAGE_ROLES")) {
+					mention_role_ids.push(mention);
+				}
+			})
+		);
+
+		if (permission.has("MENTION_EVERYONE")) {
+			mention_everyone = !!content.match(EVERYONE_MENTION) || !!content.match(HERE_MENTION);
+		}
+	}
+
 	// TODO: check and put it all in the body
 	return {
 		...opts,
 		guild_id: channel.guild_id,
 		channel_id: opts.channel_id,
-		// TODO: generate mentions and check permissions
-		mention_channels_ids: [],
-		mention_role_ids: [],
-		mention_user_ids: [],
-		attachments: opts.attachments || [], // TODO: message attachments
+		mention_channels_ids,
+		mention_role_ids,
+		mention_user_ids,
+		mention_everyone,
+		attachments: opts.attachments || [],
 		embeds: opts.embeds || [],
 		reactions: opts.reactions || [],
 		type: opts.type ?? 0