Skip to content
Extraits de code Groupes Projets
Valider e0f43adf rédigé par Will Hunt's avatar Will Hunt
Parcourir les fichiers

Leave users from rooms when unbridging

parent 094b2a8b
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
......@@ -17,7 +17,7 @@ limitations under the License.
import * as Discord from "discord.js";
import { DiscordBot } from "./bot";
import { Util } from "./util";
import { DiscordBridgeConfig } from "./config";
import { DiscordBridgeConfig, DiscordBridgeConfigChannelDeleteOptions } from "./config";
import { Bridge } from "matrix-appservice-bridge";
import { Log } from "./log";
import { DbRoomStore, IRoomStoreEntry } from "./db/roomstore";
......@@ -105,6 +105,20 @@ export class ChannelSyncroniser {
}
}
public async OnUnbridge(channel: Discord.Channel, roomId: string) {
try {
const entry = (await this.roomStore.getEntriesByMatrixId(roomId))[0];
const opts = new DiscordBridgeConfigChannelDeleteOptions();
opts.namePrefix = null;
opts.topicPrefix = null;
opts.ghostsLeave = true;
await this.handleChannelDeletionForRoom(channel as Discord.TextChannel, roomId, entry);
log.info(`Channel ${channel.id} has been unbridged.`);
} catch (e) {
log.error(`Failed to unbridge channel from room: ${e}`);
}
}
public async OnDelete(channel: Discord.Channel) {
if (channel.type !== "text") {
log.info(`Channel ${channel.id} was deleted but isn't a text channel, so ignoring.`);
......@@ -269,22 +283,24 @@ export class ChannelSyncroniser {
private async handleChannelDeletionForRoom(
channel: Discord.TextChannel,
roomId: string,
entry: IRoomStoreEntry): Promise<void> {
entry: IRoomStoreEntry,
overrideOptions?: DiscordBridgeConfigChannelDeleteOptions): Promise<void> {
log.info(`Deleting ${channel.id} from ${roomId}.`);
const intent = await this.bridge.getIntent();
const options = this.config.channel.deleteOptions;
const options = overrideOptions || this.config.channel.deleteOptions;
const plumbed = entry.remote!.get("plumbed");
// tslint:disable-next-line: no-any
await this.roomStore.upsertEntry(entry);
if (options.ghostsLeave) {
for (const member of channel.members.array()) {
try {
const mIntent = await this.bot.GetIntentFromDiscordMember(member);
mIntent.leave(roomId);
log.info(`${member.id} left ${roomId}.`);
} catch (e) {
log.warn(`Failed to make ${member.id} leave `);
}
// Not awaiting this because we want to do this in the background.
mIntent.leave(roomId).then(() => {
log.verbose(`${member.id} left ${roomId}.`);
}).catch(() => {
log.warn(`Failed to make ${member.id} leave.`);
});
}
}
if (options.namePrefix) {
......@@ -347,7 +363,6 @@ export class ChannelSyncroniser {
}
}
}
// Unlist
// Remove entry
await this.roomStore.removeEntriesByMatrixRoomId(roomId);
......
......@@ -86,7 +86,7 @@ class DiscordBridgeConfigChannel {
public deleteOptions = new DiscordBridgeConfigChannelDeleteOptions();
}
class DiscordBridgeConfigChannelDeleteOptions {
export class DiscordBridgeConfigChannelDeleteOptions {
public namePrefix: string | null = null;
public topicPrefix: string | null = null;
public disableMessaging: boolean = false;
......
......@@ -20,7 +20,7 @@ import { Util, ICommandActions, ICommandParameters, CommandPermissonCheck } from
import { Bridge } from "matrix-appservice-bridge";
import { Log } from "./log";
const log = new Log("MatrixCommandHandler");
const log = new Log("DiscordCommandHandler");
export class DiscordCommandHandler {
constructor(
......
......@@ -134,7 +134,7 @@ export class MatrixCommandHandler {
remoteRoom.data.discord_channel,
);
try {
await this.provisioner.UnbridgeChannel(res.channel);
await this.provisioner.UnbridgeChannel(res.channel, event.room_id);
return "This room has been unbridged";
} catch (err) {
log.error("Error while unbridging room " + event.room_id);
......
......@@ -17,9 +17,12 @@ limitations under the License.
import * as Discord from "discord.js";
import { DbRoomStore, RemoteStoreRoom, MatrixStoreRoom } from "./db/roomstore";
import { ChannelSyncroniser } from "./channelsyncroniser";
import { Log } from "./log";
const PERMISSION_REQUEST_TIMEOUT = 300000; // 5 minutes
const log = new Log("Provisioner");
export class Provisioner {
private pendingRequests: Map<string, (approved: boolean) => void> = new Map(); // [channelId]: resolver fn
......@@ -38,7 +41,7 @@ export class Provisioner {
return this.roomStore.linkRooms(local, remote);
}
public async UnbridgeChannel(channel: Discord.TextChannel) {
public async UnbridgeChannel(channel: Discord.TextChannel, rId?: string) {
const roomsRes = await this.roomStore.getEntriesByRemoteRoomData({
discord_channel: channel.id,
discord_guild: channel.guild.id,
......@@ -48,6 +51,18 @@ export class Provisioner {
throw Error("Channel is not bridged");
}
const remoteRoom = roomsRes[0].remote as RemoteStoreRoom;
let roomsToUnbridge: string[] = [];
if (rId) {
roomsToUnbridge = [rId];
} else {
// Kill em all.
roomsToUnbridge = roomsRes.map((entry) => entry.matrix!.roomId);
}
await Promise.all(roomsToUnbridge.map( async (roomId) => {
return this.channelSync.OnUnbridge(channel, roomId).catch((err) => {
log.error(`Failed to cleanly unbridge ${channel.id} ${channel.guild} from ${roomId}`);
});
}));
await this.roomStore.removeEntriesByRemoteRoomId(remoteRoom.getId());
}
......
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter