From 473f364998aaf288d4c6867ec4110abc7ac3b349 Mon Sep 17 00:00:00 2001 From: Will Hunt <will@half-shot.uk> Date: Thu, 25 Oct 2018 20:35:47 +0100 Subject: [PATCH] If reply source author is a discord user, show their profile --- src/bot.ts | 16 ++++++++++++- src/matrixeventprocessor.ts | 38 +++++++++++++++++++++++++++---- src/matrixroomhandler.ts | 2 +- test/test_matrixeventprocessor.ts | 6 +++++ test/test_matrixroomhandler.ts | 2 +- 5 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/bot.ts b/src/bot.ts index cfbd700..240ab20 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -60,7 +60,7 @@ export class DiscordBot { public setBridge(bridge: Bridge) { this.bridge = bridge; this.mxEventProcessor = new MatrixEventProcessor( - new MatrixEventProcessorOpts(this.config, bridge), + new MatrixEventProcessorOpts(this.config, bridge, this), ); } @@ -331,6 +331,20 @@ export class DiscordBot { return false; } + public GetDiscordUserOrMember(userId: Discord.Snowflake, guildId?: Discord.Snowflake) + : Promise<Discord.User|Discord.GuildMember> { + try { + if (guildId && this.bot.guilds.has(guildId)) { + return this.bot.guilds.get(guildId).fetchMember(userId); + } + return this.bot.fetchUser(userId); + } + catch (ex) { + log.warn(`Could not fetch user data for ${userId} (guild: ${guildId})`); + return undefined; + } + } + public GetChannelFromRoomId(roomId: string): Promise<Discord.Channel> { return this.bridge.getRoomStore().getEntriesByMatrixId( roomId, diff --git a/src/matrixeventprocessor.ts b/src/matrixeventprocessor.ts index ea734ee..90765e7 100644 --- a/src/matrixeventprocessor.ts +++ b/src/matrixeventprocessor.ts @@ -6,6 +6,7 @@ import * as escapeStringRegexp from "escape-string-regexp"; import {Util} from "./util"; import * as path from "path"; import * as mime from "mime"; +import {MatrixUser} from "matrix-appservice-bridge"; import { Log } from "./log"; const log = new Log("MatrixEventProcessor"); @@ -19,6 +20,7 @@ export class MatrixEventProcessorOpts { constructor( readonly config: DiscordBridgeConfig, readonly bridge: any, + readonly discord: DiscordBot, ) { } @@ -32,10 +34,12 @@ export interface IMatrixEventProcessorResult { export class MatrixEventProcessor { private config: DiscordBridgeConfig; private bridge: any; + private discord: DiscordBot; constructor (opts: MatrixEventProcessorOpts) { this.config = opts.config; this.bridge = opts.bridge; + this.discord = opts.discord; } public StateEventToMessage(event: any, channel: Discord.TextChannel): string { @@ -126,7 +130,7 @@ export class MatrixEventProcessor { const messageEmbed = new Discord.RichEmbed(); const replyEmbedAndBody = await this.GetEmbedForReply(event); messageEmbed.setDescription(replyEmbedAndBody ? replyEmbedAndBody[1] : body); - this.SetEmbedAuthor(messageEmbed, event.sender, profile); + await this.SetEmbedAuthor(messageEmbed, event.sender, profile); return { messageEmbed, replyEmbed: replyEmbedAndBody ? replyEmbedAndBody[0] : undefined, @@ -230,10 +234,9 @@ export class MatrixEventProcessor { replyText = Util.GetReplyFromReplyBody(sourceEvent.content.body); } embed.setDescription(replyText); - this.SetEmbedAuthor( + await this.SetEmbedAuthor( embed, sourceEvent.sender, - await intent.getProfileInfo(sourceEvent.sender), ); } catch (ex) { // For some reason we failed to get the event, so using fallback. @@ -243,11 +246,38 @@ export class MatrixEventProcessor { return [embed, reponseText]; } - private SetEmbedAuthor(embed: Discord.RichEmbed, sender: string, profile: any) { + private async SetEmbedAuthor(embed: Discord.RichEmbed, sender: string, profile?: any) { const intent = this.bridge.getIntent(); let displayName = sender; let avatarUrl = undefined; + // Are they a discord user. + if (this.bridge.getBot().isRemoteUser(sender)) { + const localpart = new MatrixUser(sender.replace("@", "")).localpart; + const userOrMember = await this.discord.GetDiscordUserOrMember(localpart.substring("_discord_".length)); + if (userOrMember instanceof Discord.User) { + embed.setAuthor( + userOrMember.username, + userOrMember.avatarURL + ); + return; + } else if (userOrMember instanceof Discord.GuildMember) { + embed.setAuthor( + userOrMember.displayName, + userOrMember.user.avatarURL + ); + return; + } + // Let it fall through. + } + if (profile === undefined) { + try { + profile = await intent.getProfileInfo(sender); + } catch (ex) { + log.warn(`Failed to fetch profile for ${sender}`, ex); + } + } + if (profile) { if (profile.displayname && profile.displayname.length >= MIN_NAME_LENGTH && diff --git a/src/matrixroomhandler.ts b/src/matrixroomhandler.ts index e627fc9..4fc96a4 100644 --- a/src/matrixroomhandler.ts +++ b/src/matrixroomhandler.ts @@ -109,7 +109,7 @@ export class MatrixRoomHandler { if (event.type === "m.room.member" && event.content.membership === "invite") { return this.HandleInvite(event); } else if (event.type === "m.room.member" && event.content.membership === "join") { - if (this.bridge.getBot()._isRemoteUser(event.state_key)) { + if (this.bridge.getBot().isRemoteUser(event.state_key)) { return this.discord.UserSyncroniser.OnMemberState(event, USERSYNC_STATE_DELAY_MS); } else { return this.discord.ProcessMatrixStateEvent(event); diff --git a/test/test_matrixeventprocessor.ts b/test/test_matrixeventprocessor.ts index e54d2ac..f08e8c9 100644 --- a/test/test_matrixeventprocessor.ts +++ b/test/test_matrixeventprocessor.ts @@ -45,6 +45,11 @@ function createMatrixEventProcessor }, }; }, + getBot: () => { + return { + isRemoteUser: () => false, + } + }, getIntent: () => { return { getClient: () => { @@ -118,6 +123,7 @@ This is the first reply`, new MatrixEventProcessorOpts( config, bridge, + null )); } const mockChannel = new MockChannel(); diff --git a/test/test_matrixroomhandler.ts b/test/test_matrixroomhandler.ts index 0bfefe5..aa2b5f6 100644 --- a/test/test_matrixroomhandler.ts +++ b/test/test_matrixroomhandler.ts @@ -66,7 +66,7 @@ function createRH(opts: any = {}) { }, getBot: () => { return { - _isRemoteUser: (id) => { + isRemoteUser: (id) => { return id !== undefined && id.startsWith("@_discord_"); }, }; -- GitLab