Skip to content

Commit 8cf91c1

Browse files
authored
Merge pull request #570 from seeyebe/feat/commands-aliases
feat/commands aliases
2 parents eb1fa28 + 78f3d50 commit 8cf91c1

File tree

7 files changed

+142
-0
lines changed

7 files changed

+142
-0
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { guildPlugin } from "vety";
2+
import { DispatchAliasEvt } from "./events/DispatchAliasEvt.js";
3+
import { CommandAliasesPluginType, zCommandAliasesConfig } from "./types.js";
4+
import { normalizeAliases } from "./functions/normalizeAliases.js";
5+
import { buildAliasMatchers } from "./functions/buildAliasMatchers.js";
6+
import { getGuildPrefix } from "../../utils/getGuildPrefix.js";
7+
8+
export const CommandAliasesPlugin = guildPlugin<CommandAliasesPluginType>()({
9+
name: "command_aliases",
10+
configSchema: zCommandAliasesConfig,
11+
12+
beforeLoad(pluginData) {
13+
const prefix = getGuildPrefix(pluginData);
14+
const config = pluginData.config.get();
15+
const normalizedAliases = normalizeAliases(config.aliases);
16+
17+
pluginData.state.matchers = buildAliasMatchers(prefix, normalizedAliases);
18+
},
19+
20+
events: [DispatchAliasEvt],
21+
});
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { ZeppelinPluginDocs } from "../../types.js";
2+
import { zCommandAliasesConfig } from "./types.js";
3+
4+
export const commandAliasesPluginDocs: ZeppelinPluginDocs = {
5+
type: "stable",
6+
prettyName: "Command Aliases",
7+
configSchema: zCommandAliasesConfig,
8+
description: "This plugin lets you create shortcuts for existing commands.",
9+
usageGuide: `
10+
For example, you can make \`!b\` work the same as \`!ban\`, or \`!c\` work the same as \`!cases\`.
11+
12+
### Example
13+
14+
\`\`\`yaml
15+
plugins:
16+
command_aliases:
17+
config:
18+
aliases:
19+
"b": "ban"
20+
"c": "cases"
21+
"b2": "ban -d 2"
22+
"ownerinfo": "info 754421392988045383"
23+
\`\`\`
24+
25+
With this setup:
26+
- \`!b @User\` runs \`!ban @User\`
27+
- \`!c\` runs \`!cases\`
28+
- \`!b2 @User\` runs \`!ban -d 2 @User\`
29+
- \`!ownerinfo\` runs \`!info 754421392988045383\`
30+
`
31+
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { Message } from "discord.js";
2+
import { commandAliasesEvt } from "../types.js";
3+
4+
export const DispatchAliasEvt = commandAliasesEvt({
5+
event: "messageCreate",
6+
async listener({ args: { message: msg }, pluginData }) {
7+
if (!msg.guild || !msg.content) return;
8+
if (msg.author.bot || msg.webhookId) return;
9+
10+
const matchers = pluginData.state.matchers ?? [];
11+
if (matchers.length === 0) return;
12+
13+
const matchingAlias = matchers.find((matcher) => matcher.regex.test(msg.content));
14+
if (!matchingAlias) return;
15+
16+
const newContent = msg.content.replace(matchingAlias.regex, matchingAlias.replacement);
17+
if (newContent === msg.content) return;
18+
19+
const copiedMessage = Object.create(msg);
20+
copiedMessage.content = newContent;
21+
22+
await pluginData.getKnubInstance().dispatchMessageCommands(copiedMessage as Message);
23+
},
24+
});
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import escapeStringRegexp from "escape-string-regexp";
2+
import { NormalizedAlias } from "./normalizeAliases.js";
3+
4+
export interface AliasMatcher {
5+
regex: RegExp;
6+
replacement: string;
7+
}
8+
9+
export function buildAliasMatchers(prefix: string, aliases: NormalizedAlias[]): AliasMatcher[] {
10+
return aliases.map((alias) => {
11+
const pattern = `^${escapeStringRegexp(prefix)}${escapeStringRegexp(alias.alias)}\\b`;
12+
return {
13+
regex: new RegExp(pattern, "i"),
14+
replacement: `${prefix}${alias.target}`,
15+
};
16+
});
17+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
export interface NormalizedAlias {
2+
alias: string;
3+
target: string;
4+
}
5+
6+
export function normalizeAliases(aliases: Record<string, string> | undefined | null): NormalizedAlias[] {
7+
if (!aliases) {
8+
return [];
9+
}
10+
11+
const normalized: NormalizedAlias[] = [];
12+
for (const [rawAlias, rawTarget] of Object.entries(aliases)) {
13+
const alias = rawAlias.trim();
14+
const target = rawTarget.trim();
15+
16+
if (!alias || !target) {
17+
continue;
18+
}
19+
20+
normalized.push({
21+
alias,
22+
target,
23+
});
24+
}
25+
26+
return normalized;
27+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { BasePluginType, guildPluginEventListener } from "vety";
2+
import z from "zod";
3+
import { AliasMatcher } from "./functions/buildAliasMatchers.js";
4+
5+
export const zCommandAliasesConfig = z.strictObject({
6+
aliases: z.record(z.string().min(1), z.string().min(1)).optional(),
7+
});
8+
9+
export interface CommandAliasesPluginType extends BasePluginType {
10+
configSchema: typeof zCommandAliasesConfig;
11+
state: {
12+
matchers: AliasMatcher[];
13+
};
14+
}
15+
16+
export const commandAliasesEvt = guildPluginEventListener<CommandAliasesPluginType>();

backend/src/plugins/availablePlugins.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ import { UtilityPlugin } from "./Utility/UtilityPlugin.js";
7777
import { utilityPluginDocs } from "./Utility/docs.js";
7878
import { WelcomeMessagePlugin } from "./WelcomeMessage/WelcomeMessagePlugin.js";
7979
import { welcomeMessagePluginDocs } from "./WelcomeMessage/docs.js";
80+
import { CommandAliasesPlugin } from "./CommandAliases/CommandAliasesPlugin.js";
81+
import { commandAliasesPluginDocs } from "./CommandAliases/docs.js";
8082

8183
export const availableGuildPlugins: ZeppelinGuildPluginInfo[] = [
8284
{
@@ -100,6 +102,10 @@ export const availableGuildPlugins: ZeppelinGuildPluginInfo[] = [
100102
plugin: CensorPlugin,
101103
docs: censorPluginDocs,
102104
},
105+
{
106+
plugin: CommandAliasesPlugin,
107+
docs: commandAliasesPluginDocs,
108+
},
103109
{
104110
plugin: CompanionChannelsPlugin,
105111
docs: companionChannelsPluginDocs,

0 commit comments

Comments
 (0)