Skip to content

Commit

Permalink
[GH-512,513] Fixed issue #512 and #513 on github plugin 'Updated subs…
Browse files Browse the repository at this point in the history
…cription success messages' (#661)

* [MI-2904]:Fixed issue #512 and #513 on github plugin (#25)

* [MI-2904]:Fixed issue #512 and #513 on github plugin

* [MI-2904]:Fixed review comments

* [MI-2904]:Fixed review comments

* [MI-2928]:Fixed review comments for issue 512 and 513 on github plugin (#26)

* [MM-512,513]:Fixed review comments given by mm team

* [MM-512,513]:Updated user error msg

* [MM-512,513]:Fixed lint errors

* [MM-512,513]: reverted package-lock.json changes

* Fixed lint.

---------

Co-authored-by: Abhishek Verma <[email protected]>
  • Loading branch information
Kshitij-Katiyar and avas27JTG authored Nov 28, 2023
1 parent 573e4a3 commit 8cf783f
Show file tree
Hide file tree
Showing 2 changed files with 148 additions and 45 deletions.
151 changes: 132 additions & 19 deletions server/plugin/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ var validFeatures = map[string]bool{
featureStars: true,
}

type Features string

func (features Features) String() string {
return string(features)
}

func (features Features) FormattedString() string {
return "`" + strings.Join(strings.Split(features.String(), ","), "`, `") + "`"
}

func (features Features) ToSlice() []string {
return strings.Split(string(features), ",")
}

// validateFeatures returns false when 1 or more given features
// are invalid along with a list of the invalid features.
func validateFeatures(features []string) (bool, []string) {
Expand Down Expand Up @@ -269,7 +283,7 @@ func (p *Plugin) handleSubscriptionsList(_ *plugin.Context, args *model.CommandA
}
for _, sub := range subs {
subFlags := sub.Flags.String()
txt += fmt.Sprintf("* `%s` - %s", strings.Trim(sub.Repository, "/"), sub.Features)
txt += fmt.Sprintf("* `%s` - %s", strings.Trim(sub.Repository, "/"), sub.Features.String())
if subFlags != "" {
txt += fmt.Sprintf(" %s", subFlags)
}
Expand All @@ -279,6 +293,21 @@ func (p *Plugin) handleSubscriptionsList(_ *plugin.Context, args *model.CommandA
return txt
}

func (p *Plugin) createPost(channelID, userID, message string) error {
post := &model.Post{
ChannelId: channelID,
UserId: userID,
Message: message,
}

if _, appErr := p.API.CreatePost(post); appErr != nil {
p.API.LogWarn("Error while creating post", "Post", post, "Error", appErr.Error())
return appErr
}

return nil
}

func (p *Plugin) checkIfConfiguredWebhookExists(ctx context.Context, githubClient *github.Client, repo, owner string) (bool, error) {
found := false
opt := &github.ListOptions{
Expand Down Expand Up @@ -321,15 +350,14 @@ func (p *Plugin) checkIfConfiguredWebhookExists(ctx context.Context, githubClien
func (p *Plugin) handleSubscribesAdd(_ *plugin.Context, args *model.CommandArgs, parameters []string, userInfo *GitHubUserInfo) string {
const errorNoWebhookFound = "\nNo webhook was found for this repository or organization. To create one, enter the following slash command `/github setup webhook`"
const errorWebhookToUser = "\nNot able to get the list of webhooks. This feature is not available for subscription to a user."
subscriptionEvents := Features("pulls,issues,creates,deletes")
if len(parameters) == 0 {
return "Please specify a repository."
}

config := p.getConfiguration()
baseURL := config.getBaseURL()

features := "pulls,issues,creates,deletes"
flags := SubscriptionFlags{}

if len(parameters) > 1 {
flagParams := parameters[1:]

Expand All @@ -346,15 +374,15 @@ func (p *Plugin) handleSubscribesAdd(_ *plugin.Context, args *model.CommandArgs,
parsedFlag := parseFlag(flag)

if parsedFlag == flagFeatures {
features = value
subscriptionEvents = Features(value)
continue
}
if err := flags.AddFlag(parsedFlag, value); err != nil {
return fmt.Sprintf("Unsupported value for flag %s", flag)
}
}

fs := strings.Split(features, ",")
fs := subscriptionEvents.ToSlice()
if SliceContainsString(fs, featureIssues) && SliceContainsString(fs, featureIssueCreation) {
return "Feature list cannot contain both issue and issue_creations"
}
Expand All @@ -373,21 +401,45 @@ func (p *Plugin) handleSubscribesAdd(_ *plugin.Context, args *model.CommandArgs,

ctx := context.Background()
githubClient := p.githubConnectUser(ctx, userInfo)
user, appErr := p.API.GetUser(args.UserId)
if appErr != nil {
return errors.Wrap(appErr, "failed to get the user").Error()
}

owner, repo := parseOwnerAndRepo(parameters[0], baseURL)
previousSubscribedEvents, err := p.getSubscribedFeatures(args.ChannelId, owner, repo)
if err != nil {
return errors.Wrap(err, "failed to get the subscribed events").Error()
}

var previousSubscribedEventMessage string
if previousSubscribedEvents != "" {
previousSubscribedEventMessage = fmt.Sprintf("\nThe previous subscription with: %s was overwritten.\n", previousSubscribedEvents.FormattedString())
}

owner, repo := parseOwnerAndRepo(parameters[0], config.getBaseURL())
if repo == "" {
if err := p.SubscribeOrg(ctx, githubClient, args.UserId, owner, args.ChannelId, features, flags); err != nil {
return err.Error()
if err = p.SubscribeOrg(ctx, githubClient, args.UserId, owner, args.ChannelId, subscriptionEvents, flags); err != nil {
return errors.Wrap(err, "failed to get the subscribed org").Error()
}
orgLink := baseURL + owner
subscriptionSuccess := fmt.Sprintf("@%v subscribed this channel to [%s](%s) with the following events: %s.", user.Username, owner, orgLink, subscriptionEvents.FormattedString())

if previousSubscribedEvents != "" {
subscriptionSuccess += previousSubscribedEventMessage
}

if err = p.createPost(args.ChannelId, p.BotUserID, subscriptionSuccess); err != nil {
return fmt.Sprintf("%s error creating the public post: %s", subscriptionSuccess, err.Error())
}

subOrgMsg := fmt.Sprintf("Successfully subscribed to organization %s.", owner)

found, err := p.checkIfConfiguredWebhookExists(ctx, githubClient, repo, owner)
if err != nil {
if strings.Contains(err.Error(), "404 Not Found") {
found, foundErr := p.checkIfConfiguredWebhookExists(ctx, githubClient, repo, owner)
if foundErr != nil {
if strings.Contains(foundErr.Error(), "404 Not Found") {
return errorWebhookToUser
}
return errors.Wrap(err, "failed to get the list of webhooks").Error()
return errors.Wrap(foundErr, "failed to get the list of webhooks").Error()
}

if !found {
Expand All @@ -400,12 +452,15 @@ func (p *Plugin) handleSubscribesAdd(_ *plugin.Context, args *model.CommandArgs,
return "Exclude repository feature is only available to subscriptions of an organization."
}

if err := p.Subscribe(ctx, githubClient, args.UserId, owner, repo, args.ChannelId, features, flags); err != nil {
return err.Error()
if err = p.Subscribe(ctx, githubClient, args.UserId, owner, repo, args.ChannelId, subscriptionEvents, flags); err != nil {
return errors.Wrap(err, "failed to create a subscription").Error()
}
repoLink := config.getBaseURL() + owner + "/" + repo

msg := fmt.Sprintf("Successfully subscribed to [%s](%s).", repo, repoLink)
msg := fmt.Sprintf("@%v subscribed this channel to [%s/%s](%s) with the following events: %s", user.Username, owner, repo, repoLink, subscriptionEvents.FormattedString())
if previousSubscribedEvents != "" {
msg += previousSubscribedEventMessage
}

ghRepo, _, err := githubClient.Repositories.Get(ctx, owner, repo)
if err != nil {
Expand All @@ -414,6 +469,10 @@ func (p *Plugin) handleSubscribesAdd(_ *plugin.Context, args *model.CommandArgs,
msg += "\n\n**Warning:** You subscribed to a private repository. Anyone with access to this channel will be able to read the events getting posted here."
}

if err = p.createPost(args.ChannelId, p.BotUserID, msg); err != nil {
return fmt.Sprintf("%s\nError creating the public post: %s", msg, appErr.Error())
}

found, err := p.checkIfConfiguredWebhookExists(ctx, githubClient, repo, owner)
if err != nil {
if strings.Contains(err.Error(), "404 Not Found") {
Expand All @@ -429,19 +488,73 @@ func (p *Plugin) handleSubscribesAdd(_ *plugin.Context, args *model.CommandArgs,
return msg
}

func (p *Plugin) getSubscribedFeatures(channelID, owner, repo string) (Features, error) {
var previousFeatures Features
subs, err := p.GetSubscriptionsByChannel(channelID)
if err != nil {
return previousFeatures, err
}

for _, sub := range subs {
fullRepoName := repo
if owner != "" {
fullRepoName = owner + "/" + repo
}

if sub.Repository == fullRepoName {
previousFeatures = sub.Features
return previousFeatures, nil
}
}

return previousFeatures, nil
}
func (p *Plugin) handleUnsubscribe(_ *plugin.Context, args *model.CommandArgs, parameters []string, _ *GitHubUserInfo) string {
if len(parameters) == 0 {
return "Please specify a repository."
}

repo := parameters[0]
config := p.getConfiguration()
owner, repo := parseOwnerAndRepo(repo, config.getBaseURL())
if owner == "" && repo == "" {
return "invalid repository"
}

if err := p.Unsubscribe(args.ChannelId, repo); err != nil {
p.client.Log.Warn("Failed to unsubscribe", "repo", repo, "error", err.Error())
owner = strings.ToLower(owner)
repo = strings.ToLower(repo)
if err := p.Unsubscribe(args.ChannelId, repo, owner); err != nil {
p.API.LogWarn("Failed to unsubscribe", "repo", repo, "error", err.Error())
return "Encountered an error trying to unsubscribe. Please try again."
}

return fmt.Sprintf("Successfully unsubscribed from %s.", repo)
baseURL := config.getBaseURL()
user, appErr := p.API.GetUser(args.UserId)
if appErr != nil {
p.API.LogWarn("Error while fetching user details", "Error", appErr.Error())
return fmt.Sprintf("error while fetching user details: %s", appErr.Error())
}

unsubscribeMessage := ""
if repo == "" {
orgLink := baseURL + owner
unsubscribeMessage = fmt.Sprintf("@%v unsubscribed this channel from [%s](%s)", user.Username, owner, orgLink)

if err := p.createPost(args.ChannelId, p.BotUserID, unsubscribeMessage); err != nil {
return fmt.Sprintf("%s error creating the public post: %s", unsubscribeMessage, err.Error())
}

return ""
}

repoLink := baseURL + owner + "/" + repo
unsubscribeMessage = fmt.Sprintf("@%v unsubscribed this channel from [%s/%s](%s)", user.Username, owner, repo, repoLink)

if err := p.createPost(args.ChannelId, p.BotUserID, unsubscribeMessage); err != nil {
return fmt.Sprintf("%s error creating the public post: %s", unsubscribeMessage, err.Error())
}

return ""
}

func (p *Plugin) handleDisconnect(_ *plugin.Context, args *model.CommandArgs, _ []string, _ *GitHubUserInfo) string {
Expand Down
42 changes: 16 additions & 26 deletions server/plugin/subscriptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ func (s SubscriptionFlags) String() string {
type Subscription struct {
ChannelID string
CreatorID string
Features string
Features Features
Flags SubscriptionFlags
Repository string
}
Expand All @@ -80,51 +80,51 @@ type Subscriptions struct {
}

func (s *Subscription) Pulls() bool {
return strings.Contains(s.Features, featurePulls)
return strings.Contains(s.Features.String(), featurePulls)
}

func (s *Subscription) PullsMerged() bool {
return strings.Contains(s.Features, "pulls_merged")
return strings.Contains(s.Features.String(), "pulls_merged")
}

func (s *Subscription) IssueCreations() bool {
return strings.Contains(s.Features, "issue_creations")
return strings.Contains(s.Features.String(), "issue_creations")
}

func (s *Subscription) Issues() bool {
return strings.Contains(s.Features, featureIssues)
return strings.Contains(s.Features.String(), featureIssues)
}

func (s *Subscription) Pushes() bool {
return strings.Contains(s.Features, "pushes")
return strings.Contains(s.Features.String(), "pushes")
}

func (s *Subscription) Creates() bool {
return strings.Contains(s.Features, "creates")
return strings.Contains(s.Features.String(), "creates")
}

func (s *Subscription) Deletes() bool {
return strings.Contains(s.Features, "deletes")
return strings.Contains(s.Features.String(), "deletes")
}

func (s *Subscription) IssueComments() bool {
return strings.Contains(s.Features, "issue_comments")
return strings.Contains(s.Features.String(), "issue_comments")
}

func (s *Subscription) PullReviews() bool {
return strings.Contains(s.Features, "pull_reviews")
return strings.Contains(s.Features.String(), "pull_reviews")
}

func (s *Subscription) Stars() bool {
return strings.Contains(s.Features, featureStars)
return strings.Contains(s.Features.String(), featureStars)
}

func (s *Subscription) Label() string {
if !strings.Contains(s.Features, "label:") {
if !strings.Contains(s.Features.String(), "label:") {
return ""
}

labelSplit := strings.Split(s.Features, "\"")
labelSplit := strings.Split(s.Features.String(), "\"")
if len(labelSplit) < 3 {
return ""
}
Expand All @@ -149,7 +149,7 @@ func (s *Subscription) excludedRepoForSub(repo *github.Repository) bool {
return false
}

func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, userID, owner, repo, channelID, features string, flags SubscriptionFlags) error {
func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, userID, owner, repo, channelID string, features Features, flags SubscriptionFlags) error {
if owner == "" {
return errors.Errorf("invalid repository")
}
Expand Down Expand Up @@ -206,7 +206,7 @@ func (p *Plugin) Subscribe(ctx context.Context, githubClient *github.Client, use
return nil
}

func (p *Plugin) SubscribeOrg(ctx context.Context, githubClient *github.Client, userID, org, channelID, features string, flags SubscriptionFlags) error {
func (p *Plugin) SubscribeOrg(ctx context.Context, githubClient *github.Client, userID, org, channelID string, features Features, flags SubscriptionFlags) error {
if org == "" {
return errors.New("invalid organization")
}
Expand Down Expand Up @@ -338,17 +338,7 @@ func (p *Plugin) GetSubscribedChannelsForRepository(repo *github.Repository) []*
return subsToReturn
}

func (p *Plugin) Unsubscribe(channelID string, repo string) error {
config := p.getConfiguration()

owner, repo := parseOwnerAndRepo(repo, config.getBaseURL())
if owner == "" && repo == "" {
return errors.New("invalid repository")
}

owner = strings.ToLower(owner)
repo = strings.ToLower(repo)

func (p *Plugin) Unsubscribe(channelID, repo, owner string) error {
repoWithOwner := fmt.Sprintf("%s/%s", owner, repo)

subs, err := p.GetSubscriptions()
Expand Down

0 comments on commit 8cf783f

Please sign in to comment.