From 478989c3f1f18c0a204702cbec3c5648b99233fc Mon Sep 17 00:00:00 2001 From: James Conroy Date: Wed, 30 Oct 2024 14:04:22 -0500 Subject: [PATCH] fix: MM remote improvements (#519) --- remote/mattermost/remote.go | 139 ++++++++++++++++++++++++++++++++---- 1 file changed, 127 insertions(+), 12 deletions(-) diff --git a/remote/mattermost/remote.go b/remote/mattermost/remote.go index d008e369..02ff7408 100644 --- a/remote/mattermost/remote.go +++ b/remote/mattermost/remote.go @@ -5,7 +5,9 @@ package mattermost import ( "context" "encoding/json" + "fmt" "strconv" + "strings" "github.com/mattermost/mattermost/server/public/model" "github.com/rs/zerolog/log" @@ -27,8 +29,6 @@ var _ remote.Remote = (*Client)(nil) // instantiate a new mattermost client. func (c *Client) new() *model.Client4 { - log.Info().Msgf("%#v", c) - url := "https://" + c.Server if c.Insecure { url = "http://" + c.Server @@ -53,7 +53,7 @@ func (c *Client) Reaction(_ models.Message, rule models.Rule, _ *models.Bot) { } } -func (c *Client) Read(inputMsgs chan<- models.Message, _ map[string]models.Rule, _ *models.Bot) { +func (c *Client) Read(inputMsgs chan<- models.Message, _ map[string]models.Rule, bot *models.Bot) { api := c.new() ctx := context.Background() @@ -68,6 +68,29 @@ func (c *Client) Read(inputMsgs chan<- models.Message, _ map[string]models.Rule, c.BotID = user.Username + go func(b *models.Bot) { + rooms := make(map[string]string) + + teams, _, err := api.GetTeamsForUser(ctx, user.Id, "") + if err != nil { + log.Fatal().Err(err) + } + + for _, team := range teams { + r, _, err := api.GetChannelsForTeamForUser(ctx, team.Id, user.Id, false, "") + if err != nil { + log.Fatal().Err(err) + } + + for _, i := range r { + teamRoom := fmt.Sprintf("%s/%s", team.Name, i.Name) + rooms[teamRoom] = i.Id + } + } + + b.Rooms = rooms + }(bot) + url := "wss://" + c.Server if c.Insecure { url = "ws://" + c.Server @@ -167,20 +190,112 @@ func (c *Client) Send(message models.Message, _ *models.Bot) { api := c.new() ctx := context.Background() - if user, resp, err := api.GetUser(ctx, "me", ""); err != nil { + user, _, err := api.GetUser(ctx, "me", "") + if err != nil { log.Fatal().Msgf("could not login, %s", err) - } else { - log.Info().Interface("user", user.Username).Interface("resp", resp).Msg("") - log.Info().Msg("logged in to mattermost") - - c.BotID = user.Username } + log.Info().Msg("logged in to mattermost") + + c.BotID = user.Id post := &model.Post{} - post.ChannelId = message.ChannelID post.Message = message.Output - if _, _, err := api.CreatePost(ctx, post); err != nil { - log.Error().Err(err).Msg("failed to create post") + if message.DirectMessageOnly { + post.UserId = message.Vars["_user.id"] + err = c.sendDirectMessage(ctx, api, post) + + if err != nil { + log.Error().Msgf("%v", err) + return + } + + return + } + + if len(message.OutputToRooms) > 0 { + for _, roomID := range message.OutputToRooms { + post.ChannelId = roomID + + err = sendMessage(ctx, api, post) + if err != nil { + log.Error().Err(err).Msgf("unable to post message to %v", roomID) + } + } + } + + if len(message.OutputToUsers) > 0 { + for _, u := range message.OutputToUsers { + post.UserId, err = getUserID(api, u) + if err != nil { + log.Error().Err(err) + } + + if err = c.sendDirectMessage(ctx, api, post); err != nil { + log.Error().Err(err) + } + } + } + + if len(message.OutputToRooms) == 0 && len(message.OutputToUsers) == 0 { + post := &model.Post{} + post.ChannelId = message.ChannelID + post.Message = message.Output + + if _, _, err := api.CreatePost(ctx, post); err != nil { + log.Error().Err(err).Msg("failed to create post") + } } } + +func getUserID(api *model.Client4, username string) (string, error) { + log.Debug().Msgf("getting user id for %s", username) + + ctx := context.Background() + + // trim any leading '@' from the provided username + username = strings.TrimPrefix(username, "@") + + user, _, err := api.GetUserByUsername(ctx, username, "") + if err != nil { + log.Error().Err(err).Msg("error retreving user id") + return "", err + } + + log.Debug().Msgf("%s user id is %s", username, user.Id) + + return user.Id, nil +} + +func (c Client) sendDirectMessage(ctx context.Context, api *model.Client4, post *model.Post) error { + if post.UserId == "" { + err := fmt.Errorf("no user id in the post, unable to create a direct message") + log.Error().Err(err).Msg("unable to create direct message channel") + + return err + } + + log.Debug().Msgf("creating direct message between %s, and %s", post.UserId, c.BotID) + + directChannel, resp, err := api.CreateDirectChannel(ctx, post.UserId, c.BotID) + if err != nil { + log.Error().Interface("resp", resp).Err(err).Msg("unable to create direct message channel") + return err + } + + post.ChannelId = directChannel.Id + + return sendMessage(ctx, api, post) +} + +func sendMessage(ctx context.Context, api *model.Client4, post *model.Post) error { + _, resp, err := api.CreatePost(ctx, post) + if err != nil { + log.Error().Err(err).Msg("unable to post message") + return err + } + + log.Debug().Interface("response", resp).Msg("") + + return nil +}