mirror of
https://github.com/ReCloudStudio/WebHooker.git
synced 2026-09-23 00:21:28 +00:00
feat: add Discord role mention support to routes
This commit is contained in:
parent
869d84d78c
commit
76ba2c0a89
17 changed files with 201 additions and 14 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import { describe, it, expect, beforeEach, afterEach } from "bun:test";
|
||||
import { sendMessage } from "../drivers/discord/rest";
|
||||
import { renderNeutralMessage } from "../drivers/discord/render";
|
||||
import { dispatchEvent } from "../core/dispatch";
|
||||
import type { Env, Route } from "../types";
|
||||
|
||||
|
|
@ -68,6 +69,22 @@ describe("discord-rest sendMessage", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("discord role mentions", () => {
|
||||
it("renders mentionRoleIds into the message content", () => {
|
||||
const out = renderNeutralMessage({
|
||||
title: "T",
|
||||
mentionRoleIds: ["111", "222"],
|
||||
});
|
||||
expect(out.content).toBe("<@&111> <@&222>");
|
||||
expect(out.embeds?.[0]?.title).toBe("T");
|
||||
});
|
||||
|
||||
it("omits content when no roles are mentioned", () => {
|
||||
const out = renderNeutralMessage({ title: "T" });
|
||||
expect(out.content).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe("dispatchEvent fallback routing", () => {
|
||||
function createMockKV(): KVNamespace {
|
||||
const store = new Map<string, string>();
|
||||
|
|
@ -169,4 +186,33 @@ describe("dispatchEvent fallback routing", () => {
|
|||
expect(sent.filter((u) => u.includes("/111/"))).toHaveLength(0);
|
||||
expect(sent.filter((u) => u.includes("/222/"))).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("prepends role mentions to the Discord message content", async () => {
|
||||
const bodies: string[] = [];
|
||||
mockFetch((url, init) => {
|
||||
bodies.push(String(init?.body ?? ""));
|
||||
return new Response("{}", { status: 200 });
|
||||
});
|
||||
const env = createEnv({ KV: createMockKV(), DB: createMockDB() });
|
||||
const routes: Route[] = [
|
||||
{
|
||||
id: "mention-push",
|
||||
name: "Mention Push",
|
||||
enabled: true,
|
||||
discordRoleIds: ["111", "222"],
|
||||
filters: [{ type: "event", match: "push" }],
|
||||
targets: [{ channelId: "333" }],
|
||||
},
|
||||
];
|
||||
|
||||
await dispatchEvent({ ...baseConfig, routes }, { event: "push", payload: {} }, env);
|
||||
|
||||
expect(bodies).toHaveLength(1);
|
||||
const parsed = JSON.parse(bodies[0]!) as {
|
||||
content?: string;
|
||||
embeds?: Array<{ title?: string }>;
|
||||
};
|
||||
expect(parsed.content).toBe("<@&111> <@&222>");
|
||||
expect(parsed.embeds?.[0]).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -55,6 +55,9 @@ export async function dispatchEvent(config: Config, event: WebhookEvent, env: En
|
|||
const group = route.groupId ? groupById.get(route.groupId) : undefined;
|
||||
const showEmoji = group?.emoji !== false;
|
||||
const message = formatEvent(route, event, tr, showEmoji);
|
||||
if (route.discordRoleIds?.length) {
|
||||
message.mentionRoleIds = route.discordRoleIds;
|
||||
}
|
||||
|
||||
for (const target of targets) {
|
||||
const targetStr =
|
||||
|
|
|
|||
|
|
@ -12,7 +12,11 @@ function toStyle(style: NeutralActionStyle): number {
|
|||
}
|
||||
|
||||
export function renderNeutralMessage(message: NeutralMessage): FormattedMessage {
|
||||
const content = message.mentionRoleIds?.length
|
||||
? message.mentionRoleIds.map((id) => `<@&${id}>`).join(" ")
|
||||
: undefined;
|
||||
return {
|
||||
content,
|
||||
embeds: [
|
||||
{
|
||||
title: message.title,
|
||||
|
|
|
|||
11
src/types.ts
11
src/types.ts
|
|
@ -64,6 +64,11 @@ export interface Route {
|
|||
* fallthrough to subsequent routes.
|
||||
*/
|
||||
stop?: boolean;
|
||||
/**
|
||||
* Discord role (身份组) ids to mention/notify when this route fires. Roles
|
||||
* are only mentioned in Discord targets; Telegram targets ignore this field.
|
||||
*/
|
||||
discordRoleIds?: string[];
|
||||
}
|
||||
|
||||
export interface Group {
|
||||
|
|
@ -136,9 +141,15 @@ export interface NeutralMessage {
|
|||
* previously sent message instead of sending a new one.
|
||||
*/
|
||||
updateKey?: string;
|
||||
/**
|
||||
* Discord role ids to mention in the message content (set by dispatch from
|
||||
* the route's `discordRoleIds`). Only used by the Discord driver.
|
||||
*/
|
||||
mentionRoleIds?: string[];
|
||||
}
|
||||
|
||||
export interface FormattedMessage {
|
||||
content?: string;
|
||||
embeds?: Array<{
|
||||
title?: string;
|
||||
description?: string;
|
||||
|
|
|
|||
|
|
@ -89,6 +89,13 @@ function validateRoutes(
|
|||
if (r.stop !== undefined && typeof r.stop !== "boolean") {
|
||||
return { ok: false, error: `route "${r.id}".stop must be a boolean` };
|
||||
}
|
||||
if (
|
||||
r.discordRoleIds !== undefined &&
|
||||
(!Array.isArray(r.discordRoleIds) ||
|
||||
!r.discordRoleIds.every((d) => typeof d === "string" && d.trim().length > 0))
|
||||
) {
|
||||
return { ok: false, error: `route "${r.id}".discordRoleIds must be a list of strings` };
|
||||
}
|
||||
if (!Array.isArray(r.filters)) {
|
||||
return { ok: false, error: `route "${r.id}".filters must be an array` };
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue