From a66e9f72df59ce29312308f8b091301a4065c45b Mon Sep 17 00:00:00 2001
From: Will Hunt <half-shot@molrams.com>
Date: Tue, 12 Sep 2017 09:27:06 +0100
Subject: [PATCH] Made Mention Matcher less aggressive and added tests.

---
 src/bot.ts                    | 15 +++--------
 src/messageprocessor.ts       | 10 +++++++
 test/test_messageprocessor.ts | 50 +++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/src/bot.ts b/src/bot.ts
index 91a75d5..40b8cc8 100644
--- a/src/bot.ts
+++ b/src/bot.ts
@@ -11,7 +11,6 @@ import * as log from "npmlog";
 import * as Bluebird from "bluebird";
 import * as mime from "mime";
 import * as path from "path";
-import * as escapeStringRegexp from "escape-string-regexp";
 
 // Due to messages often arriving before we get a response from the send call,
 // messages get delayed from discord.
@@ -151,11 +150,11 @@ export class DiscordBot {
           icon_url: profile.avatar_url,
           url: `https://matrix.to/#/${event.sender}`,
         },
-        description: this.HandleMentions(event.content.body, channel.members.array()),
+        description: this.msgProcessor.FindMentionsInPlainBody(event.content.body, channel.members.array()),
       });
     }
     return new Discord.RichEmbed({
-      description: this.HandleMentions(event.content.body, channel.members.array()),
+      description: this.msgProcessor.FindMentionsInPlainBody(event.content.body, channel.members.array()),
     });
   }
 
@@ -224,7 +223,7 @@ export class DiscordBot {
   }
 
   public async ProcessMatrixRedact(event: any) {
-    log.info("DiscordBot", `Got redact request for ${event.reacts}`);
+    log.info("DiscordBot", `Got redact request for ${event.redacts}`);
     log.verbose("DiscordBot", `Event:`, event);
     const storeEvent = await this.store.Get(DbEvent, {matrix_id: event.redacts + ";" + event.room_id});
     if (!storeEvent.Result) {
@@ -310,13 +309,6 @@ export class DiscordBot {
     return "matrix-media." + mime.extension(content.info.mimetype);
   }
 
-  private HandleMentions(body: string, members: Discord.GuildMember[]): string {
-    for (const member of members) {
-      body = body.replace(new RegExp(`(^| |\\t)${escapeStringRegexp(member.displayName)}` , "mg"), ` <@!${member.id}>`);
-    }
-    return body;
-  }
-
   private GetRoomIdsFromChannel(channel: Discord.Channel): Promise<string[]> {
     return this.bridge.getRoomStore().getEntriesByRemoteRoomData({
       discord_channel: channel.id,
@@ -556,7 +548,6 @@ export class DiscordBot {
         });
       });
       if (msg.content !== null && msg.content !== "") {
-        // Replace mentions.
         this.msgProcessor.FormatDiscordMessage(msg).then((result) => {
             rooms.forEach((room) => {
               intent.sendMessage(room, {
diff --git a/src/messageprocessor.ts b/src/messageprocessor.ts
index 8d5639d..058f119 100644
--- a/src/messageprocessor.ts
+++ b/src/messageprocessor.ts
@@ -2,6 +2,7 @@ import * as Discord from "discord.js";
 import * as marked from "marked";
 import * as log from "npmlog";
 import { DiscordBot } from "./bot";
+import * as escapeStringRegexp from "escape-string-regexp";
 
 const USER_REGEX = /<@!?([0-9]*)>/g;
 const CHANNEL_REGEX = /<#?([0-9]*)>/g;
@@ -84,4 +85,13 @@ export class MessageProcessor {
         }
         return content;
     }
+
+    public FindMentionsInPlainBody(body: string, members: Discord.GuildMember[]): string {
+      for (const member of members) {
+        body = body.replace(
+            new RegExp(`(^| |\\t)(${escapeStringRegexp(member.displayName)})($| |\\t)` , "mg"), ` <@!${member.id}>`,
+        );
+      }
+      return body;
+    }
 }
diff --git a/test/test_messageprocessor.ts b/test/test_messageprocessor.ts
index fdffdb4..fcf7261 100644
--- a/test/test_messageprocessor.ts
+++ b/test/test_messageprocessor.ts
@@ -112,4 +112,54 @@ describe("MessageProcessor", () => {
             Chai.assert.equal(content, "Hello ![3333333](mxc://image)");
         });
     });
+    describe("FindMentionsInPlainBody", () => {
+        it("processes mentioned username correctly", async () => {
+            const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot);
+            const guild: any = new MockGuild("123", []);
+            const members: Discord.GuildMember[] = [new Discord.GuildMember(guild, {
+                user: {
+                    username: "TestUsername",
+                    id: "12345",
+                },
+            })];
+            const msg = "Hello TestUsername";
+            const content = processor.FindMentionsInPlainBody(msg, members);
+            Chai.assert.equal(content, "Hello <@!12345>");
+        });
+        it("processes mentioned nickname correctly", async () => {
+            const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot);
+            const guild: any = new MockGuild("123", []);
+            const members: Discord.GuildMember[] = [new Discord.GuildMember(guild, {
+                nick: "TestNickname",
+                user: {
+                    username: "TestUsername",
+                    id: "12345",
+                },
+            })];
+            const msg = "Hello TestNickname";
+            const content = processor.FindMentionsInPlainBody(msg, members);
+            Chai.assert.equal(content, "Hello <@!12345>");
+        });
+        it("processes non-mentions correctly", async () => {
+            const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot);
+            const guild: any = new MockGuild("123", []);
+            const members: Discord.GuildMember[] = [new Discord.GuildMember(guild, {
+                nick: "that",
+                user: {
+                    username: "TestUsername",
+                    id: "12345",
+                },
+            }),
+            new Discord.GuildMember(guild, {
+                nick: "testingstring",
+                user: {
+                    username: "that",
+                    id: "12345",
+                },
+            })];
+            const msg = "Welcome thatman";
+            const content = processor.FindMentionsInPlainBody(msg, members);
+            Chai.assert.equal(content, "Welcome thatman");
+        });
+    });
 });
-- 
GitLab