diff --git a/src/matrixeventprocessor.ts b/src/matrixeventprocessor.ts index f4a0ed490245ec08a66f93a67b7dae324a99dc14..285fbd2c5dff458429e25f6bbe3137fe31b8afe9 100644 --- a/src/matrixeventprocessor.ts +++ b/src/matrixeventprocessor.ts @@ -137,21 +137,12 @@ export class MatrixEventProcessor { } public async HandleAttachment(event: IMatrixEvent, mxClient: MatrixClient): Promise<string|Discord.FileOptions> { - if (!event.content) { - event.content = {}; + if (!this.HasAttachment(event)) { + return ""; } - const hasAttachment = [ - "m.image", - "m.audio", - "m.video", - "m.file", - "m.sticker", - ].includes(event.content.msgtype as string) || [ - "m.sticker", - ].includes(event.type); - if (!hasAttachment) { - return ""; + if (!event.content) { + event.content = {}; } if (!event.content.info) { @@ -211,6 +202,19 @@ export class MatrixEventProcessor { } replyEmbed.setTimestamp(new Date(sourceEvent.origin_server_ts)); + + if (this.HasAttachment(sourceEvent)) { + const mxClient = this.bridge.getClientFactory().getClientAs(); + const url = mxClient.mxcUrlToHttp(sourceEvent.content.url); + if (["m.image", "m.sticker"].includes(sourceEvent.content.msgtype as string) + || sourceEvent.type === "m.sticker") { + // we have an image reply + replyEmbed.setImage(url); + } else { + const name = this.GetFilenameForMediaEvent(sourceEvent.content); + replyEmbed.description = `[${name}](${url})`; + } + } return replyEmbed; } catch (ex) { log.warn("Failed to handle reply, showing a unknown embed:", ex); @@ -222,6 +226,23 @@ export class MatrixEventProcessor { return embed; } + private HasAttachment(event: IMatrixEvent): boolean { + if (!event.content) { + event.content = {}; + } + + const hasAttachment = [ + "m.image", + "m.audio", + "m.video", + "m.file", + "m.sticker", + ].includes(event.content.msgtype as string) || [ + "m.sticker", + ].includes(event.type); + return hasAttachment; + } + private async SetEmbedAuthor(embed: Discord.RichEmbed, sender: string, profile?: IMatrixEvent | null) { const intent = this.bridge.getIntent(); let displayName = sender; diff --git a/test/test_matrixeventprocessor.ts b/test/test_matrixeventprocessor.ts index 6280f8112fcc732d6fd50dd83feca7741d59aacd..d733bc2d4f38dbb65c74ddb0b9d764dd34e9b9a4 100644 --- a/test/test_matrixeventprocessor.ts +++ b/test/test_matrixeventprocessor.ts @@ -124,6 +124,24 @@ function createMatrixEventProcessor(): MatrixEventProcessor { }, sender: "@_discord_1234:localhost", }; + } else if (eventId === "$image:localhost") { + return { + content: { + body: "fox.jpg", + msgtype: "m.image", + url: "mxc://fox/localhost", + }, + sender: "@fox:localhost", + }; + } else if (eventId === "$file:localhost") { + return { + content: { + body: "package.zip", + msgtype: "m.file", + url: "mxc://package/localhost", + }, + sender: "@fox:localhost", + }; } return null; }, @@ -699,5 +717,38 @@ This is the reply`, } expect(foundField).to.be.true; }); + it("should handle replies to images", async () => { + const processor = createMatrixEventProcessor(); + const result = await processor.GetEmbedForReply({ + content: { + "body": "Test", + "m.relates_to": { + "m.in_reply_to": { + event_id: "$image:localhost", + }, + }, + }, + sender: "@test:localhost", + type: "m.room.message", + } as IMatrixEvent, mockChannel as any); + expect(result!.image!.url!).to.be.equal("https://fox/localhost"); + expect(result!.description).to.be.equal("fox.jpg"); + }); + it("should handle replies to files", async () => { + const processor = createMatrixEventProcessor(); + const result = await processor.GetEmbedForReply({ + content: { + "body": "Test", + "m.relates_to": { + "m.in_reply_to": { + event_id: "$file:localhost", + }, + }, + }, + sender: "@test:localhost", + type: "m.room.message", + } as IMatrixEvent, mockChannel as any); + expect(result!.description).to.be.equal("[package.zip](https://package/localhost)"); + }); }); });