Keyword Alert Plugin
An intermediate Plexcord plugin that monitors messages for user-defined keywords and sends notifications. Demonstrates settings, Flux events, and stores.
Example: Keyword Alert Plugin
Difficulty: Intermediate | Concepts: Plugin settings, Flux events, Webpack stores, showNotification
This plugin watches incoming messages for keywords you define. When a match is found, you get a notification with the message content and author. This demonstrates the most common pattern in Plexcord plugins: listen to a Flux event → read settings → take action.
Full Source
// File: src/plugins/keywordAlert/index.ts
import definePlugin, { OptionType } from "@utils/types";
import { definePluginSettings } from "@api/Settings";
import { showNotification } from "@api/Notifications";
import { UserStore, NavigationUtils } from "@webpack/common";
import { Logger } from "@utils/Logger";
const logger = new Logger("KeywordAlert");
const settings = definePluginSettings({
keywords: {
type: OptionType.STRING,
description: "Comma-separated keywords to watch for",
default: "important, urgent",
restartNeeded: false
},
caseSensitive: {
type: OptionType.BOOLEAN,
description: "Match keywords with exact case",
default: false,
restartNeeded: false
},
ignoreSelf: {
type: OptionType.BOOLEAN,
description: "Don't alert for your own messages",
default: true,
restartNeeded: false
}
});
export default definePlugin({
name: "KeywordAlert",
description: "Notifies you when anyone uses your watched keywords",
authors: [
{
name: "YourName",
id: 0n
}
],
settings,
flux: {
MESSAGE_CREATE({ message }) {
try {
const me = UserStore.getCurrentUser();
// Ignore own messages if setting is on
if (settings.store.ignoreSelf && message.author.id === me?.id) return;
// Skip bots
if (message.author.bot) return;
// Parse keyword list
const raw = settings.store.keywords;
const keywords = raw
.split(",")
.map(k => k.trim())
.filter(Boolean);
if (keywords.length === 0) return;
const content = settings.store.caseSensitive
? message.content
: message.content.toLowerCase();
const matched = keywords.find(kw => {
const needle = settings.store.caseSensitive ? kw : kw.toLowerCase();
return content.includes(needle);
});
if (!matched) return;
// Truncate long messages
const preview = message.content.length > 120
? message.content.slice(0, 120) + "…"
: message.content;
showNotification({
title: `🔔 Keyword: "${matched}"`,
body: `${message.author.username}: ${preview}`,
color: "#FAA61A",
onClick: () => {
// Navigate to the message's channel
if (message.guild_id) {
NavigationUtils.transitionToGuild(
message.guild_id,
message.channel_id
);
}
}
});
logger.info(`Keyword "${matched}" found in message from ${message.author.username}`);
} catch (e) {
logger.error("Error processing message:", e);
}
}
}
});Key Concepts Used
Plugin Settings
The settings object uses definePluginSettings to create three user-configurable options:
keywords: aSTRINGoption that Plexcord renders as a text inputcaseSensitive: aBOOLEANrendered as a toggleignoreSelf: aBOOLEANrendered as a toggle
These automatically appear in Settings → Plugins → KeywordAlert.
Flux Event Listener
flux: {
MESSAGE_CREATE({ message }) { ... }
}Every time any message is received in any channel you have loaded, this function runs. The destructured message object includes content, author, channel_id, guild_id, and more.
Reading Settings at Runtime
settings.store.keywords // Always the current value
settings.store.caseSensitiveBecause restartNeeded: false, settings are read on every event, so no restart is needed when the user changes them.
Testing It
- Copy the file to
src/plugins/keywordAlert/index.ts - Rebuild Plexcord
- Enable the plugin in Settings → Plugins
- Configure your keywords
- Send a message in any channel containing one of your keywords
Next Example
Simple Notification Plugin
A beginner-level Plexcord plugin that shows a welcome notification when installed. Learn the bare minimum of a working plugin.
Message Formatter Plugin
An intermediate Plexcord plugin that uses patches to modify Discord's message rendering. Demonstrates the patch system with real regex replacements.