-
Notifications
You must be signed in to change notification settings - Fork 0
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
Sync emojis in comments #1
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work @LokeshN 🎉 I think this feature is going to provide lot of value
I have a few requests on how we can improve the code in regards to:
- Handling emoji aliases and skin tones
- De-duplicating some code
- Supporting PRs and issues instead of just comments
p.emojiMap = map[string]string{ | ||
"+1": "+1", | ||
"-1": "-1", | ||
"laughing": "laugh", | ||
"confused": "confused", | ||
"heart": "heart", | ||
"tada": "hooray", | ||
"rocket": "rocket", | ||
"eyes": "eyes", | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There are aliases such as thumbsup
, and skin tone-specific versions like :-1_medium_light_skin_tone:
that Mattermost users could have used for their reaction.
You can pre-populate a map for the skin tone-specific ones like this:
var baseGithubEmojiMap = map[string]string{
"+1": "+1",
"thumbsup": "+1",
}
var githubEmojiMap = map[string]string{}
for systemEmoji := range model.SystemEmojis {
for mmBase, ghBase := range baseGithubEmojiMap {
if strings.HasPrefix(systemEmoji, mmBase) {
githubEmojiMap[systemEmoji] = ghBase
}
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since emojiMap
is a static piece of data, we can instead define it on the module level, rather than as a struct field. You can use this syntax on the module level:
var githubEmojiMap = map[string]string{}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0/5 leaving it in p.
and initializing in OnActivate
(or NewPlugin
) is just as idiomatic, for plugins.
if githubEmoji == "" { | ||
return | ||
} | ||
post, error := p.client.Post.GetPost(reaction.PostId) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
error
is a an existing "type" in Go, so we shouldn't shadow it here
post, error := p.client.Post.GetPost(reaction.PostId) | |
post, err := p.client.Post.GetPost(reaction.PostId) |
} | ||
post, error := p.client.Post.GetPost(reaction.PostId) | ||
if error != nil { | ||
p.API.LogError("Invalid post id. Addition of reaction failed.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p.API.LogError("Invalid post id. Addition of reaction failed.") | |
p.API.LogError("Error fetching post for reaction add", "error", err.Error()) |
|
||
repo := post.GetProp("gh_repo") | ||
if repo == nil { | ||
p.API.LogDebug("Required prop is not present. This post is not created by this plugin, hence ignoring") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove this log message. This will be the case for almost all reactions added on Mattermost, so it's not something we need to log here.
For further checks for legitimacy, we should also check to see if the post.UserId
is the GitHub bot's user id
return | ||
} | ||
|
||
orgRepo := strings.Split(repo.(string), "/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest we make the code more compact by doing nil checking and type assertion in the same line. The ok
syntax is the "safer" way of doing a type assertion. Otherwise if repo
is not a string, the program will panic. That is highly unlikely here but should always be treated as possible.
orgRepo := strings.Split(repo.(string), "/") | |
repo, ok := post.GetProp("gh_repo").(string) | |
if !ok || repo == "" { | |
return | |
} | |
orgRepo := strings.Split(repo, "/") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
orgRepo := strings.Split(repo.(string), "/") | |
orgRepo := strings.Split(repo.(string), "/") | |
if len(orgRepo) != 2 { | |
// handle error | |
} |
|
||
reactions, _, error := ghClient.Reactions.ListIssueCommentReactions(context.Background(), orgRepo[0], orgRepo[1], int64(id), &github.ListOptions{}) | ||
|
||
if error == nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should "return early" instead of having this indented block for the rest of the function
if error == nil { | |
if err != nil { | |
p.API.LogDebug(...) | |
return |
} | ||
post, error := p.client.Post.GetPost(reaction.PostId) | ||
if error != nil { | ||
p.API.LogError("Invalid post id. Removal of reaction failed.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please apply the change requests for ReactionHasBeenAdded
to this function as well. Also, there is a decent amount of code duplication among these two functions. Can you please try extracting some code out to make the functions a bit cleaner?
It may be better to keep it as-is, since there are different "error" and "harmless skip" cases here, and it could be complicated to handle the different "log error" versus "just return" cases between the caller and callee.
|
||
if error == nil { | ||
for _, reactionObj := range reactions { | ||
if info.UserID == reaction.UserId && p.emojiMap[reaction.EmojiName] == reactionObj.GetContent() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p.emojiMap[reaction.EmojiName]
should ideally already be computed as a local variable to avoid verbosity on this long line
emoji := p.emojiMap[reaction.EmojiName]
// delete this reaction | ||
_, error = ghClient.Reactions.DeleteIssueCommentReaction(context.Background(), orgRepo[0], orgRepo[1], int64(id), reactionObj.GetID()) | ||
if error != nil { | ||
p.API.LogError("Error found while removing issue comment reaction") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p.API.LogError("Error found while removing issue comment reaction") | |
p.API.LogDebug("Error removing issue comment reaction", "error", err.Error()) |
repoName := repo.GetFullName() | ||
repoName = strings.ToLower(repoName) | ||
commentID := event.GetComment().GetID() | ||
|
||
post.AddProp("gh_repo", repoName) | ||
post.AddProp("gh_object_id", commentID) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be applied to any webhook event associated with a PR or issue, not just the "issue comment" events. For example, if a new pull request is created, I should be able to react to the post in Mattermost and have my reaction on the PR itself in GitHub. Probably best to try to de-duplicate this code addition as well.
I'm thinking we will need to add an gh_object_type
or gh_object_name
post prop in order know what github API call to make, e.g. DeleteIssueCommentReaction
vs DeleteIssueReaction
@LokeshN I have one more request to add. Can you please write unit tests for the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly 👍 -ing @mickmister's comments
p.emojiMap = map[string]string{ | ||
"+1": "+1", | ||
"-1": "-1", | ||
"laughing": "laugh", | ||
"confused": "confused", | ||
"heart": "heart", | ||
"tada": "hooray", | ||
"rocket": "rocket", | ||
"eyes": "eyes", | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0/5 leaving it in p.
and initializing in OnActivate
(or NewPlugin
) is just as idiomatic, for plugins.
@@ -702,6 +702,13 @@ func (p *Plugin) postIssueCommentEvent(event *github.IssueCommentEvent) { | |||
Type: "custom_git_comment", | |||
} | |||
|
|||
repoName := repo.GetFullName() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0/5 collapse into repoName := strings.ToLower(repo.GetFullName())
for readability.
info, appErr := p.getGitHubUserInfo(reaction.UserId) | ||
if appErr != nil { | ||
if appErr.ID != apiErrorIDNotConnected { | ||
p.API.LogError("Error in getting user info", "error", appErr.Message) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 important
if appErr != nil { | ||
if appErr.ID != apiErrorIDNotConnected { | ||
p.API.LogError("Error in getting user info", "error", appErr.Message) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
return
Thanks for the comments, I will take this up separately in a new PR. |
Fixes mattermost#500