diff --git a/src/commands/CommandHandler.ts b/src/commands/CommandHandler.ts index fea8811d..14a5f631 100644 --- a/src/commands/CommandHandler.ts +++ b/src/commands/CommandHandler.ts @@ -39,6 +39,7 @@ import { execConfigSetProtection, execConfigAddProtection, execConfigRemoveProtection } from "./ProtectionsCommands"; import { execSetPowerLevelCommand } from "./SetPowerLevelCommand"; +import { execSetDisplayNameCommand } from "./SetDisplayNameCommand"; import { execResolveCommand } from "./ResolveAlias"; import { execKickCommand } from "./KickCommand"; import { parse as tokenize } from "shell-quote"; @@ -120,11 +121,13 @@ export async function handleCommand(roomId: string, event: { content: { body: st return await execSinceCommand(roomId, event, mjolnir, tokens); } else if (parts[1] === 'kick' && parts.length > 2) { return await execKickCommand(roomId, event, mjolnir, parts); + } else if (parts[1] === 'displayname' && parts.length > 2) { + return await execSetDisplayNameCommand(roomId, event, mjolnir, parts); } else { const readItems = readCommand(cmd).slice(1); // remove "!mjolnir" const stream = new ArgumentStream(readItems); const command = commandTable.findAMatchingCommand(stream) - ?? findTableCommand("mjolnir", "help"); + ?? findTableCommand("mjolnir", "help"); const adaptor = findMatrixInterfaceAdaptor(command); const mjolnirContext: MjolnirContext = { mjolnir, roomId, event, client: mjolnir.client, emitter: mjolnir.matrixEmitter, diff --git a/src/commands/Help.tsx b/src/commands/Help.tsx index fbf911e9..2422ea90 100644 --- a/src/commands/Help.tsx +++ b/src/commands/Help.tsx @@ -35,28 +35,29 @@ import { defineMatrixInterfaceAdaptor } from "./interface-manager/MatrixInterfac import { renderMatrixAndSend } from "./interface-manager/DeadDocumentMatrix"; const oldHelpMenu = "" + -"!mjolnir - Print status information\n" + -"!mjolnir status - Print status information\n" + -"!mjolnir status protection [subcommand] - Print status information for a protection\n" + -"!mjolnir redact [room alias/ID] [limit] - Redacts messages by the sender in the target room (or all rooms), up to a maximum number of events in the backlog (default 1000)\n" + -"!mjolnir redact - Redacts a message by permalink\n" + -"!mjolnir kick [room alias/ID] [reason] - Kicks a user or all of those matching a glob in a particular room or all protected rooms\n" + -"!mjolnir sync - Force updates of all lists and re-apply rules\n" + -"!mjolnir verify - Ensures Mjolnir can moderate all your rooms\n" + -"!mjolnir list create - Creates a new ban list with the given shortcode and alias\n" + -"!mjolnir import - Imports bans and ACLs into the given list\n" + -"!mjolnir default - Sets the default list for commands\n" + -"!mjolnir protections - List all available protections\n" + -"!mjolnir enable - Enables a particular protection\n" + -"!mjolnir disable - Disables a particular protection\n" + -"!mjolnir config set . [value] - Change a protection setting\n" + -"!mjolnir config add . [value] - Add a value to a list protection setting\n" + -"!mjolnir config remove . [value] - Remove a value from a list protection setting\n" + -"!mjolnir config get [protection] - List protection settings\n" + -"!mjolnir resolve - Resolves a room alias to a room ID\n" + -"!mjolnir since / [rooms...] [reason] - Apply an action ('kick', 'ban', 'mute', 'unmute' or 'show') to all users who joined a room since / (up to users)\n" + -"!mjolnir powerlevel [room alias/ID] - Sets the power level of the user in the specified room (or all protected rooms)\n" + -"!mjolnir help - This menu\n"; + "!mjolnir - Print status information\n" + + "!mjolnir status - Print status information\n" + + "!mjolnir status protection [subcommand] - Print status information for a protection\n" + + "!mjolnir redact [room alias/ID] [limit] - Redacts messages by the sender in the target room (or all rooms), up to a maximum number of events in the backlog (default 1000)\n" + + "!mjolnir redact - Redacts a message by permalink\n" + + "!mjolnir kick [room alias/ID] [reason] - Kicks a user or all of those matching a glob in a particular room or all protected rooms\n" + + "!mjolnir sync - Force updates of all lists and re-apply rules\n" + + "!mjolnir verify - Ensures Mjolnir can moderate all your rooms\n" + + "!mjolnir list create - Creates a new ban list with the given shortcode and alias\n" + + "!mjolnir import - Imports bans and ACLs into the given list\n" + + "!mjolnir default - Sets the default list for commands\n" + + "!mjolnir protections - List all available protections\n" + + "!mjolnir enable - Enables a particular protection\n" + + "!mjolnir disable - Disables a particular protection\n" + + "!mjolnir config set . [value] - Change a protection setting\n" + + "!mjolnir config add . [value] - Add a value to a list protection setting\n" + + "!mjolnir config remove . [value] - Remove a value from a list protection setting\n" + + "!mjolnir config get [protection] - List protection settings\n" + + "!mjolnir resolve - Resolves a room alias to a room ID\n" + + "!mjolnir since / [rooms...] [reason] - Apply an action ('kick', 'ban', 'mute', 'unmute' or 'show') to all users who joined a room since / (up to users)\n" + + "!mjolnir powerlevel [room alias/ID] - Sets the power level of the user in the specified room (or all protected rooms)\n" + + "!mjolnir displayname - Sets the displayname of the draupnir instance to the specified value in all rooms.\n" + + "!mjolnir help - This menu\n"; function renderTableHelp(table: CommandTable): DocumentNode { // FIXME: is it possible to force case of table names? @@ -82,14 +83,14 @@ function renderMjolnirHelp(mjolnirTable: CommandTable): DocumentNode { defineInterfaceCommand({ parameters: parameters([], new RestDescription('command parts', findPresentationType("any"))), table: "mjolnir", - command: async function() { return CommandResult.Ok(findCommandTable("mjolnir")) }, + command: async function () { return CommandResult.Ok(findCommandTable("mjolnir")) }, designator: ["help"], summary: "Display this message" }) defineMatrixInterfaceAdaptor({ interfaceCommand: findTableCommand("mjolnir", "help"), - renderer: async function(client, commandRoomId, event, result) { + renderer: async function (client, commandRoomId, event, result) { if (result.isErr()) { throw new TypeError("This command isn't supposed to fail"); } diff --git a/src/commands/SetDisplayNameCommand.ts b/src/commands/SetDisplayNameCommand.ts index e69de29b..e6b96461 100644 --- a/src/commands/SetDisplayNameCommand.ts +++ b/src/commands/SetDisplayNameCommand.ts @@ -0,0 +1,21 @@ +import { Mjolnir } from "../Mjolnir"; +import { LogLevel, LogService } from "matrix-bot-sdk"; + +// !draupnir displayname +export async function execSetDisplayNameCommand(roomId: string, event: any, mjolnir: Mjolnir, parts: string[]) { + const displayname = parts[2]; + + let targetRooms = mjolnir.protectedRoomsTracker.getProtectedRooms(); + + for (const targetRoomId of targetRooms) { + try { + await mjolnir.client.setDisplayName(displayname); + } catch (e) { + const message = e.message || (e.body ? e.body.error : ''); + LogService.error("SetDisplayNameCommand", e); + await mjolnir.managementRoomOutput.logMessage(LogLevel.ERROR, "SetDisplayNameCommand", `Failed to set displayname to ${displayname} in ${targetRoomId}: ${message}`, targetRoomId); + } + } + + await mjolnir.client.unstableApis.addReactionToEvent(roomId, event['event_id'], '✅'); +}