Skip to content

Commit

Permalink
Add mention role support
Browse files Browse the repository at this point in the history
  • Loading branch information
SupertigerDev committed Dec 9, 2024
1 parent 9a52d34 commit 950b88d
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-- CreateTable
CREATE TABLE "_role_mentioned_messages" (
"A" TEXT NOT NULL,
"B" TEXT NOT NULL
);

-- CreateIndex
CREATE UNIQUE INDEX "_role_mentioned_messages_AB_unique" ON "_role_mentioned_messages"("A", "B");

-- CreateIndex
CREATE INDEX "_role_mentioned_messages_B_index" ON "_role_mentioned_messages"("B");

-- AddForeignKey
ALTER TABLE "_role_mentioned_messages" ADD CONSTRAINT "_role_mentioned_messages_A_fkey" FOREIGN KEY ("A") REFERENCES "Message"("id") ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE "_role_mentioned_messages" ADD CONSTRAINT "_role_mentioned_messages_B_fkey" FOREIGN KEY ("B") REFERENCES "ServerRole"("id") ON DELETE CASCADE ON UPDATE CASCADE;
5 changes: 5 additions & 0 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,10 @@ model ServerRole {
channelPermissions ServerChannelPermissions[]
mentionedMessages Message[] @relation(name: "role_mentioned_messages")
}


Expand Down Expand Up @@ -583,6 +587,7 @@ model Message {
channel Channel @relation(fields: [channelId], references: [id], onDelete: Cascade)
createdBy User @relation(fields: [createdById], references: [id])
mentions User[] @relation(name: "mentioned_messages")
roleMentions ServerRole[] @relation(name: "role_mentioned_messages")
attachments Attachment[]
reactions MessageReaction[]
Expand Down
6 changes: 4 additions & 2 deletions src/common/Bitwise.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,13 +117,15 @@ export const ROLE_PERMISSIONS = {
name: 'Mention Everyone',
description: 'mentionEveryoneDescription',
bit: 64,
//icon: 'mention'
},
NICKNAME_MEMBER: {
name: 'Nickname Member',
description: 'mentionEveryoneDescription',
bit: 128,
//icon: 'mention'
},
MENTION_ROLES: {
name: 'Mention Roles',
bit: 256,
},
};

Expand Down
3 changes: 3 additions & 0 deletions src/routes/channels/channelMessageCreate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ async function route(req: Request, res: Response) {
canMentionEveryone = !!hasMentionEveryonePerm;
}

const [canMentionRoles] = memberHasRolePermission(req, ROLE_PERMISSIONS.MENTION_ROLES);

let attachment: Partial<Attachment> | undefined = undefined;

if (body.nerimityCdnFileId) {
Expand Down Expand Up @@ -269,6 +271,7 @@ async function route(req: Request, res: Response) {
type: MessageType.CONTENT,
attachment,
everyoneMentioned: canMentionEveryone,
canMentionRoles,
htmlEmbed: body.htmlEmbed,
buttons: body.buttons?.map(({ id, label, alert }) => ({ id, label, alert })),
});
Expand Down
75 changes: 73 additions & 2 deletions src/services/Message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,14 @@ export const getMessagesByChannelId = async (channelId: string, opts?: GetMessag
bot: true,
},
},
roleMentions: {
select: {
id: true,
name: true,
hexColor: true,
icon: true,
},
},
mentions: {
select: {
id: true,
Expand Down Expand Up @@ -156,6 +164,14 @@ export const getMessagesByChannelId = async (channelId: string, opts?: GetMessag
avatar: true,
},
},
roleMentions: {
select: {
id: true,
name: true,
hexColor: true,
icon: true,
},
},
editedAt: true,
createdAt: true,
channelId: true,
Expand Down Expand Up @@ -295,6 +311,14 @@ export const MessageInclude = Prisma.validator<Prisma.MessageDefaultArgs>()({
avatar: true,
},
},
roleMentions: {
select: {
id: true,
name: true,
hexColor: true,
icon: true,
},
},
buttons: {
orderBy: { order: 'asc' },
select: {
Expand Down Expand Up @@ -354,6 +378,14 @@ export const MessageInclude = Prisma.validator<Prisma.MessageDefaultArgs>()({
avatar: true,
},
},
roleMentions: {
select: {
id: true,
name: true,
hexColor: true,
icon: true,
},
},
editedAt: true,
createdAt: true,
channelId: true,
Expand Down Expand Up @@ -463,6 +495,7 @@ interface SendMessageOptions {
updateLastSeen?: boolean; // by default, this is true.
attachment?: Partial<Attachment>;
everyoneMentioned?: boolean;
canMentionRoles?: boolean;
htmlEmbed?: string;

replyToMessageIds?: string[];
Expand All @@ -480,6 +513,7 @@ type MessageDataCreate = Parameters<typeof prisma.message.create>[0]['data'];
type MessageDataUpdate = Parameters<typeof prisma.message.update>[0]['data'];

const userMentionRegex = /\[@:([\d]+)]/g;
const roleMentionRegex = /\[r:([\d]+)]/g;
const quoteMessageRegex = /\[q:([\d]+)]/g;

interface ConstructDataOpts {
Expand All @@ -503,6 +537,20 @@ async function constructData({ messageData, creatorId, update, bypassQuotesCheck
};
}

if (sendMessageOpts?.canMentionRoles && sendMessageOpts.serverId) {
const mentionRoleIds = removeDuplicates([...messageData.content.matchAll(roleMentionRegex)].map((m) => m[1]));

const mentionedRoles = await prisma.serverRole.findMany({
where: {
id: { in: mentionRoleIds },
},
select: { id: true },
});
messageData.roleMentions = {
...(update ? { set: mentionedRoles } : { connect: mentionedRoles }),
};
}

if (!update && sendMessageOpts?.replyToMessageIds?.length) {
const replyToMessageIds = removeDuplicates(sendMessageOpts.replyToMessageIds);

Expand Down Expand Up @@ -615,6 +663,14 @@ export const createMessage = async (opts: SendMessageOptions) => {
bot: true,
},
},
roleMentions: {
select: {
id: true,
name: true,
hexColor: true,
icon: true,
},
},
mentions: {
select: {
id: true,
Expand Down Expand Up @@ -764,15 +820,30 @@ export const createMessage = async (opts: SendMessageOptions) => {
});
mentionUserIds = serverMembers.map((member) => member.userId);
} else {
if (message.mentions.length) {
mentionUserIds = message.mentions.map((mention) => mention.id);
}

if (message.mentionReplies) {
const userIds = message.replyMessages.map((message) => message.replyToMessage?.createdBy.id);
if (userIds.length) {
mentionUserIds = [...mentionUserIds, ...userIds];
}
}

if (message.mentions.length) {
mentionUserIds = message.mentions.map((mention) => mention.id);
if (message.roleMentions.length) {
const users = await prisma.user.findMany({
where: {
memberInServers: {
some: {
serverId: opts.serverId,
roleIds: { hasSome: message.roleMentions.map((role) => role.id) },
},
},
},
});
const userIds = users.map((user) => user.id);
mentionUserIds = [...mentionUserIds, ...userIds];
}

if (message.quotedMessages.length) {
Expand Down

0 comments on commit 950b88d

Please sign in to comment.