Skip to content

Commit

Permalink
Allow configuration of multiple moderator users to be invited to all …
Browse files Browse the repository at this point in the history
…rooms
  • Loading branch information
reivilibre committed Nov 28, 2024
1 parent 20626b2 commit 113b526
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 28 deletions.
8 changes: 4 additions & 4 deletions config/default.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@ idServerDomain: "vector.im"
# result in emails or other communications to the user.
idServerBrand: "vector-im"

# This is the user ID of the moderator for all public-facing rooms the bot creates.
# Note that this user will be granted power level 100 (the highest) in every room
# These are the user IDs of the moderators for all public-facing rooms the bot creates.
# Note that these users will be granted power level 100 (the highest) in every room
# and be invited.
moderatorUserId: "@moderator:example.org"
moderatorUserIds: ["@moderator:example.org"]

# Settings for how the bot should represent livestreams.
livestream:
Expand Down Expand Up @@ -337,4 +337,4 @@ metrics:
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
dry_run_enabled: false
2 changes: 1 addition & 1 deletion spec/util/e2e-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ export class E2ETestEnv {
}
},
},
moderatorUserId: `@modbot:${homeserver.domain}`,
moderatorUserId: [`@modbot:${homeserver.domain}`],
webserver: {
address: '0.0.0.0',
port: 0,
Expand Down
24 changes: 15 additions & 9 deletions src/Conference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ export class Conference {
this.client,
mergeWithCreationTemplate(AUDITORIUM_BACKSTAGE_CREATION_TEMPLATE, {
room_alias_name: (new RoomAlias(alias)).localpart,
invite: [this.config.moderatorUserId],
invite: this.config.moderatorUserIds,
}),
);
await rootSpace.addChildRoom(roomId);
Expand Down Expand Up @@ -433,7 +433,7 @@ export class Conference {
subspace = await this.client.createSpace({
isPublic: true,
name: name,
invites: [this.config.moderatorUserId],
invites: this.config.moderatorUserIds,
});
this.subspaces[subspaceId] = subspace;

Expand All @@ -448,9 +448,11 @@ export class Conference {
roomId: subspace.roomId,
} as IStoredSubspace);

// Grants PL100 to the moderator in the subspace.
// Grants PL100 to the moderators in the subspace.
// We can't do this directly with `createSpace` unfortunately, as we could for plain rooms.
await this.client.setUserPowerLevel(this.config.moderatorUserId, subspace.roomId, 100);
for (let moderator of this.config.moderatorUserIds) {
await this.client.setUserPowerLevel(moderator, subspace.roomId, 100);
}
} else {
subspace = this.subspaces[subspaceId];
}
Expand Down Expand Up @@ -481,7 +483,7 @@ export class Conference {
);
} else {
// Create a new interest room.
roomId = await safeCreateRoom(this.client, mergeWithCreationTemplate(SPECIAL_INTEREST_CREATION_TEMPLATE(this.config.moderatorUserId), {
roomId = await safeCreateRoom(this.client, mergeWithCreationTemplate(SPECIAL_INTEREST_CREATION_TEMPLATE(this.config.moderatorUserIds), {
creation_content: {
[RSC_CONFERENCE_ID]: this.id,
[RSC_SPECIAL_INTEREST_ID]: interestRoom.id,
Expand Down Expand Up @@ -571,7 +573,7 @@ export class Conference {

await parentSpace.addChildSpace(audSpace, { order: `auditorium-${auditorium.id}` });

const roomId = await safeCreateRoom(this.client, mergeWithCreationTemplate(AUDITORIUM_CREATION_TEMPLATE(this.config.moderatorUserId), {
const roomId = await safeCreateRoom(this.client, mergeWithCreationTemplate(AUDITORIUM_CREATION_TEMPLATE(this.config.moderatorUserIds), {
creation_content: {
[RSC_CONFERENCE_ID]: this.id,
[RSC_AUDITORIUM_ID]: auditorium.id,
Expand Down Expand Up @@ -629,7 +631,7 @@ export class Conference {
}

if (!this.talks[talk.id]) {
roomId = await safeCreateRoom(this.client, mergeWithCreationTemplate(TALK_CREATION_TEMPLATE(this.config.moderatorUserId), {
roomId = await safeCreateRoom(this.client, mergeWithCreationTemplate(TALK_CREATION_TEMPLATE(this.config.moderatorUserIds), {
name: talk.title,
creation_content: {
[RSC_CONFERENCE_ID]: this.id,
Expand Down Expand Up @@ -848,7 +850,9 @@ export class Conference {
// we'll be unable to do promotions/demotions in the future.
const pls = await this.client.getRoomStateEvent(roomId, "m.room.power_levels", "");
pls['users'][await this.client.getUserId()] = 100;
pls['users'][this.config.moderatorUserId] = 100;
for (let moderator of this.config.moderatorUserIds) {
pls['users'][moderator] = 100;
}
for (const userId of mxids) {
if (pls['users'][userId]) continue;
pls['users'][userId] = 50;
Expand Down Expand Up @@ -916,7 +920,9 @@ export class Conference {
this.membersInRooms[roomId] = joinedOrLeftMembers;
const total = new Set(Object.values(this.membersInRooms).flat());
total.delete(myUserId);
total.delete(this.config.moderatorUserId);
for (let moderator of this.config.moderatorUserIds) {
total.delete(moderator);
}
attendeeTotalGauge.set(total.size);
} catch (ex) {
LogService.warn("Conference", `Failed to recalculate room membership for ${roomId}`, ex);
Expand Down
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export interface IConfig {
managementRoom: string;
idServerDomain?: string;
idServerBrand?: string;
moderatorUserId: string;
moderatorUserIds: string[];
livestream: {
auditoriumUrl: string;
talkUrl: string;
Expand Down
23 changes: 10 additions & 13 deletions src/models/room_kinds.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { RoomCreateOptions } from "matrix-bot-sdk";

export const KickPowerLevel = 50;

export const PUBLIC_ROOM_POWER_LEVELS_TEMPLATE = (moderatorUserId: string) => ({
export const PUBLIC_ROOM_POWER_LEVELS_TEMPLATE = (moderatorUserIds: string[]) => ({
ban: 50,
events_default: 0,
invite: 50,
Expand All @@ -40,10 +40,7 @@ export const PUBLIC_ROOM_POWER_LEVELS_TEMPLATE = (moderatorUserId: string) => ({
"m.space.parent": 100,
"m.space.child": 100,
},
users: {
[moderatorUserId]: 100,
// should be populated with the creator
},
users: Object.fromEntries(moderatorUserIds.map(moderator => [moderator, 100])),
});

export const PRIVATE_ROOM_POWER_LEVELS_TEMPLATE = {
Expand Down Expand Up @@ -91,7 +88,7 @@ export const CONFERENCE_ROOM_CREATION_TEMPLATE: RoomCreateOptions = {
},
};

export const AUDITORIUM_CREATION_TEMPLATE = (moderatorUserId: string) => ({
export const AUDITORIUM_CREATION_TEMPLATE = (moderatorUserIds: string[]) => ({
preset: 'public_chat',
visibility: 'public',
initial_state: [
Expand All @@ -101,8 +98,8 @@ export const AUDITORIUM_CREATION_TEMPLATE = (moderatorUserId: string) => ({
creation_content: {
[RSC_ROOM_KIND_FLAG]: RoomKind.Auditorium,
},
power_level_content_override: PUBLIC_ROOM_POWER_LEVELS_TEMPLATE(moderatorUserId),
invite: [moderatorUserId],
power_level_content_override: PUBLIC_ROOM_POWER_LEVELS_TEMPLATE(moderatorUserIds),
invite: moderatorUserIds,
} satisfies RoomCreateOptions);

export const AUDITORIUM_BACKSTAGE_CREATION_TEMPLATE: RoomCreateOptions = {
Expand All @@ -118,7 +115,7 @@ export const AUDITORIUM_BACKSTAGE_CREATION_TEMPLATE: RoomCreateOptions = {
power_level_content_override: PRIVATE_ROOM_POWER_LEVELS_TEMPLATE,
};

export const TALK_CREATION_TEMPLATE = (moderatorUserId: string) => ({ // before being opened up to the public
export const TALK_CREATION_TEMPLATE = (moderatorUserIds: string[]) => ({ // before being opened up to the public
preset: 'private_chat',
visibility: 'private',
initial_state: [
Expand All @@ -128,11 +125,11 @@ export const TALK_CREATION_TEMPLATE = (moderatorUserId: string) => ({ // before
creation_content: {
[RSC_ROOM_KIND_FLAG]: RoomKind.Talk,
},
power_level_content_override: PUBLIC_ROOM_POWER_LEVELS_TEMPLATE(moderatorUserId),
invite: [moderatorUserId],
power_level_content_override: PUBLIC_ROOM_POWER_LEVELS_TEMPLATE(moderatorUserIds),
invite: moderatorUserIds,
} satisfies RoomCreateOptions);

export const SPECIAL_INTEREST_CREATION_TEMPLATE = (moderatorUserId: string) => ({
export const SPECIAL_INTEREST_CREATION_TEMPLATE = (moderatorUserIds: string[]) => ({
preset: 'public_chat',
visibility: 'public',
initial_state: [
Expand All @@ -149,7 +146,7 @@ export const SPECIAL_INTEREST_CREATION_TEMPLATE = (moderatorUserId: string) => (
"m.room.power_levels": 50,
},
},
invite: [moderatorUserId],
invite: moderatorUserIds,
} satisfies RoomCreateOptions);

export function mergeWithCreationTemplate(template: RoomCreateOptions, addlProps: any): any {
Expand Down

0 comments on commit 113b526

Please sign in to comment.