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

ContentWithMentionReplaced on roles and nicks (Fixes #208) #375

Merged
merged 11 commits into from
Jun 13, 2017
Merged

ContentWithMentionReplaced on roles and nicks (Fixes #208) #375

merged 11 commits into from
Jun 13, 2017

Conversation

jD91mZM2
Copy link
Contributor

@jD91mZM2 jD91mZM2 commented May 4, 2017

Haven't tried if it works, so ¯\_(ツ)_/¯

message.go Outdated
func (m *Message) ContentWithMentionsReplaced() string {
if m.Mentions == nil {
return m.Content
func (m *Message) ContentWithMentionsReplaced(s *Session) (content string, err error) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is breaking the API, we should have a ContentWithMentionsReplacedWithSession and document that this will replace more data than above.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

True

message.go Outdated
if !role.Mentionable {
continue
}
content = regexp.MustCompile("<@&"+regexp.QuoteMeta(role.ID)+">").ReplaceAllString(content, "@"+role.Name)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is really unperformant, instead of iterating through all the roles on each message we should use regexp.ReplaceAllStringFunc instead here, search for <@&[.*?]> and then search for the correct role name only when a mention happens.

Copy link
Contributor Author

@jD91mZM2 jD91mZM2 May 4, 2017

Choose a reason for hiding this comment

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

Well, I know it's slow and inefficient and crappy. I just kept the same syntax as previously used ¯\_(ツ)_/¯.

Copy link
Collaborator

Choose a reason for hiding this comment

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

The difference is before the mentions array tells us which things are mentioned, in this case we don't know that theres a role mention, and so we're iterating through each role and doing a regex.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh... yeah that's true. Nice catch!

Copy link
Collaborator

@iopred iopred left a comment

Choose a reason for hiding this comment

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

While you're here, you should also make channel mentions work too.

Also, a test here wouldn't hurt, should be very easy to create as we don't need Session to be connected.

message.go Outdated

channel, err := s.State.Channel(m.ChannelID)
if err != nil {
return
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should probably return ContentWithMentionsReplaced.

message.go Outdated
return content

if patternRoles == nil {
patternRoles = regexp.MustCompile("<&[^>]*>")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Only compile this once, where you define the var, also I prefer a lazy regex:

<&[0-9]*>

Copy link
Contributor Author

@jD91mZM2 jD91mZM2 May 8, 2017

Choose a reason for hiding this comment

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

I do only compile this once. The difference is that I don't compile it in case it's not used

True, but what if Discord decides not to use 0-9 or something weird like that?

Copy link
Collaborator

Choose a reason for hiding this comment

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

id's are actually numbers, we just use strings internally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I know. But we never know if they decide to change them. Or, we do know that that's not gonna happen. Still. Better be paranoid 😛

Copy link
Collaborator

@iopred iopred May 8, 2017

Choose a reason for hiding this comment

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

Nope, being paranoid means you litter your code with defensiveness that is unwarranted.

Discord uses snowflakes as their ID's which are 64bit ints and have huge amounts of infrastructure around it. In fact we are actually the bad guys because we don't define our ID's as strings (which python does for example).

At worst you should be using (.*?), but [0-9]* is correct.

message.go Outdated
return mention
}

return "<@&" + role.ID + ">"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't you want return "@"+role.Name here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

lol oops

message.go Outdated
}

patternRoles.ReplaceAllStringFunc(content, func(mention string) string {
role, err := s.State.Role(channel.GuildID, mention)
Copy link
Collaborator

Choose a reason for hiding this comment

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

This won't work right? You're passing <&40394820394209> here as the role id instead of just 40394820394209, in bruxism I just do mention[3 : len(mention)-1]

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, yeah, that's true. Will correct!

@jD91mZM2
Copy link
Contributor Author

jD91mZM2 commented May 8, 2017

It does require a session to get the channel 🤔

EDIT: I just realized there is MentionRoles. Should I use that?

@iopred
Copy link
Collaborator

iopred commented May 8, 2017

Oh, there is! Yeah definitely use MentionRoles instead of the regexp, but use similar regexp code for MentionRooms.

You can make a fake Session/State:

fakeState = &State{}
fakeState.Add.....
fakeSession = &Session{State:fakeState}

message.ContentWithMoreMentionsReplaced(fakeSession)

@jD91mZM2
Copy link
Contributor Author

jD91mZM2 commented May 8, 2017

Yep, trying to fake a session and state already 😛

message.go Outdated
return content

if patternChannels == nil {
patternChannels = regexp.MustCompile("<#[^>]*>")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Compile this once.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think you missed this, move this to line 183 and use "<#[0-9]*>"


for _, user := range m.Mentions {
content = strings.NewReplacer(
"<@"+user.ID+">", "@"+user.Username,
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should be user.Username:
https://discordapp.com/developers/docs/resources/channel#message-formatting

Only the @! replaces with nick.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Realized that, but didn't bother to fix it, because for some reason I thought I'd have to make a bunch of workarounds. Didn't realize it was as easy as changing that 😛

message.go Outdated
content = regexp.MustCompile(fmt.Sprintf("<@!?(%s)>", user.ID)).ReplaceAllString(content, "@"+user.Username)
member, err := s.State.Member(channel.GuildID, user.ID)
nick := user.Username
if (err == nil && member.Nick != "") || nick == "" {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the nick == "" check is unneeded, a Member will always have a Username.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's true. No idea why I put that there 😆

@iopred
Copy link
Collaborator

iopred commented May 8, 2017

Thanks for all the work on this guy <3

@bwmarrin bwmarrin added this to the v0.17.0 milestone May 15, 2017
@jD91mZM2
Copy link
Contributor Author

Reason I didn't move it at first was because I thought only initiating it if necessary would be better. But I guess all global variables in Go are lazily initiated anyways, so... ¯_(ツ)_/¯

And then now I realized it could cause race conditions. Better just move it where it should be

@iopred
Copy link
Collaborator

iopred commented Jun 13, 2017

Thanks again!

@iopred iopred merged commit 5a02430 into bwmarrin:develop Jun 13, 2017
@jD91mZM2 jD91mZM2 deleted the 2 branch July 23, 2017 06:21
ErikMcClure pushed a commit to ErikMcClure/discordgo that referenced this pull request Aug 4, 2020
…) (bwmarrin#375)

* ContentWithMentionReplaced on roles and nicks (Fixes bwmarrin#208)

* Compatibility

* Like this? 🤔

* More efficient regexp

* Tweaked a little

* Tweaked a little more

* Tweaked even more

* Removed unessecary crap condition that is useless

* Disallow voice channel

* Moved regexp declaration
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.

3 participants