diff --git a/changelog.d/736.feature b/changelog.d/736.feature new file mode 100644 index 00000000..f55c5ff9 --- /dev/null +++ b/changelog.d/736.feature @@ -0,0 +1 @@ +Add configuration setting (`bridge.userPowerLevels`) to auto-apply power levels to designated users on bridge startup. diff --git a/config/config.sample.yaml b/config/config.sample.yaml index 3443e4af..5ba904f8 100644 --- a/config/config.sample.yaml +++ b/config/config.sample.yaml @@ -44,6 +44,13 @@ bridge: adminMxid: '@admin:localhost' # The message to send to the bridge admin if the Discord token is not valid invalidTokenMessage: 'Your Discord bot token seems to be invalid, and the bridge cannot function. Please update it in your bridge settings and restart the bridge' + # Custom power levels to assign to Matrix users in bridged rooms (supports regexes). + # Patterns are tested in order; first match is used. + #userPowerLevels: + # - userPattern: "@admin:example.com" + # pl: 100 + # - userPattern: "@.*:example.com" + # pl: 50 # Authentication configuration for the discord bot. auth: # This MUST be a string (wrapped in quotes) diff --git a/config/config.schema.yaml b/config/config.schema.yaml index eb320ac0..e31bce5b 100644 --- a/config/config.schema.yaml +++ b/config/config.schema.yaml @@ -42,6 +42,14 @@ properties: type: "number" userLimit: type: "number" + userPowerLevels: + type: "array" + items: + type: "object" + required: ["userPattern", "pl"] + properties: + userPattern: "string" + pl: "number" auth: type: "object" required: ["botToken", "clientID"] diff --git a/src/config.ts b/src/config.ts index b9362fa9..ea240de8 100644 --- a/src/config.ts +++ b/src/config.ts @@ -80,6 +80,11 @@ export class DiscordBridgeConfig { } } +interface UserPowerLevel { + userPattern: string; + pl: number; +} + export class DiscordBridgeConfigBridge { public domain: string; public homeserverUrl: string; @@ -103,6 +108,11 @@ export class DiscordBridgeConfigBridge { public userLimit: number|null = null; public adminMxid: string|null = null; public invalidTokenMessage: string = 'Your Discord token is invalid'; + public userPowerLevels: UserPowerLevel[] = []; + + public GetCustomPowerLevelForUser(userId: string): number|undefined { + return this.userPowerLevels.find(obj => RegExp(obj.userPattern).test(userId))?.pl; + } } export class DiscordBridgeConfigDatabase { diff --git a/src/discordas.ts b/src/discordas.ts index baebd985..56daa0f7 100644 --- a/src/discordas.ts +++ b/src/discordas.ts @@ -228,6 +228,22 @@ async function run(): Promise { await appservice.begin(); log.info(`Started listening on port ${port}`); + const client = appservice.botIntent.underlyingClient; + for (const roomId of await client.getJoinedRooms()) { + for (const userId of await client.getJoinedRoomMembers(roomId)) { + let customPL; + if (!appservice.isNamespacedUser(userId) && + (customPL = config.bridge.GetCustomPowerLevelForUser(userId)) !== undefined) { + // TODO allSettled + try { + await client.setUserPowerLevel(userId, roomId, customPL); + log.verbose(`Set power level of ${customPL} for user ${userId} in room ${roomId}`); + } catch (err) { + log.warn(`Cannot set custom power level of ${customPL} for user ${userId} in room ${roomId}: ${err}`); + } + } + } + } } run().catch((err) => { diff --git a/src/matrixeventprocessor.ts b/src/matrixeventprocessor.ts index f1f46115..b9fd1f37 100644 --- a/src/matrixeventprocessor.ts +++ b/src/matrixeventprocessor.ts @@ -258,6 +258,12 @@ export class MatrixEventProcessor { } // We don't know if the user also updated their profile, but to be safe.. this.mxUserProfileCache.delete(event.sender); + + const customPL = this.config.bridge.GetCustomPowerLevelForUser(event.sender); + if (customPL !== undefined) { + client.setUserPowerLevel(event.sender, event.room_id, customPL) + .catch((err) => log.warn(`Cannot set custom power level of ${customPL} for user ${event.sender} in room ${event.room_id}: ${err}`)); + } } if (membership === "join" && isNewJoin && allowJoinLeave) { msg += "joined the room";