Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use webhooks to reflect irc usernames + avatars #230

Merged
merged 17 commits into from
Mar 22, 2018

Conversation

Fiaxhs
Copy link
Contributor

@Fiaxhs Fiaxhs commented May 2, 2017

This fixes #128

The discord bot gets renamed with the irc nickname, and use the account avatar if there's a matching username in the room.

discord

@coveralls
Copy link

coveralls commented May 2, 2017

Coverage Status

Coverage decreased (-3.3%) to 95.076% when pulling 2c05038 on Fiaxhs:master into fe37ec4 on reactiflux:master.

@coveralls
Copy link

coveralls commented May 2, 2017

Coverage Status

Coverage decreased (-3.3%) to 95.057% when pulling b4452dd on Fiaxhs:master into fe37ec4 on reactiflux:master.

@Throne3d
Copy link
Collaborator

Throne3d commented May 2, 2017

Could you add tests for getDiscordAvatar and findWebhook, as well as ensuring that it uses a webhook in sendToDiscord when one is available (and then does not go on to send a regular message)? I can probably advise on how to do this if you're unsure.

@Fiaxhs
Copy link
Contributor Author

Fiaxhs commented May 2, 2017

Sure! I'll do this soon.

Copy link
Collaborator

@Throne3d Throne3d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bump on tests?

@Fiaxhs
Copy link
Contributor Author

Fiaxhs commented May 17, 2017 via email

@coveralls
Copy link

coveralls commented May 30, 2017

Coverage Status

Coverage increased (+0.1%) to 98.582% when pulling 2bf761b on Fiaxhs:master into 8c4d83a on reactiflux:master.

@Fiaxhs
Copy link
Contributor Author

Fiaxhs commented May 30, 2017

Finally got some time to write tests, sorry for the delay :)

@Kakkela
Copy link

Kakkela commented May 30, 2017

I would like to add this as a warning if this gets pushed to master.
https://trello.com/c/6ZZTEBJw/278-webhook-incorrectly-stacks-message-authors-on-android-client

So basically currently this wont be really readable on android client because of messages merging under one author incorrectly.

@NightScript370
Copy link

Aw man, you already made it work with latest commit. Oh well. I'll delete my fork now.

Throne3d
Throne3d previously approved these changes May 30, 2017
@Throne3d
Copy link
Collaborator

Throne3d commented May 30, 2017

Testing this locally, it seems to work well, and the tests added should help to ensure it keeps this functionality.

Assuming @ekmartin is okay with it, I think this is good to go.

(I'm slightly worried about IRC users masquerading as authenticated Discord users by changing to their usernames, but I don't think this is readily fixable, and the messages have 'BOT' marked on them, and it presents a problem on the IRC end as is anyway, so this shouldn't actually make it much if at all worse.)

Edit: Oh, a note – maybe add to the readme that webhooks allow for this sort of display behavior? That's not immediately obvious from the term 'webhook'.

@Fiaxhs
Copy link
Contributor Author

Fiaxhs commented May 30, 2017

Just added a note on webhooks. However feel free to change it, even the image. I feel quite uncomfortable writing the readme for a project that isn't mine!

@coveralls
Copy link

coveralls commented May 30, 2017

Coverage Status

Coverage increased (+0.1%) to 98.582% when pulling 8c0c11a on Fiaxhs:master into 8c4d83a on reactiflux:master.

@Throne3d
Copy link
Collaborator

That looks like an accurate and useful summary, so it should be fine! Thanks.

@NightScript370
Copy link

@Fiaxhs Can you make this case-insensitive?

@Throne3d Throne3d dismissed their stale review July 1, 2017 20:39

Noted a necessary change

lib/bot.js Outdated
}
return null;
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think case insensitivity should be a blocker but it does make me wonder what happens if two Discord users have the same display name, as this seems doable, or the same name ignoring case. This is a problem elsewhere already, I guess, such as when an IRC user mentions a Discord user.

