diff --git a/config/config.sample.yaml b/config/config.sample.yaml index ed97ed42640ea79345159f5c5868bc810c68778b..7b3680e3904ee8c309b57dd01f5d6d6315927d4a 100644 --- a/config/config.sample.yaml +++ b/config/config.sample.yaml @@ -89,3 +89,6 @@ limits: # (Copies of a sent message may arrive from discord before we've # fininished handling it, causing us to echo it back to the room) discordSendDelay: 750 +ghosts: + # the tag to append to ghost nicknames + tag: "" diff --git a/config/config.schema.yaml b/config/config.schema.yaml index 9a35f4b26cee167a0a94009d4614be1c70d127e9..68ecba2af8dc808d77ae8ad9d7a7349874c133e0 100644 --- a/config/config.schema.yaml +++ b/config/config.schema.yaml @@ -109,3 +109,8 @@ properties: type: "boolean" ghostsLeave: type: "boolean" + ghosts: + type: "object" + properties: + tag: + type: "string" diff --git a/src/config.ts b/src/config.ts index 3fdde89e4e9d5626a23654952bbfe7957a37484f..b54ca4cf02da2d5f5e0512e2da1e487a988b4d4a 100644 --- a/src/config.ts +++ b/src/config.ts @@ -23,6 +23,7 @@ export class DiscordBridgeConfig { public room: DiscordBridgeConfigRoom = new DiscordBridgeConfigRoom(); public channel: DiscordBridgeConfigChannel = new DiscordBridgeConfigChannel(); public limits: DiscordBridgeConfigLimits = new DiscordBridgeConfigLimits(); + public ghosts: DiscordBridgeConfigGhosts = new DiscordBridgeConfigGhosts(); /** * Apply a set of keys and values over the default config. @@ -109,3 +110,7 @@ export class LoggingFile { public enabled: string[] = []; public disabled: string[] = []; } + +class DiscordBridgeConfigGhosts { + public tag: string = ""; +} diff --git a/src/usersyncroniser.ts b/src/usersyncroniser.ts index 3a329a3f1504f45ba8838181c17c817bfd135ead..2af4dac34fa821e2b5fe3d28622f163dee20afa3 100644 --- a/src/usersyncroniser.ts +++ b/src/usersyncroniser.ts @@ -234,7 +234,8 @@ export class UserSyncroniser { id: discordUser.id, mxUserId: `@_discord_${discordUser.id}${mxidExtra}:${this.config.bridge.domain}`, }); - const displayName = this.displayNameForUser(discordUser); + const displayName = this.displayNameForUser(discordUser) + + (this.config.ghosts.tag ? " " + this.config.ghosts.tag : ""); // Determine if the user exists. const remoteId = discordUser.id + mxidExtra; const remoteUser = await this.userStore.getRemoteUser(remoteId); @@ -273,7 +274,7 @@ export class UserSyncroniser { const guildState: IGuildMemberState = Object.assign({}, DEFAULT_GUILD_STATE, { bot: newMember.user.bot, displayColor: newMember.displayColor, - displayName: newMember.displayName, + displayName: newMember.displayName + (this.config.ghosts.tag ? " " + this.config.ghosts.tag : ""), id: newMember.id, mxUserId: `@_discord_${newMember.id}:${this.config.bridge.domain}`, roles: newMember.roles.map((role) => { return { diff --git a/test/test_usersyncroniser.ts b/test/test_usersyncroniser.ts index c5b7b1cff0418e3f72494acf3194652745255b53..2984d293e8d77b25b4e98971ed0d4ac1673f68c9 100644 --- a/test/test_usersyncroniser.ts +++ b/test/test_usersyncroniser.ts @@ -64,7 +64,7 @@ const UserSync = (Proxyquire("../src/usersyncroniser", { }, })).UserSyncroniser; -function CreateUserSync(remoteUsers: RemoteUser[] = []): UserSyncroniser { +function CreateUserSync(remoteUsers: RemoteUser[] = [], nickTag: string = ""): UserSyncroniser { UTIL_UPLOADED_AVATAR = false; SEV_ROOM_ID = null; SEV_CONTENT = null; @@ -153,6 +153,7 @@ function CreateUserSync(remoteUsers: RemoteUser[] = []): UserSyncroniser { }; const config = new DiscordBridgeConfig(); config.bridge.domain = "localhost"; + config.ghosts.tag = nickTag; return new UserSync(bridge as Bridge, config, discordbot, userStore as any); } @@ -196,6 +197,27 @@ describe("UserSyncroniser", () => { expect(state.avatarId, "AvatarID").is.empty; expect(state.avatarUrl, "AvatarUrl").is.null; }); + it("Will obay name tags", async () => { + const remoteUser = new RemoteUser("123456"); + remoteUser.avatarurl = "test.jpg"; + remoteUser.displayname = "TestUsername"; + + const userSync = CreateUserSync([remoteUser], "(Discord)"); + const user = new MockUser( + "123456", + "TestUsername", + "6969", + "test.jpg", + "111", + ); + const state = await userSync.GetUserUpdateState(user as any); + expect(state.createUser, "CreateUser").is.false; + expect(state.removeAvatar, "RemoveAvatar").is.false; + expect(state.displayName, "DisplayName").equals("TestUsername#6969 (Discord)"); + expect(state.mxUserId , "UserId").equals("@_discord_123456:localhost"); + expect(state.avatarId, "AvatarID").is.empty; + expect(state.avatarUrl, "AvatarUrl").is.null; + }); it("Will change avatars", async () => { const remoteUser = new RemoteUser("123456"); remoteUser.avatarurl = "test.jpg"; @@ -467,6 +489,18 @@ describe("UserSyncroniser", () => { const state = await userSync.GetUserStateForGuildMember(member as any); expect(state.displayName).to.be.equal("BestDog"); }); + it("Will will obay name tags", async () => { + const userSync = CreateUserSync([new RemoteUser("123456")], "(Discord)"); + const guild = new MockGuild( + "654321"); + const member = new MockMember( + "123456", + "username", + guild, + "BestDog"); + const state = await userSync.GetUserStateForGuildMember(member as any); + expect(state.displayName).to.be.equal("BestDog (Discord)"); + }); it("Will correctly add roles", async () => { const userSync = CreateUserSync([new RemoteUser("123456")]); const guild = new MockGuild(