Plugin

ReplyPingControl

Control whether to always or never get pinged on message replies, with a whitelist feature

index.ts
Download

Source

src/plugins/replyPingControl/index.ts
1/*
2 * FiveCord — a Discord client mod
3 * Copyright (c) 2025 FiveCord
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
7import { definePluginSettings } from "@api/Settings";
8import { Devs } from "@utils/constants";
9import definePlugin, { OptionType } from "@utils/types";
10import { MessageStore, showToast, UserStore } from "@webpack/common";
11import { MessageJSON } from "discord-types/general";
12
13let cachedWhitelist: string[] = [];
14
15export const settings = definePluginSettings({
16 alwaysPingOnReply: {
17 type: OptionType.BOOLEAN,
18 description: "Always get pinged when someone replies to your messages",
19 default: false,
20 },
21 replyPingWhitelist: {
22 type: OptionType.STRING,
23 description: "Comma-separated list of User IDs to always receive reply pings from",
24 default: "",
25 disabled: () => settings.store.alwaysPingOnReply,
26 onChange: newValue => {
27 const originalIDs = newValue.split(",")
28 .map(id => id.trim())
29 .filter(id => id !== "");
30
31 const isInvalid = originalIDs.some(id => !isValidUserId(id));
32
33 if (isInvalid) {
34 showToast("Invalid User ID: One or more User IDs in the whitelist are invalid. Please check your input.");
35 } else {
36 cachedWhitelist = originalIDs;
37 showToast("Whitelist Updated: Reply ping whitelist has been successfully updated.");
38 }
39 }
40 }
41});
42
43export default definePlugin({
44 name: "ReplyPingControl",
45 description: "Control whether to always or never get pinged on message replies, with a whitelist feature",
46 authors: [Devs.FiveCord],
47 settings,
48
49 patches: [{
50 find: "_channelMessages",
51 replacement: {
52 match: /receiveMessage\((\i)\)\{/,
53 replace: "$&$self.modifyMentions($1);"
54 }
55 }],
56
57 modifyMentions(message: MessageJSON) {
58 const user = UserStore.getCurrentUser();
59 if (message.author.id === user.id)
60 return;
61
62 const repliedMessage = this.getRepliedMessage(message);
63 if (!repliedMessage || repliedMessage.author.id !== user.id)
64 return;
65
66 const isWhitelisted = cachedWhitelist.includes(message.author.id);
67
68 if (isWhitelisted || settings.store.alwaysPingOnReply) {
69 if (!message.mentions.some(mention => mention.id === user.id))
70 message.mentions.push(user as any);
71 } else {
72 message.mentions = message.mentions.filter(mention => mention.id !== user.id);
73 }
74 },
75
76 getRepliedMessage(message: MessageJSON) {
77 const ref = message.message_reference;
78 return ref && MessageStore.getMessage(ref.channel_id, ref.message_id);
79 },
80});
81
82function parseWhitelist(value: string) {
83 return value.split(",")
84 .map(id => id.trim())
85 .filter(id => id !== "");
86}
87
88function isValidUserId(id: string) {
89 return /^\d+$/.test(id);
90}
91