Add assign and close commands

This commit is contained in:
Half-Shot 2020-07-20 16:06:12 +01:00
parent a4e7601ee6
commit ae2a317b57
3 changed files with 90 additions and 14 deletions

View File

@ -251,11 +251,21 @@ export class AdminRoom extends EventEmitter {
}
}
public async handleCommand(command: string) {
const err = handleCommand(this.userId, command, AdminRoom.botCommands, this);
if (err) {
await this.sendNotice(err);
public async handleCommand(event_id: string, command: string) {
const { error, handled } = await handleCommand(this.userId, command, AdminRoom.botCommands, this);
if (!handled) {
return this.sendNotice("Command not understood");
}
if (error) {
return this.sendNotice("Failed to handle command:" + error);
}
return this.botIntent.underlyingClient.sendEvent(this.roomId, "m.reaction", {
"m.relates_to": {
rel_type: "m.annotation",
event_id: event_id,
key: "✅",
}
});
}
}

View File

@ -1,6 +1,7 @@
import markdown from "markdown-it";
// @ts-ignore
import argvSplit from "argv-split";
import e from "express";
const md = new markdown();
@ -16,7 +17,7 @@ export function botCommand(prefix: string, help: string, requiredArgs: string[]
}
export type BotCommands = {[prefix: string]: {
fn: (...args: string[]) => Promise<void>,
fn: (...args: string[]) => Promise<{status: boolean}>,
requiredArgs: string[],
optionalArgs: string[],
includeUserId: boolean,
@ -51,7 +52,7 @@ export function compileBotCommands(prototype: any): {helpMessage: any, botComman
}
}
export function handleCommand(userId: string, command: string, botCommands: BotCommands, obj: any, errorOnUnknown=true): string|null {
export async function handleCommand(userId: string, command: string, botCommands: BotCommands, obj: any): Promise<{error?: string, handled?: boolean}> {
const cmdLower = command.toLowerCase();
const parts = argvSplit(cmdLower);
for (let i = parts.length; i > 0; i--) {
@ -60,15 +61,19 @@ export function handleCommand(userId: string, command: string, botCommands: BotC
const command = botCommands[prefix];
if (command) {
if (command.requiredArgs.length > parts.length - i) {
return "Missing args";
return {error: "Missing args"};
}
const args = parts.slice(i);
if (command.includeUserId) {
args.splice(0,0, userId);
}
botCommands[prefix].fn.apply(obj, args);
return null;
try {
await botCommands[prefix].fn.apply(obj, args);
return {handled: true};
} catch (ex) {
return {handled: true, error: ex.message};
}
}
}
return errorOnUnknown ? "Command not understood" : null;
return {handled: false};
}

View File

@ -159,14 +159,30 @@ export class GitHubRepoConnection implements IConnection {
}
public async onMessageEvent(ev: MatrixEvent<MatrixMessageContent>) {
const err = handleCommand(ev.sender, ev.content.body, GitHubRepoConnection.botCommands, this, false);
if (err) {
await this.as.botIntent.sendText(this.roomId, err, "m.notice");
const { error, handled } = await handleCommand(ev.sender, ev.content.body, GitHubRepoConnection.botCommands, this);
if (!handled) {
// Not for us.
return;
}
if (error) {
await this.as.botIntent.sendEvent(this.roomId,{
msgtype: "m.notice",
body: "Failed to handle command",
});
return;
}
await this.as.botClient.sendEvent(this.roomId, "m.reaction", {
"m.relates_to": {
rel_type: "m.annotation",
event_id: ev.event_id,
key: "✅",
}
});
}
@botCommand("gh create", "Create an issue for this repo", ["title"], ["description", "labels"], true)
public async onCreateIssue(userId: string, title: string, description?: string, labels?: string) {
// @ts-ignore
private async onCreateIssue(userId: string, title: string, description?: string, labels?: string) {
const octokit = await this.tokenStore.getOctokitForUser(userId);
if (!octokit) {
return this.as.botIntent.sendText(this.roomId, "You must login to create an issue", "m.notice");
@ -189,6 +205,51 @@ export class GitHubRepoConnection implements IConnection {
});
}
@botCommand("gh assign", "Assign an issue to a user", ["number", "...users"], [], true)
// @ts-ignore
private async onAssign(userId: string, number: string, ...users: string[]) {
const octokit = await this.tokenStore.getOctokitForUser(userId);
if (!octokit) {
return this.as.botIntent.sendText(this.roomId, "You must login to assign an issue", "m.notice");
}
if (users.length === 1) {
users = users[0].split(",");
}
await octokit.issues.addAssignees({
repo: this.state.repo,
owner: this.state.org,
issue_number: parseInt(number, 10),
assignees: users,
});
}
@botCommand("gh close", "Close an issue", ["number"], ["comment"], true)
// @ts-ignore
private async onAssign(userId: string, number: string, comment?: string) {
const octokit = await this.tokenStore.getOctokitForUser(userId);
if (!octokit) {
return this.as.botIntent.sendText(this.roomId, "You must login to close an issue", "m.notice");
}
if (comment) {
await octokit.issues.createComment({
repo: this.state.repo,
owner: this.state.org,
issue_number: parseInt(number, 10),
body: comment,
})
}
await octokit.issues.update({
repo: this.state.repo,
owner: this.state.org,
issue_number: parseInt(number, 10),
state: "closed",
});
}
public async onIssueCreated(event: IGitHubWebhookEvent) {
log.info(`onIssueCreated ${this.roomId} ${this.org}/${this.repo} #${event.issue?.number}`);
const orgRepoName = event.issue!.repository_url.substr("https://api.github.com/repos/".length);