import { DiscordBot } from "./discordbot"; import { Bridge, RemoteRoom } from "matrix-appservice-bridge"; import { DiscordBridgeConfig } from "./config"; import * as Discord from "discord.js"; import * as log from "npmlog"; export class MatrixRoomHandler { private config: DiscordBridgeConfig; private bridge: Bridge; private discord: DiscordBot; private aliasList: any; constructor (bridge: Bridge, discord: DiscordBot, config: DiscordBridgeConfig) { this.bridge = bridge; this.discord = discord; this.config = config; this.aliasList = {}; } public OnAliasQueried (alias: string, roomId: string) { const aliasLocalpart = alias.substr(1, alias.length - `:${this.config.bridge.domain}`.length - 1); log.info("MatrixRoomHandler", `Room created ${aliasLocalpart} => ${roomId}`); if (this.aliasList[aliasLocalpart] == null) { log.warn("MatrixRoomHandler", "Room was created but we couldn't assign additonal aliases"); return; } const mxClient = this.bridge.getClientFactory().getClientAs(); this.aliasList[aliasLocalpart].forEach((item) => { if (item === "#" + aliasLocalpart) { return; } mxClient.createAlias(item, roomId).catch( (err) => { log.warn("MatrixRoomHandler", `Failed to create alias '${aliasLocalpart} for ${roomId}'`, err); }); }); delete this.aliasList[aliasLocalpart]; } public OnEvent (request, context) { const event = request.getData(); if (event.type === "m.room.message" && context.rooms.remote) { let srvChanPair = context.rooms.remote.roomId.substr("_discord".length).split("_", 2); this.discord.ProcessMatrixMsgEvent(event, srvChanPair[0], srvChanPair[1]); } } public OnAliasQuery (alias: string, aliasLocalpart: string): Promise<any> { let srvChanPair = aliasLocalpart.substr("_discord_".length).split("#", 2); if (srvChanPair.length < 2 || srvChanPair[0] === "" || srvChanPair[1] === "") { log.warn("MatrixRoomHandler", `Alias '${aliasLocalpart}' was missing a server and/or a channel`); return; } return this.discord.LookupRoom(srvChanPair[0], srvChanPair[1]).then((channel) => { return this.createMatrixRoom(channel, aliasLocalpart); }).catch((err) => { log.error("MatrixRoomHandler", `Couldn't find discord room '${aliasLocalpart}'.`, err); }); } private createMatrixRoom (channel: Discord.TextChannel, alias: string) { const botID = this.bridge.getBot().getUserId(); // const roomOwner = "@_discord_" + user.id_str + ":" + this._bridge.opts.domain; const users = {}; users[botID] = 100; // users[roomOwner] = 75; // var powers = util.roomPowers(users); const remote = new RemoteRoom(`discord_${channel.guild.id}_${channel.id}`); remote.set("discord_type", "text"); remote.set("discord_guild", channel.guild.id); remote.set("discord_channel", channel.id); const gname = channel.guild.name.replace(" ", "-"); const cname = channel.name.replace(" ", "-"); this.aliasList[alias] = [ `#_discord_${channel.guild.id}#${channel.id}:${this.config.bridge.domain}`, `#_discord_${channel.guild.id}#${cname}:${this.config.bridge.domain}`, `#_discord_${gname}#${channel.id}:${this.config.bridge.domain}`, `#_discord_${gname}#${cname}:${this.config.bridge.domain}`, ]; const creationOpts = { visibility: "public", room_alias_name: alias, name: `[Discord] ${channel.guild.name}#${channel.name}`, topic: channel.topic ? channel.topic : "", // invite: [roomOwner], initial_state: [ // powers, { type: "m.room.join_rules", content: { join_rule: "public", }, state_key: "", }, // }, { // type: "org.matrix.twitter.data", // content: user, // state_key: "" // }, { // type: "m.room.avatar", // state_key: "", // content: { // url: avatar // } ], }; return { creationOpts, remote, }; } }