diff --git a/config/default.yaml b/config/default.yaml index c219432..d46e24c 100644 --- a/config/default.yaml +++ b/config/default.yaml @@ -334,4 +334,7 @@ runMode: normal metrics: enabled: false port: 8081 - address: 127.0.0.1 \ No newline at end of file + address: 127.0.0.1 + +# if set to `true` will prevent the conf-bot from sending live invites to email/matrix_ids +dry_run_enabled: false \ No newline at end of file diff --git a/spec/util/e2e-test.ts b/spec/util/e2e-test.ts index 54fc4ab..b5b3745 100644 --- a/spec/util/e2e-test.ts +++ b/spec/util/e2e-test.ts @@ -223,6 +223,7 @@ export class E2ETestEnv { address: '0.0.0.0', port: 0, }, + dry_run_enabled: false, ...providedConfig, }; const conferenceBot = await ConferenceBot.start(config); diff --git a/src/IRCBridge.ts b/src/IRCBridge.ts index d230666..dc02055 100644 --- a/src/IRCBridge.ts +++ b/src/IRCBridge.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { MatrixClient, MatrixEvent } from "matrix-bot-sdk"; +import {LogService, MatrixClient, MatrixEvent} from "matrix-bot-sdk"; import * as irc from "irc-upd"; import { Auditorium } from "./models/Auditorium"; import { InterestRoom } from "./models/InterestRoom"; @@ -128,7 +128,8 @@ export class IRCBridge { public async plumbChannelToRoom(channel: string, roomId: string) { if (await this.shouldInviteBot(roomId)) { - await this.mxClient.inviteUser(this.config.botUserId, roomId); + //await this.mxClient.inviteUser(this.config.botUserId, roomId); + LogService.info("IRCBridge", `Inviting ${this.config.botUserId}`) } await this.ircClient.join(channel); const result = await this.executeCommand(`plumb ${roomId} ${this.config.serverName} ${channel}`); diff --git a/src/commands/FDMCommand.ts b/src/commands/FDMCommand.ts index dc79ff0..a41e36b 100644 --- a/src/commands/FDMCommand.ts +++ b/src/commands/FDMCommand.ts @@ -21,11 +21,12 @@ import { invitePersonToRoom, resolveIdentifiers } from "../invites"; import { logMessage } from "../LogProxy"; import { IPerson } from "../models/schedule"; import { ConferenceMatrixClient } from "../ConferenceMatrixClient"; +import {IConfig} from "../config"; export class FDMCommand implements ICommand { public readonly prefixes = ["fdm"]; - constructor(private readonly client: ConferenceMatrixClient, private readonly conference: Conference) {} + constructor(private readonly client: ConferenceMatrixClient, private readonly conference: Conference, private readonly config: IConfig) {} public async run(roomId: string, event: any, args: string[]) { const spi = this.conference.getInterestRoom("I.infodesk"); @@ -115,7 +116,7 @@ export class FDMCommand implements ICommand { for (const person of infodeskResolved) { try { if (person.mxid && inBsJoined.includes(person.mxid)) continue; - await invitePersonToRoom(this.client, person, infBackstage); + await invitePersonToRoom(this.client, person, infBackstage, this.config); } catch (e) { await logMessage(LogLevel.ERROR, "InviteCommand", `Error inviting ${person.mxid} / ${person.person.id} to ${infBackstage} - ignoring`, this.client); } @@ -124,13 +125,13 @@ export class FDMCommand implements ICommand { for (const person of volResolved) { try { if (person.mxid && volJoined.includes(person.mxid)) continue; - await invitePersonToRoom(this.client, person, vol); + await invitePersonToRoom(this.client, person, vol, this.config); } catch (e) { await logMessage(LogLevel.ERROR, "InviteCommand", `Error inviting ${person.mxid} / ${person.person.id} to ${vol} - ignoring`, this.client); } try { if (person.mxid && volBsJoined.includes(person.mxid)) continue; - await invitePersonToRoom(this.client, person, volBackstage); + await invitePersonToRoom(this.client, person, volBackstage, this.config); } catch (e) { await logMessage(LogLevel.ERROR, "InviteCommand", `Error inviting ${person.mxid} / ${person.person.id} to ${volBackstage} - ignoring`, this.client); } diff --git a/src/commands/InviteCommand.ts b/src/commands/InviteCommand.ts index efaa840..3a297ed 100644 --- a/src/commands/InviteCommand.ts +++ b/src/commands/InviteCommand.ts @@ -114,7 +114,7 @@ export class InviteCommand implements ICommand { if (target.mxid && effectiveJoinedUserIds.includes(target.mxid)) continue; if (emailInvitePersonIds.includes(target.person.id)) continue; try { - await invitePersonToRoom(this.client, target, roomId); + await invitePersonToRoom(this.client, target, roomId, this.config); } catch (e) { LogService.error("InviteCommand", e); await logMessage(LogLevel.ERROR, "InviteCommand", `Error inviting ${target.mxid}/${target.emails} / ${target.person.id} to ${roomId} - ignoring: ${e.message ?? e.statusMessage ?? '(see logs)'}`, this.client); diff --git a/src/config.ts b/src/config.ts index aa10844..f98e017 100644 --- a/src/config.ts +++ b/src/config.ts @@ -55,6 +55,7 @@ export interface IConfig { address: string; port: number; }; + dry_run_enabled: boolean; conference: { id: string; name: string; diff --git a/src/index.ts b/src/index.ts index e72f089..1e68e60 100644 --- a/src/index.ts +++ b/src/index.ts @@ -238,7 +238,7 @@ export class ConferenceBot { new BuildCommand(this.client, this.conference, this.config), new CopyModeratorsCommand(this.client), new DevCommand(this.client, this.conference), - new FDMCommand(this.client, this.conference), + new FDMCommand(this.client, this.conference, this.config), new HelpCommand(this.client), new InviteCommand(this.client, this.conference, this.config), new InviteMeCommand(this.client, this.conference), diff --git a/src/invites.ts b/src/invites.ts index 8035867..24c691e 100644 --- a/src/invites.ts +++ b/src/invites.ts @@ -19,6 +19,7 @@ import { RS_3PID_PERSON_ID } from "./models/room_state"; import { logMessage } from "./LogProxy"; import { IPerson } from "./models/schedule"; import { ConferenceMatrixClient } from "./ConferenceMatrixClient"; +import {IConfig} from "./config"; const MAX_EMAILS_PER_BATCH = 1000; @@ -78,9 +79,14 @@ export async function resolveIdentifiers(client: ConferenceMatrixClient, people: return resolved; } -export async function invitePersonToRoom(client: ConferenceMatrixClient, resolvedPerson: ResolvedPersonIdentifier, roomId: string): Promise { +export async function invitePersonToRoom(client: ConferenceMatrixClient, resolvedPerson: ResolvedPersonIdentifier, roomId: string, config: IConfig): Promise { if (resolvedPerson.mxid) { - return await client.inviteUser(resolvedPerson.mxid.trim(), roomId); + if (config.dry_run_enabled) { + LogService.info("invites", `Inviting ${resolvedPerson.mxid} (dry-run)`) + } + else { + return await client.inviteUser(resolvedPerson.mxid.trim(), roomId); + } } if (!resolvedPerson.emails) { @@ -93,16 +99,21 @@ export async function invitePersonToRoom(client: ConferenceMatrixClient, resolve } for (const email of resolvedPerson.emails) { - const idInvite = await client.identityClient.makeEmailInvite(email, roomId); - const content = { - display_name: idInvite.display_name, - // XXX: https://github.com/matrix-org/matrix-doc/issues/2948 - key_validity_url: `${client.identityClient.serverUrl}/_matrix/identity/v2/pubkey/ephemeral/isvalid`, - public_key: idInvite.public_key, - public_keys: idInvite.public_keys, - [RS_3PID_PERSON_ID]: resolvedPerson.person.id, - }; - const stateKey = idInvite.token; // not included in the content - await client.sendStateEvent(roomId, "m.room.third_party_invite", stateKey, content); + if (config.dry_run_enabled) { + LogService.info("invites", `Third-party inviting ${email} (dry-run)`) + } + else { + const idInvite = await client.identityClient.makeEmailInvite(email, roomId); + const content = { + display_name: idInvite.display_name, + // XXX: https://github.com/matrix-org/matrix-doc/issues/2948 + key_validity_url: `${client.identityClient.serverUrl}/_matrix/identity/v2/pubkey/ephemeral/isvalid`, + public_key: idInvite.public_key, + public_keys: idInvite.public_keys, + [RS_3PID_PERSON_ID]: resolvedPerson.person.id, + }; + const stateKey = idInvite.token; // not included in the content + await client.sendStateEvent(roomId, "m.room.third_party_invite", stateKey, content); + } } }