Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
f58c142
Remove reason requirement from slash unban command
seeyebe Jun 6, 2025
04b8914
feat: Add custom add_message and remove_message support to role buttons
seeyebe Jun 7, 2025
242015c
fix: handle button interactions properly for slash commands
seeyebe Jun 9, 2025
25771f2
feat: add embed support to welcome messages
seeyebe Jun 11, 2025
863ef3d
Update CaseMsgCmd.ts
seeyebe Jul 8, 2025
f9c566b
Update actualCaseCmd.ts
seeyebe Jul 8, 2025
ea59b88
feat: add reply info in message delete log
seeyebe Sep 26, 2025
b467c39
feat: add has_attachments trigger
seeyebe Sep 26, 2025
8b6cf4b
chore: run formatter
almeidx Jun 1, 2025
886b79b
fix: package-lock newlines
Dragory Nov 8, 2025
752a138
Merge pull request #512 from ZeppelinBot/chore/format
Dragory Nov 9, 2025
cee4e20
build(deps): bump the github-actions group with 2 updates (#513)
dependabot[bot] Nov 9, 2025
2be9f30
dev: update devenv to Node 24; add pnpm
Dragory Nov 10, 2025
677e24a
refactor: replace npm workspace with pnpm monorepo
Dragory Nov 10, 2025
a36f4f1
feat: update TS to 5.9.3, Knub to 32.0.0-next.27, djs to 14.23.2
Dragory Nov 10, 2025
b9f3c2a
chore: normalize zod imports
Dragory Nov 10, 2025
9ec63fa
chore: update to knub@32.0.0-next.28
Dragory Nov 10, 2025
d77a509
fix: type errors
Dragory Nov 10, 2025
47e948c
feat: use pnpm in codequality workflow
Dragory Nov 10, 2025
a8f2c7f
chore: update .nvmrc
Dragory Nov 10, 2025
d848c8b
build: use pnpm in Dockerfile; node 24
Dragory Nov 10, 2025
2f3c3ad
chore: set package.json engines to 24+
Dragory Nov 10, 2025
ebe8dff
chore: npm -> pnpm
Dragory Nov 10, 2025
1694309
chore: mark pnpm-lock.yaml as binary for git
Dragory Nov 11, 2025
c2f05ad
feat: add CommandAliases plugin
seeyebe Nov 11, 2025
6aa7982
chore: remove leftover comment in DispatchAliasEvt
seeyebe Nov 11, 2025
9665704
chore: fix missing comma in CommandAliases plugin docs
seeyebe Nov 11, 2025
1fc524b
chore: knub -> vety
Dragory Nov 13, 2025
30548b8
Merge branch 'master' into feat/commands-aliases
seeyebe Nov 13, 2025
73b0e29
fix: typeorm commands
Dragory Nov 13, 2025
cec1bf3
feat: redis support
Dragory Nov 13, 2025
9c3ac7f
chore: npm -> pnpm in start-dev.js
Dragory Nov 13, 2025
a1000ce
chore: add warning traces for dev
Dragory Nov 13, 2025
c58ac36
chore: ready -> clientReady
Dragory Nov 13, 2025
50376b1
fix: FishFish session token expiry time calculation
Dragory Nov 13, 2025
3fd88b6
fix: disable non-functional FishFish websocket connection
Dragory Nov 13, 2025
5d864e8
feat: debug counters
Dragory Nov 13, 2025
b802e4d
feat(getOrFetchUser): redis cache; use debug counters
Dragory Nov 13, 2025
2ad152d
refactor(resolveUser): use getOrFetchUser internally; debug counters
Dragory Nov 13, 2025
ee57e6c
chore: update typeorm
Dragory Nov 13, 2025
80d1719
chore: remove debug log
Dragory Nov 13, 2025
6ae477b
chore: update tmp package
Dragory Nov 13, 2025
e0bc978
chore: remove unnecessary @types/moment-timezone package
Dragory Nov 13, 2025
f5472d4
chore: remove clinic package
Dragory Nov 13, 2025
6f2b027
chore: remove unused rimraf package
Dragory Nov 13, 2025
5ba4053
chore: update multer package
Dragory Nov 13, 2025
8b7d656
refactor: change import from 'knub' to 'vety'
seeyebe Nov 13, 2025
78f3d50
refactor: change import from 'knub' to 'vety'
seeyebe Nov 13, 2025
eb1fa28
debug: resolveUser context
Dragory Nov 13, 2025
8cf91c1
Merge pull request #570 from seeyebe/feat/commands-aliases
Dragory Nov 13, 2025
bc42741
refactor: change import from 'zod/v4' to 'zod'
seeyebe Nov 13, 2025
02d3c3e
Merge pull request #560 from seeyebe/feat/has_attachment-trigger
Dragory Nov 13, 2025
6cdc263
fix: getKnubInstance -> getVetyInstance
Dragory Nov 13, 2025
63510a5
fix: initial load plugin error ignoring
Dragory Nov 13, 2025
0ac6928
refactor(automod): replace "has" with "min_count"/"max_count" in has_…
Dragory Nov 13, 2025
cee5623
fix: migration commands
Dragory Nov 13, 2025
d2c73fd
chore: ignore pnpm store + other files from docker
Dragory Nov 13, 2025
79c5438
docs: update update docs
Dragory Nov 13, 2025
1ecc163
chore: replace console.log() with debug counters
Dragory Nov 13, 2025
175d266
debug: add debug counter for runAutomodOnMessage
Dragory Nov 13, 2025
4e23036
fix: !cases not working with user id
Dragory Nov 13, 2025
82087ea
fix: catch reaction invalid emoji errors
Dragory Nov 13, 2025
f4764d3
Merge branch 'master' into feat/welcome-message-embed-support
seeyebe Nov 14, 2025
67a3e2a
Merge branch 'master' into fix/button-interaction-acknowledgment
seeyebe Nov 14, 2025
8c49fa7
Merge branch 'master' into feat/role-buttons-custom-messages
seeyebe Nov 14, 2025
f7a20fb
Merge branch 'master' into fix/slash-unban-reason-validation
seeyebe Nov 14, 2025
8039edf
Merge branch 'master' into feat/log-replied-message
seeyebe Nov 14, 2025
1a61bc0
Merge branch 'master' into fix/remove-prefix-case-show-flag
seeyebe Nov 14, 2025
6959d8a
fix: crash when cleaning 0 messages
Dragory Nov 15, 2025
ec09c17
feat: bake build info into image
Dragory Nov 15, 2025
26bbe55
chore: remove unused packages
Dragory Nov 15, 2025
13fbddd
Merge pull request #559 from seeyebe/feat/log-replied-message
Dragory Nov 15, 2025
8f883e5
Merge pull request #549 from seeyebe/fix/remove-prefix-case-show-flag
Dragory Nov 15, 2025
07401ba
Merge pull request #532 from seeyebe/feat/role-buttons-custom-messages
Dragory Nov 15, 2025
e311279
Merge pull request #531 from seeyebe/fix/slash-unban-reason-validation
Dragory Nov 15, 2025
81db425
fix: knub -> vety
Dragory Nov 15, 2025
5227e6c
fix: missing import
Dragory Nov 15, 2025
7218fbd
chore: align welcome DMs with MessageContent helper
seeyebe Nov 15, 2025
0ff6d91
Merge pull request #540 from seeyebe/feat/welcome-message-embed-support
Dragory Nov 15, 2025
942b8d0
Merge pull request #537 from seeyebe/fix/button-interaction-acknowled…
Dragory Nov 15, 2025
ec57153
fix: update imports for Logs plugin to use correct modules
seeyebe Nov 15, 2025
77e356b
Merge pull request #573 from seeyebe/fix/fixes
Dragory Nov 15, 2025
6795bf7
Merge branch 'master' of github.com:ZeppelinBot/Zeppelin
Dragory Nov 15, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

**/node_modules
**/dist
**/.pnpm-store
**/.docker

**/*.log
**/npm-debug.log*
Expand Down Expand Up @@ -35,6 +37,7 @@
# Debug files
**/*.debug.ts
**/*.debug.js
/debug

**/.vscode

Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
package-lock.json binary
pnpm-lock.yaml binary
26 changes: 13 additions & 13 deletions .github/workflows/codequality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,18 @@ jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [22]

steps:
- uses: actions/checkout@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8

- uses: actions/setup-node@2028fbc5c25fe9cf00d9f06a71cc4710d4507903
with:
node-version: ${{ matrix.node-version }}
- name: npm install, lint, code style check
run: |
npm ci
npm run lint
npm run codestyle-check
node-version: 24

- uses: pnpm/action-setup@41ff72655975bd51cab0327fa583b6e92b6d3061
with:
version: 10.19.0
run_install: true

- run: |
pnpm run lint
pnpm run codestyle-check
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ build/Release
# Dependency directories
node_modules/
jspm_packages/
.pnpm-store

# Typescript v1 declaration files
typings/
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
22
24
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The project is called Zeppelin. It's a Discord bot that uses Discord.js. The bot is built on the Knub framework.
The project is called Zeppelin. It's a Discord bot that uses Discord.js. The bot is built on the Vety framework (formerly called Knub).

This repository is a monorepository that contains these projects:
1. **Backend**: The shared codebase of the bot and API. Located in `backend`.
Expand Down
32 changes: 24 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
FROM node:22 AS build
FROM node:24 AS build

ARG COMMIT_HASH
ARG BUILD_TIME

RUN mkdir /zeppelin
RUN chown node:node /zeppelin

# Install pnpm
RUN npm install -g pnpm@10.19.0

USER node

# Install dependencies before copying over any other files
COPY --chown=node:node package.json package-lock.json /zeppelin
COPY --chown=node:node package.json pnpm-workspace.yaml pnpm-lock.yaml /zeppelin
RUN mkdir /zeppelin/backend
COPY --chown=node:node backend/package.json /zeppelin/backend
RUN mkdir /zeppelin/shared
Expand All @@ -15,23 +21,33 @@ RUN mkdir /zeppelin/dashboard
COPY --chown=node:node dashboard/package.json /zeppelin/dashboard

WORKDIR /zeppelin
RUN npm ci
RUN CI=true pnpm install

COPY --chown=node:node . /zeppelin

# Build backend
WORKDIR /zeppelin/backend
RUN npm run build
RUN pnpm run build

# Build dashboard
WORKDIR /zeppelin/dashboard
RUN npm run build
RUN pnpm run build

# Prune dev dependencies
# Only keep prod dependencies
WORKDIR /zeppelin
RUN npm prune --omit=dev
RUN CI=true pnpm install --prod

# Add version info
RUN echo "${COMMIT_HASH}" > /zeppelin/.commit-hash
RUN echo "${BUILD_TIME}" > /zeppelin/.build-time

# --- Main image ---

FROM node:22-alpine AS main
FROM node:24-alpine AS main

RUN npm install -g pnpm@10.19.0

USER node
COPY --from=build --chown=node:node /zeppelin /zeppelin

WORKDIR /zeppelin
53 changes: 22 additions & 31 deletions backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,78 +11,71 @@
"watch": "tsc-watch --build --onSuccess \"node start-dev.js\"",
"watch-yaml-parse-test": "tsc-watch --build --onSuccess \"node dist/yamlParseTest.js\"",
"build": "tsc --build",
"start-bot-dev": "node --enable-source-maps --stack-trace-limit=30 --inspect=0.0.0.0:9229 dist/index.js",
"start-bot-dev-debug": "DEBUG=true clinic heapprofiler --collect-only --dest .clinic-bot -- node --enable-source-maps --stack-trace-limit=30 --inspect=0.0.0.0:9229 dist/index.js",
"start-bot-prod": "node --enable-source-maps --stack-trace-limit=30 dist/index.js",
"start-bot-prod-debug": "DEBUG=true clinic heapprofiler --collect-only --dest .clinic-bot -- node --enable-source-maps --stack-trace-limit=30 dist/index.js",
"watch-bot": "tsc-watch --build --onSuccess \"npm run start-bot-dev\"",
"typecheck": "tsc --noEmit",
"start-bot-dev": "node --enable-source-maps --stack-trace-limit=30 --trace-warnings --inspect=0.0.0.0:9229 dist/index.js",
"start-bot-prod": "node --enable-source-maps --stack-trace-limit=30 --trace-warnings dist/index.js",
"watch-bot": "tsc-watch --build --onSuccess \"pnpm run start-bot-dev\"",
"start-api-dev": "node --enable-source-maps --stack-trace-limit=30 --inspect=0.0.0.0:9239 dist/api/index.js",
"start-api-dev-debug": "DEBUG=true clinic heapprofiler --collect-only --dest .clinic-api -- node --enable-source-maps --stack-trace-limit=30 --inspect=0.0.0.0:9239 dist/api/index.js",
"start-api-prod": "node --enable-source-maps --stack-trace-limit=30 dist/api/index.js",
"start-api-prod-debug": "clinic heapprofiler --collect-only --dest .clinic-api -- node --enable-source-maps --stack-trace-limit=30 dist/api/index.js",
"watch-api": "tsc-watch --build --onSuccess \"npm run start-api-dev\"",
"typeorm": "node ../node_modules/typeorm/cli.js",
"migrate": "npm run typeorm -- migration:run -d dist/data/dataSource.js",
"migrate-prod": "npm run migrate",
"migrate-dev": "npm run build && npm run migrate",
"migrate-rollback": "npm run typeorm -- migration:revert -d dist/data/dataSource.js",
"migrate-rollback-prod": "npm run migrate-rollback",
"migrate-rollback-dev": "npm run build && npm run migrate-rollback",
"watch-api": "tsc-watch --build --onSuccess \"pnpm run start-api-dev\"",
"migrate": "pnpm exec typeorm migration:run -d dist/data/dataSource.js",
"migrate-prod": "pnpm run migrate",
"migrate-dev": "pnpm run build && pnpm run migrate",
"migrate-rollback": "pnpm exec typeorm migration:revert -d dist/data/dataSource.js",
"migrate-rollback-prod": "pnpm run migrate-rollback",
"migrate-rollback-dev": "pnpm run build && pnpm run migrate-rollback",
"validate-active-configs": "node --enable-source-maps dist/validateActiveConfigs.js > ../config-errors.txt",
"export-config-json-schema": "node --enable-source-maps dist/exportSchemas.js ../config-checker/public/config-schema.json",
"test": "npm run build && npm run run-tests",
"test": "pnpm run build && pnpm run run-tests",
"run-tests": "ava",
"test-watch": "tsc-watch --build --onSuccess \"npx ava\""
"test-watch": "tsc-watch --build --onSuccess \"pnpm exec ava\""
},
"dependencies": {
"@silvia-odwyer/photon-node": "^0.3.1",
"@zeppelinbot/shared": "workspace:*",
"bufferutil": "^4.0.3",
"clinic": "^13.0.0",
"cors": "^2.8.5",
"cross-env": "^7.0.3",
"deep-diff": "^1.0.2",
"discord.js": "^14.19.3",
"discord.js": "*",
"emoji-regex": "^8.0.0",
"escape-string-regexp": "^1.0.5",
"express": "^4.20.0",
"fp-ts": "^2.0.1",
"humanize-duration": "^3.15.0",
"js-yaml": "^4.1.0",
"knub": "^32.0.0-next.25",
"knub-command-manager": "^9.1.0",
"last-commit-log": "^2.1.0",
"lodash-es": "^4.17.21",
"moment-timezone": "^0.5.21",
"multer": "^1.4.5-lts.1",
"multer": "^2.0.2",
"mysql2": "^3.9.8",
"parse-color": "^1.0.0",
"passport": "^0.6.0",
"passport-custom": "^1.0.5",
"passport-oauth2": "^1.6.1",
"pkg-up": "^3.1.0",
"redis": "^5.9.0",
"reflect-metadata": "^0.1.12",
"regexp-worker": "^1.1.0",
"safe-regex": "^2.0.2",
"seedrandom": "^3.0.1",
"strip-combining-marks": "^1.0.0",
"threads": "^1.7.0",
"tlds": "^1.221.1",
"tmp": "0.0.33",
"tmp": "0.2.5",
"tsconfig-paths": "^3.9.0",
"twemoji": "^12.1.4",
"typeorm": "^0.3.17",
"typeorm": "^0.3.27",
"utf-8-validate": "^5.0.5",
"uuid": "^9.0.0",
"yawn-yaml": "github:dragory/yawn-yaml#string-number-fix-build",
"zod": "^3.25.17"
"vety": "1.0.0-rc2",
"zod": "^4.1.12"
},
"devDependencies": {
"@types/cors": "^2.8.5",
"@types/express": "^4.16.1",
"@types/jest": "^24.0.15",
"@types/js-yaml": "^3.12.1",
"@types/lodash-es": "^4.17.12",
"@types/moment-timezone": "^0.5.6",
"@types/multer": "^1.4.7",
"@types/passport": "^1.0.0",
"@types/passport-oauth2": "^1.4.8",
Expand All @@ -92,9 +85,7 @@
"@types/twemoji": "^12.1.0",
"@types/uuid": "^9.0.2",
"ava": "^5.3.1",
"rimraf": "^2.6.2",
"source-map-support": "^0.5.16",
"zod-to-json-schema": "^3.22.3"
"source-map-support": "^0.5.16"
},
"ava": {
"files": [
Expand Down
7 changes: 5 additions & 2 deletions backend/src/RegExpRunner.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CooldownManager } from "knub";
import { CooldownManager } from "vety";
import { EventEmitter } from "node:events";
import { RegExpWorker, TimeoutError } from "regexp-worker";
import { MINUTES, SECONDS } from "./utils.js";
Expand All @@ -9,7 +9,10 @@ const isTimeoutError = (a): a is TimeoutError => {
};

export class RegExpTimeoutError extends Error {
constructor(message: string, public elapsedTimeMs: number) {
constructor(
message: string,
public elapsedTimeMs: number,
) {
super(message);
}
}
Expand Down
2 changes: 1 addition & 1 deletion backend/src/api/auth.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import express, { Request, Response } from "express";
import https from "https";
import pick from "lodash/pick.js";
import { pick } from "lodash-es";
import passport from "passport";
import { Strategy as CustomStrategy } from "passport-custom";
import OAuth2Strategy from "passport-oauth2";
Expand Down
4 changes: 2 additions & 2 deletions backend/src/api/docs.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import express from "express";
import z from "zod/v4";
import { z } from "zod";
import { $ZodPipeDef } from "zod/v4/core";
import { availableGuildPlugins } from "../plugins/availablePlugins.js";
import { ZeppelinGuildPluginInfo } from "../types.js";
import { indentLines } from "../utils.js";
import { notFound } from "./responses.js";
import { $ZodPipeDef } from "zod/v4/core";

function isZodObject(schema: z.ZodType): schema is z.ZodObject<any> {
return schema.def.type === "object";
Expand Down
2 changes: 1 addition & 1 deletion backend/src/api/guilds/importExport.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { ApiPermissions } from "@zeppelinbot/shared/apiPermissions.js";
import express, { Request, Response } from "express";
import moment from "moment-timezone";
import { z } from "zod/v4";
import { z } from "zod";
import { GuildCases } from "../../data/GuildCases.js";
import { Case } from "../../data/entities/Case.js";
import { MINUTES } from "../../utils.js";
Expand Down
6 changes: 3 additions & 3 deletions backend/src/commandTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
CommandContext,
messageCommandBaseTypeConverters,
TypeConversionError,
} from "knub";
} from "vety";
import { createTypeHelper } from "knub-command-manager";
import {
channelMentionRegex,
Expand Down Expand Up @@ -41,15 +41,15 @@ export const commandTypes = {
},

async resolvedUser(value, context: CommandContext<any>) {
const result = await resolveUser(context.pluginData.client, value);
const result = await resolveUser(context.pluginData.client, value, "commandTypes:resolvedUser");
if (result == null || result instanceof UnknownUser) {
throw new TypeConversionError(`User \`${escapeCodeBlock(value)}\` was not found`);
}
return result;
},

async resolvedUserLoose(value, context: CommandContext<any>) {
const result = await resolveUser(context.pluginData.client, value);
const result = await resolveUser(context.pluginData.client, value, "commandTypes:resolvedUserLoose");
if (result == null) {
throw new TypeConversionError(`Invalid user: \`${escapeCodeBlock(value)}\``);
}
Expand Down
19 changes: 8 additions & 11 deletions backend/src/configValidator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { BaseConfig, ConfigValidationError, GuildPluginBlueprint, PluginConfigManager } from "knub";
import { z, ZodError } from "zod/v4";
import { BaseConfig, ConfigValidationError, GuildPluginBlueprint, PluginConfigManager } from "vety";
import { z, ZodError } from "zod";
import { availableGuildPlugins } from "./plugins/availablePlugins.js";
import { zZeppelinGuildConfig } from "./types.js";
import { formatZodIssue } from "./utils/formatZodIssue.js";
Expand Down Expand Up @@ -28,15 +28,12 @@ export async function validateGuildConfig(config: any): Promise<string | null> {
}

const plugin = pluginNameToPlugin.get(pluginName)!;
const configManager = new PluginConfigManager(
pluginOptions,
{
configSchema: plugin.configSchema,
defaultOverrides: plugin.defaultOverrides ?? [],
levels: {},
customOverrideCriteriaFunctions: plugin.customOverrideCriteriaFunctions,
},
);
const configManager = new PluginConfigManager(pluginOptions, {
configSchema: plugin.configSchema,
defaultOverrides: plugin.defaultOverrides ?? [],
levels: {},
customOverrideCriteriaFunctions: plugin.customOverrideCriteriaFunctions,
});

try {
await configManager.init();
Expand Down
4 changes: 2 additions & 2 deletions backend/src/data/DefaultLogMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
"ROLE_UPDATE": "{timestamp} 🖊 Role **{newRole.name}** (`{newRole.id}`) was edited. Changes:\n{differenceString}",

"MESSAGE_EDIT": "{timestamp} ✏ {userMention(user)} edited their message (`{after.id}`) in {channelMention(channel)}:\n**Before:**{messageSummary(before)}**After:**{messageSummary(after)}",
"MESSAGE_DELETE": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
"MESSAGE_DELETE": "{timestamp} 🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",
"MESSAGE_DELETE_BULK": "{timestamp} 🗑 **{count}** messages by {authorIds} deleted in {channelMention(channel)} ({archiveUrl})",
"MESSAGE_DELETE_BARE": "{timestamp} 🗑 Message (`{messageId}`) deleted in {channelMention(channel)} (no more info available)",
"MESSAGE_DELETE_AUTO": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
"MESSAGE_DELETE_AUTO": "{timestamp} 🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}{replyInfo}",

"VOICE_CHANNEL_JOIN": "{timestamp} 🎙 🔵 {userMention(member)} joined {channelMention(channel)}",
"VOICE_CHANNEL_MOVE": "{timestamp} 🎙 ↔ {userMention(member)} moved from {channelMention(oldChannel)} to {channelMention(newChannel)}",
Expand Down
Loading
Loading