This function also currently checks by username as opposed to nickname (display name), which might be unexpected. This should maybe:

  1. Check by nickname and username
  2. Check by the above, case-insensitively, if no match found
  3. If more than one found, default to no fancy icon

That might be more complicated than necessary, but I think it would suffice for most or all use-cases. It should at least check nicknames?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the purpose of checking case-sensitively at all? Performance?

Copy link
Collaborator

@Throne3d Throne3d Aug 16, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that if you have two users with the same nickname barring case, you can pick a particular one to use. (It's also possible to have two users with the exact same nickname, case-sensitively, but then the ambiguity is basically required as opposed to mostly quite avoidable.)

Maybe it's over-much, though – if two users have the same nickname, case-sensitive or not, it's not particularly unreasonable to expect weird behavior around the ambiguity. It at least shouldn't be actively detrimental.

lib/bot.js Outdated
}).catch(logger.error);
return;
}

Copy link
Collaborator

@Throne3d Throne3d Jul 1, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

… I also failed to notice that this seems to discard the custom formatting when sending with a webhook; I think the 'Webhooks first' code should go after the const withAuthor… bit, here, and use withAuthor instead of withMentions.

Edit: Or, rather… make a new pattern for webhook messages?

Edit2: … I'm not sure. Uh. It seems plausibly useful to be able to change the formatting for a webhook message, if people were changing the withAuthor thing drastically. Maybe. But defeats the point of a webhook a little. Uh. Maybe ignore this. We can address it later if anybody complains. (Above thing should still use nicknames and maybe case insensitively check.)

@Throne3d
Copy link
Collaborator

Throne3d commented Jul 1, 2017

(Sorry I didn't notice this before.)

@NightScript370
Copy link

Hey @Fiaxhs, can you update this to the latest commit?

@Fiaxhs
Copy link
Contributor Author

Fiaxhs commented Jul 31, 2017

Nice! I didn't see the addUser function, this would have save me some time.

I keep finding things to be picky about

Fine by me :)

Thanks for your contribution!

You're welcome! I use it every day, for once I could bring some value to a project I use.

Copy link
Member

@ekmartin ekmartin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry about the late answer here - this is definitely cool. Just a few minor comments :)

lib/bot.js Outdated

// Remove channel passwords from the mapping and lowercase IRC channel names
_.forOwn(options.channelMapping, (ircChan, discordChan) => {
this.channelMapping[discordChan] = ircChan.split(' ')[0].toLowerCase();
});

