Plugin
KeywordNotify
Sends a notification if a given message matches certain keywords or regexes
1
/*2
* FiveCord — a Discord client mod3
* Copyright (c) 2025 FiveCord4
* SPDX-License-Identifier: GPL-3.0-or-later5
*/6
7
import "./style.css";8
9
import { DataStore } from "@api/index";10
import { definePluginSettings } from "@api/Settings";11
import { Flex } from "@components/Flex";12
import { DeleteIcon } from "@components/Icons";13
import { Devs } from "@utils/constants";14
import { useForceUpdater } from "@utils/react";15
import definePlugin, { OptionType } from "@utils/types";16
import { Button, Forms, TextInput, UserStore, UserUtils, useState } from "@webpack/common";17
import { User } from "discord-types/general";18
19
let regexes: string[] = [];20
let me: User | null = null;21
22
async function setRegexes(idx: number, reg: string) {23
regexes[idx] = reg;24
await DataStore.set("KeywordNotify_rules", regexes);25
}26
27
async function removeRegex(idx: number, updater: () => void) {28
regexes.splice(idx, 1);29
await DataStore.set("KeywordNotify_rules", regexes);30
updater();31
}32
33
async function addRegex(updater: () => void) {34
regexes.push("");35
await DataStore.set("KeywordNotify_rules", regexes);36
updater();37
}38
39
const settings = definePluginSettings({40
replace: {41
type: OptionType.COMPONENT,42
description: "",43
component: () => {44
const update = useForceUpdater();45
const [values, setValues] = useState(regexes);46
47
const elements = regexes.map((a, i) => {48
const setValue = (v: string) => {49
const valuesCopy = [...values];50
valuesCopy[i] = v;51
setValues(valuesCopy);52
};53
54
return (55
<>56
<Forms.FormTitle tag="h4">Keyword Regex {i + 1}</Forms.FormTitle>57
58
<Flex flexDirection="row">59
<div style={{ flexGrow: 1 }}>60
<TextInput61
placeholder={"example|regex"}62
spellCheck={false}63
value={values[i]}64
onChange={setValue}65
onBlur={() => setRegexes(i, values[i])}66
/>67
</div>68
69
<Button70
onClick={() => removeRegex(i, update)}71
look={Button.Looks.BLANK}72
size={Button.Sizes.ICON}73
className="keywordnotify-delete">74
<DeleteIcon />75
</Button>76
</Flex>77
</>78
);79
});80
81
return (82
<>83
{elements}84
<div><Button onClick={() => addRegex(update)}>Add Regex</Button></div>85
</>86
);87
}88
},89
});90
91
export default definePlugin({92
name: "KeywordNotify",93
authors: [Devs.FiveCord],94
description: "Sends a notification if a given message matches certain keywords or regexes",95
settings,96
patches: [97
{98
find: "}_dispatch(",99
replacement: {100
match: /}_dispatch\((.{1,2}),.{1,2}\){/,101
replace: "$&$1=$self.modify($1);"102
}103
}104
],105
106
async start() {107
regexes = await DataStore.get("KeywordNotify_rules") ?? [];108
me = await UserUtils.getUser(UserStore.getCurrentUser().id);109
},110
111
applyRegexes(m) {112
if (regexes.some(r => m.content.match(new RegExp(r)))) {113
m.mentions.push(me);114
}115
},116
117
modify(e) {118
if (e.type === "MESSAGE_CREATE") {119
this.applyRegexes(e.message);120
} else if (e.type === "LOAD_MESSAGES_SUCCESS") {121
for (let msg = 0; msg < e.messages.length; ++msg) {122
this.applyRegexes(e.messages[msg]);123
}124
}125
return e;126
}127
});128