mirror of
https://github.com/the-draupnir-project/Draupnir.git
synced 2026-10-22 17:11:17 +00:00
Two appservice bot commands to test with.
One lists unstarted mjolnirs, and one allows you to try restart them.
This commit is contained in:
1 parent
203f42dc0e
commit
de9a0a078b
2 files changed
+163
No files matched your search
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* Copyright (C) 2022 Gnuxie <Gnuxie@protonmail.com>
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
import { WeakEvent } from 'matrix-appservice-bridge';
|
||||
import { readCommand } from '../../commands/interface-manager/CommandReader';
|
||||
import { defineCommandTable, defineInterfaceCommand, findCommandTable } from '../../commands/interface-manager/InterfaceCommand';
|
||||
import { defineMatrixInterfaceAdaptor, findMatrixInterfaceAdaptor, MatrixContext } from '../../commands/interface-manager/MatrixInterfaceAdaptor';
|
||||
import { ArgumentStream, paramaters } from '../../commands/interface-manager/ParamaterParsing';
|
||||
import { MjolnirAppService } from '../AppService';
|
||||
import { CommandResult } from '../../commands/interface-manager/Validation';
|
||||
import { renderHelp } from '../../commands/interface-manager/MatrixHelpRenderer';
|
||||
|
||||
defineCommandTable("appservice bot");
|
||||
|
||||
export interface AppserviceContext extends MatrixContext {
|
||||
appservice: MjolnirAppService;
|
||||
}
|
||||
|
||||
export type AppserviceBaseExecutor = (this: AppserviceContext, ...args: any[]) => Promise<CommandResult<any>>;
|
||||
|
||||
import '../../commands/interface-manager/MatrixPresentations';
|
||||
import './ListCommand';
|
||||
|
||||
|
||||
const helpCommand = defineInterfaceCommand({
|
||||
paramaters: paramaters([]),
|
||||
table: "appservice bot",
|
||||
command: async function() { return CommandResult.Ok(findCommandTable("appservice bot").getCommands()) },
|
||||
designator: ["help"],
|
||||
summary: "Display this message"
|
||||
})
|
||||
|
||||
defineMatrixInterfaceAdaptor({
|
||||
interfaceCommand: helpCommand,
|
||||
renderer: renderHelp
|
||||
})
|
||||
|
||||
export class AppserviceCommandHandler {
|
||||
private readonly commandTable = findCommandTable("appservice bot");
|
||||
|
||||
constructor (
|
||||
private readonly appservice: MjolnirAppService
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
public handleEvent(mxEvent: WeakEvent): void {
|
||||
if (mxEvent.type !== 'm.room.message' && mxEvent.room_id !== this.appservice.config.adminRoom) {
|
||||
return;
|
||||
}
|
||||
const body = typeof mxEvent.content['body'] === 'string' ? mxEvent.content['body'] : '';
|
||||
if (body.startsWith(this.appservice.bridge.getBot().getUserId())) {
|
||||
const readItems = readCommand(body).slice(1); // remove "!mjolnir"
|
||||
const argumentStream = new ArgumentStream(readItems);
|
||||
const command = this.commandTable.findAMatchingCommand(argumentStream);
|
||||
// FIXME: what if there's no command, print help?
|
||||
if (command) {
|
||||
const adaptor = findMatrixInterfaceAdaptor(command);
|
||||
const context: AppserviceContext = {
|
||||
appservice: this.appservice,
|
||||
roomId: mxEvent.room_id,
|
||||
event: mxEvent,
|
||||
client: this.appservice.bridge.getBot().getClient()
|
||||
};
|
||||
adaptor.invoke(context, context, ...argumentStream.rest());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
/**
|
||||
* Copyright (C) 2022 Gnuxie <Gnuxie@protonmail.com>
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
import { defineMatrixInterfaceAdaptor, MatrixContext, MatrixInterfaceAdaptor } from '../../commands/interface-manager/MatrixInterfaceAdaptor';
|
||||
import { MatrixSendClient } from '../../MatrixEmitter';
|
||||
import { htmlEscape } from '../../utils';
|
||||
import { UnstartedMjolnir } from '../MjolnirManager';
|
||||
import { BaseFunction, defineInterfaceCommand } from '../../commands/interface-manager/InterfaceCommand';
|
||||
import { findPresentationType, paramaters } from '../../commands/interface-manager/ParamaterParsing';
|
||||
import { AppserviceBaseExecutor } from './AppserviceCommandHandler';
|
||||
import { UserID } from 'matrix-bot-sdk';
|
||||
import { CommandError, CommandResult } from '../../commands/interface-manager/Validation';
|
||||
import { tickCrossRenderer } from '../../commands/interface-manager/MatrixHelpRenderer';
|
||||
|
||||
/**
|
||||
* There is ovbiously something we're doing very wrong here,
|
||||
* all just to satisfy type contstraints.
|
||||
* Really there should only be `defineApplicationCommand`
|
||||
* and `defineMatrixInterfaceCommand` but we have to do this
|
||||
* long winded dance just to make type contstraints work.
|
||||
* There might be a better way, but at what cost.
|
||||
*/
|
||||
|
||||
const listUnstarted = defineInterfaceCommand<AppserviceBaseExecutor>({
|
||||
designator: ["list", "unstarted"],
|
||||
table: "appservice bot",
|
||||
paramaters: paramaters([]),
|
||||
command: async function() {
|
||||
return CommandResult.Ok(this.appservice.mjolnirManager.getUnstartedMjolnirs());
|
||||
},
|
||||
summary: "List any Mjolnir that failed to start."
|
||||
});
|
||||
|
||||
defineMatrixInterfaceAdaptor({
|
||||
interfaceCommand: listUnstarted,
|
||||
renderer: async function(this: MatrixInterfaceAdaptor<MatrixContext, BaseFunction>, client: MatrixSendClient, commandRoomId: string, event: any, result: CommandResult<UnstartedMjolnir[]>) {
|
||||
tickCrossRenderer.call(this, client, commandRoomId, event, result); // don't await, it doesn't really matter.
|
||||
if (result.isErr()) {
|
||||
return; // just let the default handler deal with it.
|
||||
}
|
||||
const unstarted = result.ok;
|
||||
let text = '';
|
||||
let html = '';
|
||||
html += `<b>Unstarted mjolnir: </b> ${unstarted.length}<br/>`;
|
||||
text += `Unstarted mjolnir: ${unstarted.length}\n`;
|
||||
|
||||
html += "<li>";
|
||||
for (const mjolnir of unstarted) {
|
||||
html += `<ul>${htmlEscape(mjolnir.mjolnirRecord.owner)}, <code>${htmlEscape(mjolnir.mxid.toString())}</code>, <code>${mjolnir.failCode}</code>:\n${mjolnir.cause}</ul>`
|
||||
text += ` * ${htmlEscape(mjolnir.mjolnirRecord.owner)}, ${htmlEscape(mjolnir.mxid.toString())}, ${mjolnir.failCode}: ${mjolnir.cause}`;
|
||||
}
|
||||
html += "</li>";
|
||||
await client.sendMessage(commandRoomId, {
|
||||
msgtype: 'm.notice',
|
||||
body: text,
|
||||
formatted_body: html,
|
||||
});
|
||||
}
|
||||
})
|
||||
|
||||
// We need a "default" adaptor that needs to be explicitly defined still
|
||||
// (since you need to know if you have not created an adaptor)
|
||||
// but can be composed onto the end of existing adaptors easily
|
||||
// e.g. read recipt and tick vs cross.
|
||||
const restart = defineInterfaceCommand<AppserviceBaseExecutor>({
|
||||
designator: ["restart"],
|
||||
table: "appservice bot",
|
||||
paramaters: paramaters([
|
||||
{
|
||||
name: "mjolnir",
|
||||
acceptor: findPresentationType("UserID"),
|
||||
}
|
||||
]),
|
||||
command: async(context, mjolnirId: UserID): Promise<CommandResult<true>> => {
|
||||
const mjolnirManager = context.appservice.mjolnirManager;
|
||||
const mjolnir = mjolnirManager.findUnstartedMjolnir(mjolnirId.localpart);
|
||||
if (mjolnir?.mjolnirRecord === undefined) {
|
||||
return CommandError.Result(`We can't find the unstarted mjolnir ${mjolnirId}, is it running?`);
|
||||
}
|
||||
await mjolnirManager.startMjolnir(mjolnir?.mjolnirRecord);
|
||||
return CommandResult.Ok(true);
|
||||
},
|
||||
summary: "Attempt to restart a Mjolnir."
|
||||
})
|
||||
|
||||
defineMatrixInterfaceAdaptor({
|
||||
interfaceCommand: restart,
|
||||
renderer: tickCrossRenderer
|
||||
})
|
||||
Reference in new issue
Block a user