// Extract id and token from Webhook urls
_.forOwn(options.webhooks, (url, chan) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

chan -> channel

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(consistent with your block on line 80)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

on second thought, might as well merge this down into the connect block and only have one forOwn(options.webhooks, ...)?

lib/bot.js Outdated
@@ -258,7 +268,9 @@ class Bot {
sendToIRC(message) {
const author = message.author;
// Ignore messages sent by the bot itself:
if (author.id === this.discord.user.id) return;
if (author.id === this.discord.user.id ||
Object.keys(this.webhooks).some(chan => this.webhooks[chan].id === author.id)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

channel

lib/bot.js Outdated
@@ -335,6 +347,44 @@ class Bot {
return null;
}

findWebhook(ircChannel) {
const discordChannelName = this.invertedMapping[ircChannel.toLowerCase()];
if (discordChannelName) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well do: return discordChannelName && this.webhooks[discordChannelName].

const guildMembers = this.findDiscordChannel(channel).guild.members;
const findByNicknameOrUsername = caseSensitive =>
(member) => {
if (caseSensitive) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are discord nicknames case sensitive or insensitive? Can there be two users with the same username/nickname with different casing? I think we can simplify this logic as long as we know what assumptions we're making.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Insensitive and yes, which is why I suggested (I think I suggested?) matching case sensitively first and then falling back to case insensitive if there's no match found. (Since IRC users have no way to, in a dropdown, select the correct one of the various case sensitivities – Discord users have this ability since Discord translates the mention in its UI – I thought it best to allow them to force the right one by picking the right case, where relevant.)

Copy link
Contributor Author

@Fiaxhs Fiaxhs Aug 3, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can even have two users with the exact same nickname (same case): http://i.imgur.com/ACuYlcS.png + http://i.imgur.com/oD3JEfK.png
(And @maorninja suggested the change :) )

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(Yes but I suggested here the logic for how to implement it. :P)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

( right :D )

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I would blame Discord because they allow 2 users with the exact same nickname, but that's just my opinion. I wish there was a bot that could block that.

lib/bot.js Outdated
username: author,
text,
avatarURL: this.getDiscordAvatar(author, channel)
}).catch(logger.error);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would the error here not bubble up to our on('error' handler? (I don't know)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Webhook clients aren't attached to the main discord client:

this.discord = new discord.Client({ autoReconnect: true });
vs.
this.webhooks[channel] = { [...], client: new discord.WebhookClient(id, token);}
So there's no way errors will bubble up to the main on('error'

I could probably define a function and use it for both error handling, though.

lib/bot.js Outdated
const webhook = this.findWebhook(channel);
if (webhook) {
logger.debug('Sending message to Discord via webhook', withMentions, channel, '->', `#${discordChannel.name}`);
webhook.client.sendMessage(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

formatting nitpick:

webhook.client.sendMessage(withMentions, {
  text,
  username: author,
  avatarUrl: this.getDiscordAvatar(author, channel)
})

(could even do const avatarURL = this.getDiscordAvatar(author, channel); first - always optimize for readability)

test/bot.test.js Outdated
@@ -807,4 +810,81 @@ describe('Bot', function () {
this.sendStub.should.have.been.calledOnce;
this.sendStub.getCall(0).args.should.deep.equal([msg]);
});

it('should create webhooks clients for each webhook url in the config', function () {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of tests - nice!

Variables renaming
Improved code readability
@coveralls
Copy link

coveralls commented Aug 3, 2017

Coverage Status

Coverage increased (+0.07%) to 99.327% when pulling 549b8fb on Fiaxhs:master into ddd9c54 on reactiflux:master.

@qaisjp
Copy link

qaisjp commented Aug 16, 2017

What if we fall back to adorable.io avatars?

See https://github.com/ekmartin/slack-irc/ and qaisjp/go-discord-irc@8593484

@qaisjp
Copy link

qaisjp commented Aug 16, 2017

Also, please send feedback to Discord asking them to put some focus on this! https://trello.com/c/6ZZTEBJw

@Kakkela's #230 (comment) shows a major block

@Throne3d
Copy link
Collaborator

Throne3d commented Aug 16, 2017

@qiasjp

I'm not sure there's a need to fallback to specific avatars – if the users haven't got Discord accounts with avatars, then they haven't chosen an avatar, so it seems sensible to stick to what Discord does by default? (That is, the standard game controller picture.)

I agree that there should be a warning about the bug when this gets merged. That's a pretty big issue on Discord's end. I don't think it should be a block to us merging this, but instead added as a clear warning in the relevant config area, so users of the individual servers can choose whether to enable it despite this.

@qaisjp
Copy link

qaisjp commented Aug 16, 2017

@Throne3d yes but the Discord default avatars have a bit of variety. the webhook currently has the same default avatar across usernames.

fyi the only reason I suggested it is because @ekmartin's slack bridge supports it

@qaisjp
Copy link

qaisjp commented Aug 17, 2017

Also, something to mention to people reading this issue:

A nice workaround for the Android/web bug is to alternate the webhook per user

(This wouldn't be suitable for reactiflux/discord-irc, but my purpose build discord-irc bridge bot will do this)

const webhook = this.findWebhook(channel);
if (webhook) {
logger.debug('Sending message to Discord via webhook', withMentions, channel, '->', `#${discordChannel.name}`);
const avatarURL = this.getDiscordAvatar(author, channel);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

During netsplits author is nil. This would usually send some message like <${username}> ${message} (or something similar, I can't recall. but the message would contain ${} sent verbatim). Now this.getDiscordAvatar crashes with TypeError: Cannot read property 'toLowerCase' of undefined

@NightScript370
Copy link

NightScript370 commented Sep 24, 2017

EDIT: NVM.

@coveralls
Copy link

coveralls commented Jan 11, 2018

Coverage Status

Coverage increased (+0.1%) to 98.48% when pulling 90c901a on Fiaxhs:master into 68d0fd8 on reactiflux:master.

@Fiaxhs
Copy link
Contributor Author

Fiaxhs commented Jan 15, 2018

@Kovaelin Here's what my config looks like:

{
  "channelMapping": {
    "#machinzone": "#machinzonefr",
    "#crypto": "#machincrypto",
    "#dev": "#machindev"
  }
  [...]
  "webhooks": {
    "#crypto": "https://discordapp.com/api/webhooks/xxxx/XXXXX",
    "#machinzone": "https://discordapp.com/api/webhooks/xxxx/XXXXX",
    "#dev": "https://discordapp.com/api/webhooks/xxxx/XXXXX"
  }
}

@Kovaelin
Copy link

I still can't seem to get the webhook to work. Do I have to change any of the other files? Does it work if I use the Discord channel ID rather than the channel name?

My config file looks like this:
[
{
"nickname": "ROBOBOT",
"server": "IRC.SERVER.BOT",
"discordToken": "TOkeN",
"commandCharacters": ["!"],
"ircStatusNotices": true,
"ircOptions": {
"floodProtection": false,
"encoding": "utf-8"
},
"channelMapping": {
"DISCORDIDNUMBERSA": "#IRC"
},
"webhooks": {
"NUMBERSA": "https://discordapp.com/api/webhooks/COPYPASTEA/COPYPASTEB"
}
},

{
"nickname": "ROBOBOT2",
"server": "IRC.SERVER.BOT",
"discordToken": "TOkeN",
"channelMapping": {
"DISCORDIDNUMBERSB": "#IRC2"
},
"commandCharacters": ["!"]
}
]

@Fiaxhs
Copy link
Contributor Author

Fiaxhs commented Jan 15, 2018

@Kovaelin Could you open an issue on https://github.com/Fiaxhs/discord-irc instead, please?

@ryantheleach
Copy link

Still looking for this even with the bug. This would be a huge improvement to quality of life

@Kakkela
Copy link

Kakkela commented Mar 21, 2018

Webhook merging bug on Android is now moved to "Claimed fixed, needs verification"
I'm going to test on my bridge today or tomorrow. Not sure if it's fixed on just Alpha channel on Android or what.

https://trello.com/c/6ZZTEBJw/278-webhook-incorrectly-stacks-message-authors-on-android-client

@qaisjp
Copy link

qaisjp commented Mar 21, 2018 via email

@Kakkela
Copy link

Kakkela commented Mar 22, 2018

Yes this does now indeed work on Android (all channels) as intended and no unnecessary merging happens.

@qaisjp
Copy link

qaisjp commented Mar 22, 2018 via email

@Fiaxhs Fiaxhs closed this Mar 22, 2018
@Fiaxhs Fiaxhs reopened this Mar 22, 2018
@ekmartin ekmartin merged commit c7263b7 into reactiflux:master Mar 22, 2018
@ekmartin
Copy link
Member

Published in version 2.6.0 of discord-irc - thank you for your patience!

I wonder if the usernames on the Discord side should be suffixed with (IRC) to make what's happening clearer though? If you think that's a good idea we can publish a new version later.

@qaisjp
Copy link

qaisjp commented Mar 22, 2018 via email

@ekmartin
Copy link
Member

Opened an issue for it: #377 - PRs welcome!

@Kovaelin
Copy link

Kovaelin commented Apr 2, 2018

Thank you for this update!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

use webhooks to mirror users usernames
9 participants