Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Download [Latest Release Version](https://github.com/virtomize/mail2most/release
## build it yourself

You can compile the project yourself using this repo and [mage](https://magefile.org).
Just clone the repo and run `mage build`, you can find the binary under `bin/mail2most`
Just clone the repo and run `mage service:build`, you can find the binary under `bin/mail2most`

# Usage

Expand Down
2 changes: 1 addition & 1 deletion lib/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ type filter struct {
}

type mattermost struct {
URL, Team, Username, Password, AccessToken string
URL, Team, Username, Password, AccessToken, UserId string
Channels []string
Users []string
Broadcast []string
Expand Down
16 changes: 9 additions & 7 deletions lib/mail2most.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,17 +82,19 @@ func (m Mail2Most) Run() error {
if send {
err := m.PostMattermost(p, mail)
if err != nil {
m.Error("Mattermost Error", map[string]interface{}{
m.Error("Right after PostMattermost, Mattermost Error. Email not set as synced in mattermost.", map[string]interface{}{
Copy link
Contributor

Choose a reason for hiding this comment

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

should be more like

m.Error("Mattermost Error", map[string]interface{}{
"call": "PostMattermost",
"error": err
})

I think the "Email not set as synced" part can be removed this its now the correct default behavior.

Copy link
Contributor

Choose a reason for hiding this comment

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

Just for reference: putting additional information into the additional information part (map[string]interface) allows the logger to seperate this information and depending on the logging type (text/json) to seperate the fields so they can be read and parsed by a logging backend correctly

Copy link
Contributor

Choose a reason for hiding this comment

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

can you fix it pls

"Error": err,
})
} else {
alreadySend[p] = append(alreadySend[p], mail.ID)
}
err = writeToFile(alreadySend, m.Config.General.File)
if err != nil {
m.Error("File Error", map[string]interface{}{
"Error": err,
})
m.Debug("In mail2most Run, Before writeToFile on " + m.Config.General.File,nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

put the additional logging information into map[string]interface{}

m.Debug("writing to file", map[string]interface{
"filename": m.Config.General.File,
}

Copy link
Contributor

Choose a reason for hiding this comment

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

same here

err = writeToFile(alreadySend, m.Config.General.File)

if err != nil {
m.Error("File Error", map[string]interface{}{
"Error": err,
})
}
}
}
}
Expand Down
36 changes: 16 additions & 20 deletions lib/mattermost.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ import (

func (m Mail2Most) mlogin(profile int) (*model.Client4, error) {
c := model.NewAPIv4Client(m.Config.Profiles[profile].Mattermost.URL)

m.Info("in mlogin", nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

m.Debug("login", map[string]interface{
"profile": profile,
})

no need to have this on Info logging

Copy link
Contributor

Choose a reason for hiding this comment

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

same here

if m.Config.Profiles[profile].Mattermost.Username != "" && m.Config.Profiles[profile].Mattermost.Password != "" {
_, resp := c.Login(m.Config.Profiles[profile].Mattermost.Username, m.Config.Profiles[profile].Mattermost.Password)
me, resp := c.Login(m.Config.Profiles[profile].Mattermost.Username, m.Config.Profiles[profile].Mattermost.Password)
if resp.Error != nil {
return nil, resp.Error
}
m.Config.Profiles[profile].Mattermost.UserId = me.Id

} else if m.Config.Profiles[profile].Mattermost.AccessToken != "" {
c.AuthToken = m.Config.Profiles[profile].Mattermost.AccessToken
c.AuthType = "BEARER"
Expand All @@ -28,7 +30,9 @@ func (m Mail2Most) mlogin(profile int) (*model.Client4, error) {
return nil, err
}
u := model.UserFromJson(r.Body)

m.Config.Profiles[profile].Mattermost.Username = u.Email
m.Config.Profiles[profile].Mattermost.UserId = u.Id
} else {
return nil, fmt.Errorf("no username, password or token is set")
}
Expand Down Expand Up @@ -59,6 +63,7 @@ func (m Mail2Most) PostMattermost(profile int, mail Mail) error {
if err != nil {
return err
}

defer c.Logout()

// check if body is base64 encoded
Expand Down Expand Up @@ -112,13 +117,13 @@ func (m Mail2Most) PostMattermost(profile int, mail Mail) error {
email := fmt.Sprintf("%s@%s", mail.From[0].MailboxName, mail.From[0].HostName)
user, resp := c.GetUserByEmail(email, "")
if resp.Error != nil {
m.Debug("user not found in system", map[string]interface{}{"error": resp.Error})
m.Debug("user not found in system for email " + email, map[string]interface{}{"error": resp.Error})
Copy link
Contributor

@c-seeger c-seeger Mar 25, 2025

Choose a reason for hiding this comment

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

m.Debug("user not found", map[string]interface{}{
  "error": resp.Error, 
  "email": email,
  "call": "GetUserByEmail",
  })

Copy link
Author

Choose a reason for hiding this comment

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

should be more precise I think
email sender not defined as mattermost user

Copy link
Contributor

Choose a reason for hiding this comment

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

how about

m.Debug("user not found", map[string]interface{}{
  "error": resp.Error, 
  "email": email,
  "call": "GetUserByEmail",
  "note": "email sender not defined as mattermost user",
  })

msg += m.getFromLine(profile, mail.From[0].PersonalName, email)
} else {
msg += m.getFromLine(profile, "@"+user.Username, email)
}
}

//m.Debug("Before SubjectOnly/BodyOnly " + err.Error,nil)
Copy link
Contributor

Choose a reason for hiding this comment

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

can be removed i guess?

if m.Config.Profiles[profile].Mattermost.SubjectOnly && m.Config.Profiles[profile].Mattermost.BodyOnly {
err := fmt.Errorf("config defines SubjectOnly and BodyOnly to be true which exclude each other")
m.Error("Configuration inconsistency found", map[string]interface{}{"Config.Profile.Mattermost.SubjectOnly": true, "Config.Profile.Mattermost.BodyOnly": true, "error": err})
Expand Down Expand Up @@ -190,33 +195,24 @@ func (m Mail2Most) PostMattermost(profile int, mail Mail) error {
return err
}
}

m.Debug("In PostMattermost, Before m.Config.Profiles[profile].Mattermost.Users treatment",nil)
Copy link
Contributor

@c-seeger c-seeger Mar 25, 2025

Choose a reason for hiding this comment

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

same as the others, adding additional information as seperate

if len(m.Config.Profiles[profile].Mattermost.Users) > 0 {

var (
me *model.User
resp *model.Response
)

// who am i
// user is defined by its email address
if strings.Contains(m.Config.Profiles[profile].Mattermost.Username, "@") {
me, resp = c.GetUserByEmail(m.Config.Profiles[profile].Mattermost.Username, "")
if resp.Error != nil {
return resp.Error
}
} else {
me, resp = c.GetUserByEmail(m.Config.Profiles[profile].Mattermost.Username, "")
if resp.Error != nil {
return resp.Error
}
}
myid := me.Id
myid := m.Config.Profiles[profile].Mattermost.UserId

for _, user := range m.Config.Profiles[profile].Mattermost.Users {
var (
u *model.User
)
m.Debug("In PostMattermost, In m.Config.Profiles[profile].Mattermost.Users treatment ", map[string]interface{}{"length of user name": len(user)})
Copy link
Contributor

Choose a reason for hiding this comment

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

not sure if this is debug line is really needed since it's now catched with a proper error instead

Copy link
Contributor

Choose a reason for hiding this comment

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

map[string]interface{}{"length of user name": len(user)} since it is used to allow the logger to create parsable key value pairs the key should follow usual naming standards e.g: username_length. Also what benefit is created by this debug line providing user length as information for debugging?


if len(user) == 0 {
return errors.New("User to send message to in Mattermost seems to be empty")
}
// user is defined by its email address
if strings.Contains(user, "@") {
u, resp = c.GetUserByEmail(user, "")
Expand Down