Skip to content

Commit

Permalink
Merge pull request #18 from moneyforward/fix/get_all_reacted_users
Browse files Browse the repository at this point in the history
Fix/get all reacted users
  • Loading branch information
sho0126hiro authored Mar 21, 2023
2 parents dd3bc0a + a63ad86 commit 0afc4cb
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 23 deletions.
7 changes: 7 additions & 0 deletions app/internal/domain/repository/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,15 @@ import (
)

type SlackRepository interface {
// PostMessage send a message to a channel
PostMessage(ctx context.Context, channelID, message, ts string) error

// PostEphemeral sends an ephemeral message to user in a channel
PostEphemeral(ctx context.Context, channelID, message, ts, userID string) error

// GetParentMessage gets Slack message that started the thread
GetParentMessage(ctx context.Context, channelID, ts string) (*model.SlackMessage, error)

// ListUsersEmail fetches users email
ListUsersEmail(ctx context.Context, userID []string) ([]*model.SlackUserEmail, error)
}
7 changes: 4 additions & 3 deletions app/internal/domain/service/slack_reaction_users.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,18 +68,19 @@ func (s *slackReactionUsersService) ListUsersEmailByReaction(ctx context.Context
if err != nil {
return nil, err
}
inviteUserIDs := s.getReactionUserIDs(ctx, msg.Reactions, reactionName)
inviteUserEmails, err := s.chunkedListUsersEmail(ctx, inviteUserIDs)
reactedUserIDs := s.getReactionUserIDs(ctx, msg.Reactions, reactionName)
reactedUserEmails, err := s.chunkedListUsersEmail(ctx, reactedUserIDs)
if err != nil {
return nil, err
}
return inviteUserEmails, nil
return reactedUserEmails, nil
}

// getReactionUserIDs get reaction users by reactionName
func (s *slackReactionUsersService) getReactionUserIDs(ctx context.Context, reactions []*model.SlackReaction, reactionName string) []string {
var userIDs []string
var targetReactions []*model.SlackReaction
// filtered reactions by reactionName
for _, reaction := range reactions {
rn := slack.ExtractReactionName(reaction.Name)
if slack.RemoveSkinToneFromReaction(rn) == reactionName {
Expand Down
2 changes: 2 additions & 0 deletions app/internal/domain/service/slack_reaction_users_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ func Test_slackReactionUsersService_ListUsersEmailByReaction(t *testing.T) {
{
Name: "join",
UserIDs: []string{"user01", "user02"},
Count: 2,
},
{
Name: "reactionSample",
UserIDs: []string{"user02", "user03"},
Count: 2,
},
},
}
Expand Down
1 change: 1 addition & 0 deletions app/internal/model/slack_message.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type SlackMessage struct {

type SlackReaction struct {
Name string
Count int
UserIDs []string
}

Expand Down
58 changes: 38 additions & 20 deletions app/internal/repository/slack.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,21 @@ package repository

import (
"context"
"fmt"

"github.com/moneyforward/auriga/app/pkg/slack"
"github.com/slack-go/slack"

pkgslack "github.com/moneyforward/auriga/app/pkg/slack"

"github.com/moneyforward/auriga/app/internal/model"

"github.com/moneyforward/auriga/app/pkg/errors"
)

type slackRepository struct {
client slack.Client
client pkgslack.Client
}

func newSlackRepository(client slack.Client) *slackRepository {
func newSlackRepository(client pkgslack.Client) *slackRepository {
return &slackRepository{
client: client,
}
Expand All @@ -49,35 +50,52 @@ func (r *slackRepository) PostEphemeral(ctx context.Context, channelID, message,
func (r *slackRepository) GetParentMessage(ctx context.Context, channelID, ts string) (*model.SlackMessage, error) {
msgs, err := r.client.GetConversationReplies(ctx, channelID, ts)
if err != nil {
if errors.Is(err, slack.ErrThreadNotFound) {
if errors.Is(err, pkgslack.ErrThreadNotFound) {
return nil, errThreadNotfound
} else {
return nil, err
}
}
if len(msgs) <= 0 {
return nil, errors.New("number of messages is zero")
}
parentMessage := msgs[0]
if r.isIncompleteReaction(parentMessage.Reactions) {
// get full reactions
parentMessage.Reactions, err = r.client.GetReaction(ctx, channelID, ts, true)
if err != nil {
return nil, err
}
}
var reactions []*model.SlackReaction
for _, reaction := range parentMessage.Reactions {
reactions = append(reactions, &model.SlackReaction{
Name: reaction.Name,
UserIDs: reaction.Users,
Count: reaction.Count,
})
}
return &model.SlackMessage{
ChannelID: parentMessage.Channel,
Reactions: reactions,
}, nil
}

if len(msgs) > 0 {
fmt.Printf("%#v \n", msgs[0])
parentMessage := msgs[0]
var reactions []*model.SlackReaction
for _, reaction := range parentMessage.Reactions {
reactions = append(reactions, &model.SlackReaction{
Name: reaction.Name,
UserIDs: reaction.Users,
})
// isIncompleteReaction returns true if more fetches is required
// reactions[*].Count may be greater than len(reactions[*].Users), at which point a fetch is required.
func (r *slackRepository) isIncompleteReaction(reactions []slack.ItemReaction) bool {
for _, reaction := range reactions {
if reaction.Count > len(reaction.Users) {
return true
}
return &model.SlackMessage{
ChannelID: parentMessage.Channel,
Reactions: reactions,
}, nil
}
return nil, errors.New("number of messages is zero")
return false
}

func (r *slackRepository) ListUsersEmail(ctx context.Context, userID []string) ([]*model.SlackUserEmail, error) {
users, err := r.client.GetUsersInfo(ctx, userID...)
if err != nil {
if errors.Is(err, slack.ErrUserNotFound) {
if errors.Is(err, pkgslack.ErrUserNotFound) {
return nil, errUserNotFound
} else {
return nil, err
Expand Down
10 changes: 10 additions & 0 deletions app/pkg/slack/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type Client interface {
PostEphemeral(ctx context.Context, channelID, userID, ts, message string) error
GetConversationReplies(ctx context.Context, channelID, ts string) ([]slack.Message, error)
GetUsersInfo(ctx context.Context, userID ...string) (*[]slack.User, error)
GetReaction(ctx context.Context, channelID, ts string, full bool) ([]slack.ItemReaction, error)

GetClient() *slack.Client
GetAppUserID() string
Expand Down Expand Up @@ -118,6 +119,15 @@ func (c *client) GetUsersInfo(ctx context.Context, userID ...string) (*[]slack.U
return users, nil
}

func (c *client) GetReaction(ctx context.Context, channelID, ts string, full bool) ([]slack.ItemReaction, error) {
return c.Client.GetReactionsContext(ctx, slack.ItemRef{
Channel: channelID,
Timestamp: ts,
}, slack.GetReactionsParameters{
Full: full,
})
}

func (c *client) GetClient() *slack.Client {
return c.Client
}
Expand Down

0 comments on commit 0afc4cb

Please sign in to comment.