diff --git a/src/bot.ts b/src/bot.ts index e482314ed6dfe148da99ccfc845ea6cc0f4c034b..09d87e118cb9df5a8d000aaeab6b26cbef326e9e 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -26,7 +26,7 @@ import { DiscordMessageProcessorOpts, DiscordMessageProcessorResult, } from "./discordmessageprocessor"; -import { MatrixEventProcessor, MatrixEventProcessorOpts } from "./matrixeventprocessor"; +import { MatrixEventProcessor, MatrixEventProcessorOpts, IMatrixEventProcessorResult } from "./matrixeventprocessor"; import { PresenceHandler } from "./presencehandler"; import { Provisioner } from "./provisioner"; import { UserSyncroniser } from "./usersyncroniser"; @@ -345,53 +345,23 @@ export class DiscordBot { } } - public async ProcessMatrixStateEvent(event: IMatrixEvent): Promise<void> { - log.verbose(`Got state event from ${event.room_id} ${event.type}`); - const channel = await this.GetChannelFromRoomId(event.room_id) as Discord.TextChannel; - const msg = this.mxEventProcessor.StateEventToMessage(event, channel); + public async sendAsBot(msg: string, channel: Discord.TextChannel, event: IMatrixEvent): Promise<void> { if (!msg) { return; } - let res = await channel.send(msg); - if (!Array.isArray(res)) { - res = [res]; - } - await Util.AsyncForEach(res, async (m: Discord.Message) => { - log.verbose("Sent (state msg) ", m.id); - this.sentMessages.push(m.id); - this.lastEventIds[event.room_id] = event.event_id; - const evt = new DbEvent(); - evt.MatrixId = `${event.event_id};${event.room_id}`; - evt.DiscordId = m.id; - evt.GuildId = channel.guild.id; - evt.ChannelId = channel.id; - await this.store.Insert(evt); - }); - if (!this.config.bridge.disableReadReceipts) { - try { - await this.bridge.getIntent().sendReadReceipt(event.room_id, event.event_id); - } catch (err) { - log.error(`Failed to send read receipt for ${event}. `, err); - } - } + const res = await channel.send(msg); + await this.StoreMessagesSent(res, channel, event); } - public async ProcessMatrixMsgEvent(event: IMatrixEvent, guildId: string, channelId: string): Promise<void> { - const mxClient = this.bridge.getClientFactory().getClientAs(); - log.verbose(`Looking up ${guildId}_${channelId}`); - const result = await this.LookupRoom(guildId, channelId, event.sender); - const chan = result.channel; - const botUser = result.botUser; - - const embedSet = await this.mxEventProcessor.EventToEmbed(event, chan); + public async send( + embedSet: IMatrixEventProcessorResult, + opts: Discord.MessageOptions, + roomLookup: ChannelLookupResult, + event: IMatrixEvent, + ): Promise<void> { + const chan = roomLookup.channel; + const botUser = roomLookup.botUser; const embed = embedSet.messageEmbed; - const opts: Discord.MessageOptions = {}; - const file = await this.mxEventProcessor.HandleAttachment(event, mxClient); - if (typeof(file) === "string") { - embed.description += " " + file; - } else { - opts.file = file; - } let msg: Discord.Message | null | (Discord.Message | null)[] = null; let hook: Discord.Webhook | undefined; @@ -429,32 +399,10 @@ export class DiscordBot { opts.embed = embed; msg = await chan.send("", opts); } + await this.StoreMessagesSent(msg, chan, event); } catch (err) { log.error("Couldn't send message. ", err); } - if (!Array.isArray(msg)) { - msg = [msg]; - } - await Util.AsyncForEach(msg, async (m: Discord.Message) => { - log.verbose("Sent ", m.id); - this.sentMessages.push(m.id); - this.lastEventIds[event.room_id] = event.event_id; - const evt = new DbEvent(); - evt.MatrixId = `${event.event_id};${event.room_id}`; - evt.DiscordId = m.id; - // Webhooks don't send guild info. - evt.GuildId = guildId; - evt.ChannelId = channelId; - await this.store.Insert(evt); - }); - if (!this.config.bridge.disableReadReceipts) { - try { - await this.bridge.getIntent().sendReadReceipt(event.room_id, event.event_id); - } catch (err) { - log.error(`Failed to send read receipt for ${event}. `, err); - } - } - return; } public async ProcessMatrixRedact(event: IMatrixEvent) { @@ -919,4 +867,32 @@ export class DiscordBot { } } } + + private async StoreMessagesSent( + msg: Discord.Message | null | (Discord.Message | null)[], + chan: Discord.TextChannel, + event: IMatrixEvent, + ) { + if (!Array.isArray(msg)) { + msg = [msg]; + } + await Util.AsyncForEach(msg, async (m: Discord.Message) => { + if (!m) { + return; + } + log.verbose("Sent ", m.id); + this.sentMessages.push(m.id); + this.lastEventIds[event.room_id] = event.event_id; + try { + const evt = new DbEvent(); + evt.MatrixId = `${event.event_id};${event.room_id}`; + evt.DiscordId = m.id; + evt.GuildId = chan.guild.id; + evt.ChannelId = chan.id; + await this.store.Insert(evt); + } catch (err) { + log.error(`Failed to insert sent event (${event.event_id};${event.room_id}) into store`, err); + } + }); + } } diff --git a/src/matrixeventprocessor.ts b/src/matrixeventprocessor.ts index dfab2e6488d995112de5a8008111d42eea42f609..b0489e02a16bacae2e4eaa6c598ebd389c3ae0d4 100644 --- a/src/matrixeventprocessor.ts +++ b/src/matrixeventprocessor.ts @@ -100,7 +100,7 @@ export class MatrixEventProcessor { } return; } else if (["m.room.member", "m.room.name", "m.room.topic"].includes(event.type)) { - await this.discord.ProcessMatrixStateEvent(event); + await this.ProcessStateEvent(event); return; } else if (event.type === "m.room.redaction" && context.rooms.remote) { await this.discord.ProcessMatrixRedact(event); @@ -116,7 +116,7 @@ export class MatrixEventProcessor { } else if (context.rooms.remote) { const srvChanPair = context.rooms.remote.roomId.substr("_discord".length).split("_", ROOM_NAME_PARTS); try { - await this.discord.ProcessMatrixMsgEvent(event, srvChanPair[0], srvChanPair[1]); + await this.ProcessMsgEvent(event, srvChanPair[0], srvChanPair[1]); return; } catch (err) { log.warn("There was an error sending a matrix event", err); @@ -155,7 +155,30 @@ export class MatrixEventProcessor { await this.bridge.getRoomStore().removeEntriesByMatrixRoomId(roomId); } - public StateEventToMessage(event: IMatrixEvent, channel: Discord.TextChannel): string | undefined { + public async ProcessMsgEvent(event: IMatrixEvent, guildId: string, channelId: string) { + const mxClient = this.bridge.getClientFactory().getClientAs(); + log.verbose(`Looking up ${guildId}_${channelId}`); + const roomLookup = await this.discord.LookupRoom(guildId, channelId, event.sender); + const chan = roomLookup.channel; + const botUser = roomLookup.botUser; + + const embedSet = await this.EventToEmbed(event, chan); + const opts: Discord.MessageOptions = {}; + const file = await this.HandleAttachment(event, mxClient); + if (typeof(file) === "string") { + embedSet.messageEmbed.description += " " + file; + } else { + opts.file = file; + } + + await this.discord.send(embedSet, opts, roomLookup, event); + await this.sendReadReceipt(event); + } + + public async ProcessStateEvent(event: IMatrixEvent) { + log.verbose(`Got state event from ${event.room_id} ${event.type}`); + const channel = await this.discord.GetChannelFromRoomId(event.room_id) as Discord.TextChannel; + const SUPPORTED_EVENTS = ["m.room.member", "m.room.name", "m.room.topic"]; if (!SUPPORTED_EVENTS.includes(event.type)) { log.verbose(`${event.event_id} ${event.type} is not displayable.`); @@ -198,7 +221,8 @@ export class MatrixEventProcessor { } msg += " on Matrix."; - return msg; + await this.discord.sendAsBot(msg, channel, event); + await this.sendReadReceipt(event); } public async EventToEmbed( @@ -342,6 +366,16 @@ export class MatrixEventProcessor { return embed; } + private async sendReadReceipt(event: IMatrixEvent) { + if (!this.config.bridge.disableReadReceipts) { + try { + await this.bridge.getIntent().sendReadReceipt(event.room_id, event.event_id); + } catch (err) { + log.error(`Failed to send read receipt for ${event}. `, err); + } + } + } + private HasAttachment(event: IMatrixEvent): boolean { if (!event.content) { event.content = {};