diff --git a/src/bot.ts b/src/bot.ts index 04b2b4cc0f0d4349825a814a3d64fdb054e21701..31b7ae7b1921029b51e03bf9cb175319ce1aab84 100644 --- a/src/bot.ts +++ b/src/bot.ts @@ -526,7 +526,7 @@ export class DiscordBot { return intent.sendTyping(room, isTyping); })); }).catch((err) => { - log.verbose("DiscordBot", "Failed to send typing indicator.", err); + log.warn("DiscordBot", "Failed to send typing indicator.", err); }); } diff --git a/src/messageprocessor.ts b/src/messageprocessor.ts index 8142611f14b457a8946706bd6128c8736ee51d94..283b4011257866a0602f36947217beec7b4944b0 100644 --- a/src/messageprocessor.ts +++ b/src/messageprocessor.ts @@ -48,9 +48,14 @@ export class MessageProcessor { public InsertEmbeds(content: string, msg: Discord.Message): string { for (const embed of msg.embeds) { - let embedContent = "\n----\n"; // Horizontal rule. + let embedContent = "\n\n----"; // Horizontal rule. Two to make sure the content doesn't become a title. const embedTitle = embed.url ? `[${embed.title}](${embed.url})` : embed.title; - embedContent += embedTitle != null ? `#### ${embedTitle}\n\n${embed.description}` : embed.description; + if (embedTitle) { + embedContent += "\n##### " + embedTitle; // h5 is probably best. + } + if (embed.description) { + embedContent += "\n" + embed.description; + } content += embedContent; } return content; @@ -101,8 +106,12 @@ export class MessageProcessor { public FindMentionsInPlainBody(body: string, members: Discord.GuildMember[]): string { for (const member of members) { + const matcher = escapeStringRegexp(member.user.username + "#" + member.user.discriminator) + "|" + + escapeStringRegexp(member.displayName); body = body.replace( - new RegExp(`(^| |\\t)(${escapeStringRegexp(member.displayName)})($| |\\t)` , "mg"), ` <@!${member.id}>`, + new RegExp( + `\\b(${matcher})(?=\\b)` + , "mig"), `<@!${member.id}>`, ); } return body; diff --git a/test/mocks/user.ts b/test/mocks/user.ts index d66db47989c99d347fab338e7eb36208a15ea7b4..a2d7574c997d94eacb11eccc85a687d1e78682ce 100644 --- a/test/mocks/user.ts +++ b/test/mocks/user.ts @@ -1,6 +1,7 @@ export class MockUser { public id = ""; public username: string; + public discriminator: string; constructor(id: string, username: string = "") { this.id = id; this.username = username; diff --git a/test/test_messageprocessor.ts b/test/test_messageprocessor.ts index 71b527e44d2a2431fa7fcb3a4e2b7305cbfe6945..bc756796a806e92f38b339886c03834ee6909ca1 100644 --- a/test/test_messageprocessor.ts +++ b/test/test_messageprocessor.ts @@ -122,25 +122,51 @@ describe("MessageProcessor", () => { user: { username: "TestUsername", id: "12345", + discriminator: "54321", }, })]; - const msg = "Hello TestUsername"; - const content = processor.FindMentionsInPlainBody(msg, members); - Chai.assert.equal(content, "Hello <@!12345>"); + Chai.assert.equal( + processor.FindMentionsInPlainBody("Hello TestUsername", members), + "Hello <@!12345>", + ); + Chai.assert.equal( + processor.FindMentionsInPlainBody("Hello TestUsername#54321", members), + "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: "Test", + user: { + username: "Test", + id: "54321", + }, + }), 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>"); + Chai.assert.equal(processor.FindMentionsInPlainBody("Hello TestNickname", members), "Hello <@!12345>"); + Chai.assert.equal(processor.FindMentionsInPlainBody("TestNickname: Hello", members), "<@!12345>: Hello"); + Chai.assert.equal(processor.FindMentionsInPlainBody("TestNickname, Hello", members), "<@!12345>, Hello"); + Chai.assert.equal(processor.FindMentionsInPlainBody("TestNickname Hello", members), "<@!12345> Hello"); + Chai.assert.equal(processor.FindMentionsInPlainBody("testNicKName Hello", members), "<@!12345> Hello"); + Chai.assert.equal( + processor.FindMentionsInPlainBody("I wish TestNickname was here", members), + "I wish <@!12345> was here", + ); + Chai.assert.equal( + processor.FindMentionsInPlainBody("I wish TestNickname was here, TestNickname is cool", members), + "I wish <@!12345> was here, <@!12345> is cool", + ); + Chai.assert.equal( + processor.FindMentionsInPlainBody("TestNickname was here with Test", members), + "<@!12345> was here with <@!54321>", + ); }); it("processes non-mentions correctly", async () => { const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot); @@ -175,7 +201,7 @@ describe("MessageProcessor", () => { ]; const inContent = ""; const content = processor.InsertEmbeds(inContent, msg); - Chai.assert.equal(content, "\n----\nTestDescription"); + Chai.assert.equal(content, "\n\n----\nTestDescription"); }); it("processes urlless embeds properly", () => { const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot); @@ -188,7 +214,7 @@ describe("MessageProcessor", () => { ]; const inContent = ""; const content = processor.InsertEmbeds(inContent, msg); - Chai.assert.equal(content, "\n----\n#### TestTitle\n\nTestDescription"); + Chai.assert.equal(content, "\n\n----\n##### TestTitle\nTestDescription"); }); it("processes linked embeds properly", () => { const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot); @@ -202,7 +228,7 @@ describe("MessageProcessor", () => { ]; const inContent = ""; const content = processor.InsertEmbeds(inContent, msg); - Chai.assert.equal(content, "\n----\n#### [TestTitle](testurl)\n\nTestDescription"); + Chai.assert.equal(content, "\n\n----\n##### [TestTitle](testurl)\nTestDescription"); }); it("processes multiple embeds properly", () => { const processor = new MessageProcessor(new MessageProcessorOpts("localhost"), <DiscordBot> bot); @@ -223,7 +249,7 @@ describe("MessageProcessor", () => { const content = processor.InsertEmbeds(inContent, msg); Chai.assert.equal( content, -"\n----\n#### [TestTitle](testurl)\n\nTestDescription\n----\n#### [TestTitle2](testurl2)\n\nTestDescription2", +"\n\n----\n##### [TestTitle](testurl)\nTestDescription\n\n----\n##### [TestTitle2](testurl2)\nTestDescription2", ); }); it("inserts embeds properly", () => { @@ -240,7 +266,11 @@ describe("MessageProcessor", () => { const content = processor.InsertEmbeds(inContent, msg); Chai.assert.equal( content, - "Content that goes in the message\n----\n#### [TestTitle](testurl)\n\nTestDescription", +`Content that goes in the message + +---- +##### [TestTitle](testurl) +TestDescription`, ); }); }); diff --git a/tools/addbot.ts b/tools/addbot.ts index 119788daa14b78727534225bcd3983f2bac478a0..425b83e81025b045c287c54cf23e2a4bf04229d6 100644 --- a/tools/addbot.ts +++ b/tools/addbot.ts @@ -20,7 +20,8 @@ const perms = flags.READ_MESSAGES | flags.SPEAK | flags.EMBED_LINKS | flags.ATTACH_FILES | - flags.READ_MESSAGE_HISTORY; + flags.READ_MESSAGE_HISTORY | + flags.MANAGE_WEBHOOKS; const url = `https://discordapp.com/api/oauth2/authorize?client_id=${clientId}&scope=bot&permissions=${perms}`; console.log(`Go to ${url} to invite the bot into a guild.`);