Skip to content

Commit

Permalink
Merge pull request #22 from cseeger-epages/issue/16
Browse files Browse the repository at this point in the history
Issue/16
  • Loading branch information
cseeger-epages authored Dec 4, 2019
2 parents 5748d7c + 9d4fae1 commit 34b7fd9
Show file tree
Hide file tree
Showing 6 changed files with 278 additions and 84 deletions.
14 changes: 13 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ Filter emails from mail accounts and send them to mattermost.
- Filter mails by To
- Filter mails by Subject
- Filter mails by TimeRange
- Mattermost Broadcasts
- Mattermost broadcasts
- Choose to post Subject and Body or Subject only
- Send to channels and/or users
- Profile management including default profiles

Missing feature or found a bug ? Feel free to open an [issue](https://github.com/cseeger-epages/mail2most/issues) and let us know !

Expand Down Expand Up @@ -124,6 +126,16 @@ systemctl enable mail2most
systemctl start mail2most
```

## Common problems

**Problem: mail2most crashes after profile changes**

Solution: This happens when the data.json is not consistent to the config changes. Delete data.json to solve this problem.

**Problem: Channel contains special characters mattermost can not found the channel**

Solution: Mattermost does not support special characters for channel names, only in display names. To find the correct channel name use the last part of the url found under `view info`

# Contribution to Mail2Most

Thank you for participating to this project.
Expand Down
95 changes: 83 additions & 12 deletions conf/mail2most.conf
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,70 @@
# Logfile is used if Output is set to "logfile"
Logfile = "mail2most.log"

# The DefaultProfile defines a set of defaults used in Profiles that do not define the specific section
# if you create an empty Profile the DefaultProfile is used
# if a Profile contains the section Mail, Mattermost or Filter this section will overwrite the sections from the Default Profile
# at least an empty Profile has to be created for the DefaultProfile to be processed
# only defining the DefaultProfile without having a [Profile] defined will not work
[DefaultProfile]
# The DefaultProfile.Mail defines a default mailserver
# if your Profile hast no defined mailserver this information will be used
[DefaultProfile.Mail]
ImapServer = "default.mail.example.com:993"
Username = "username"
Password = "password"
# ReadOnly does not change any flags on emails
ReadOnly = true
# ImapTLS allows you to enable / disable tls encryption whithin the imap protocol
ImapTLS = true

# The DefaultProfile.Mattermost defines a default mattermost server
# if your Profile has no defined mattermost server this information will be used
[DefaultProfile.Mattermost]
URL = "https://default.mattermost.example.com"
Team = "defaultTeam"
# you can define username password
Username = "username"
Password = "password"
# or accesstoken
AccessToken = "mytoken"
# Channels contains all channels to post your messages
# if no channel is defined nothing is posted into a channel
Channels = ["#default-channel"]
# Users contains all users to post your message to, you can use the username or email address
# if no users are defined nothing is posted to any user
Users = ["bob","[email protected]"]
# SubjectOnly will post only the mail subject
SubjectOnly = false
# StripHTML will remove all HTML tags bevor sending a msg to mattermost
StripHTML = true
# HideFrom allows you to hide the From Address in mattermost messages
HideFrom= false

# The DefaultProfile.Filter defines a default filter
# if your Profile has no defined filter this information will be used
[DefaultProfile.Filter]
# Folders filters your mails only in specific email folders
Folders = ["some-default-email-folder", "some-other-default-email-folder"]
# Unseen lets you process unseen mails only
Unseen = false
# From filters for defined from addresses
From = ["[email protected]"]
# To filters for defined to addresses
To = ["[email protected]"]
# Subject filters if the email subject contains one of the defined strings
Subject = ["example subject"]
# TimeRange will only process mails that are not older than the defined time range
TimeRange = "24h"

#[[Profile]] defines a profile, you can have as many as you want
[[Profile]]
# IgnoreDefaults lets you ignore the DefaultProfile settings and forces to set everything in the Profile
# this option should only be used if you try to overwrite a default with an empty value
# the better way is to define the value only in the profile and not in the defaults
IgnoreDefaults = false

#[Profile.Mail] contains the mail server configuration
#[Profile.Mail] contains the mail server configuration and overwrites the default
[Profile.Mail]
ImapServer = "mail.example.com:993"
Username = "username"
Expand All @@ -29,22 +89,27 @@
# ImapTLS allows you to enable / disable tls encryption whithin the imap protocol
ImapTLS = true

#[Profile.Mattermost] contains the mattermost configuration
#[Profile.Mattermost] contains the mattermost configuration and overwrites the default
[Profile.Mattermost]
URL = "https://mattermost.example.com"
Team = "exampleTeam"
# you can define username password
Username = "username"
Password = "password"
# or accesstoken
AccessToken = "mytoken"
# Channels contains all channels to post your messages
Channels = ["#some-channel"]
# Users contains all users to post your message to, you can use the username or email address
Users = ["bob","[email protected]"]
# SubjectOnly will post only the mail subject
SubjectOnly = false
# StripHTML will remove all HTML tags bevor sending a msg to mattermost
StripHTML = true
# HideFrom allows you to hide the From Address in mattermost messages
HideFrom= false

#[Profile.Filter] contains all filters that are applied to your mails
#[Profile.Filter] contains all filters that are applied to your mails and overwrites the default
[Profile.Filter]
# Folders filters your mails only in specific email folders
Folders = ["some-email-folder", "some-other-email-folder"]
Expand All @@ -61,6 +126,10 @@

# you can define multiple profiles by adding another [[Profile]]
[[Profile]]
# IgnoreDefaults lets you ignore the DefaultProfile settings and forces to set everything in the Profile
# this option should only be used if you try to overwrite a default with an empty value
# the better way is to define the value only in the profile and not in the defaults
IgnoreDefaults = false

# you can use the same mailserver as in the other profile or even another one
[Profile.Mail]
Expand All @@ -74,21 +143,23 @@
[Profile.Mattermost]
URL = "https://mattermost.example.com"
Team = "anotherTeam"
# you can define username password
Username = "username"
Password = "password"
# or accesstoken
AccessToken = "mytoken"
# you can even post to multiple channels if you want to
Channels = ["#some-other-channel","#some-crazy-channel"]
# Users contains all users to post your message to, you can use the username or email address
Users = ["bob","[email protected]"]
# Broadcast allows you to set @channel, @all, @here etc at the begining fo the message
# Broadcast = ["@channel", "@all"]
Broadcast = []
SubjectOnly = false

# you are free to create another set of filters for your new profile
[Profile.Filter]
Folders = ["some-email-folder", "some-other-email-folder"]
Unseen = false
# or filter multiple from to or subjects
From = ["[email protected]", "[email protected]"]
To = ["[email protected]", "[email protected]"]
Subject = ["example subject", "another subject"]
TimeRange = "24h"
# if you dont add for example [Profile.Filter] the filters defined in the [DefaultProfile.Filter] section are used


# if you create an empty Profile the defaults were used
[[Profile]]
# setting IgnoreDefaults = true in an empty profile will result in an error since nothing is defined then
27 changes: 15 additions & 12 deletions lib/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import (
)

type config struct {
General general
Logging logging
Profiles []profile `toml:"Profile"`
General general
Logging logging
Profiles []profile `toml:"Profile"`
DefaultProfile profile
}
type general struct {
File string
Expand All @@ -24,9 +25,10 @@ type logging struct {
}

type profile struct {
Mail maildata
Mattermost mattermost
Filter filter
IgnoreDefaults bool
Mail maildata
Mattermost mattermost
Filter filter
}

type maildata struct {
Expand All @@ -42,12 +44,13 @@ type filter struct {
}

type mattermost struct {
URL, Team, Username, Password string
Channels []string
Broadcast []string
SubjectOnly bool
StripHTML bool
HideFrom bool
URL, Team, Username, Password, AccessToken string
Channels []string
Users []string
Broadcast []string
SubjectOnly bool
StripHTML bool
HideFrom bool
}

func parseConfig(fileName string, conf *config) error {
Expand Down
25 changes: 25 additions & 0 deletions lib/internals.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"fmt"
"io"
"io/ioutil"
"reflect"
"strings"
"time"

Expand All @@ -27,6 +28,30 @@ func New(confPath string) (Mail2Most, error) {
if err != nil {
return Mail2Most{}, err
}

for k, p := range conf.Profiles {
if !p.IgnoreDefaults {
// create a default profile and overwrite what is defined in the profile
prof := conf.DefaultProfile
voft := reflect.ValueOf(&prof).Elem()
vof := reflect.ValueOf(p)
for i := 0; i < voft.NumField(); i++ {
for j := 0; j < vof.NumField(); j++ {
if vof.Field(j).Type().Kind() == reflect.Struct {
if voft.Type().Field(i).Name == vof.Type().Field(j).Name {
for k := 0; k < vof.Field(j).NumField(); k++ {
if !vof.Field(j).Field(k).IsZero() {
voft.Field(i).FieldByName(vof.Field(j).Type().Field(k).Name).Set(vof.Field(j).Field(k))
}
}
}
}
}
}
conf.Profiles[k] = prof
}
}

m := Mail2Most{Config: conf}
err = m.initLogger()
if err != nil {
Expand Down
17 changes: 14 additions & 3 deletions lib/mail2most.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,19 @@ func (m Mail2Most) Run() error {
// this is nessasary if new profiles are added
// and the caching file does not contain any caching
// for this profile
l := len(alreadySend)
for k, v := range alreadySendFile {
alreadySend[k] = v
if k < l {
alreadySend[k] = v
}
if k >= l {
m.Error("data.json error", map[string]interface{}{
"error": "data.json contains more profile information than defined in the config",
"cause": "this happens if profiles are deleted from the config file and can create inconsistencies",
"solution": "delete the data.json file",
"note": "by deleting the data.json file all mails are parsed and send again",
})
}
}

// set a 10 seconds sleep default if no TimeInterval is defined
Expand Down Expand Up @@ -74,8 +85,9 @@ func (m Mail2Most) Run() error {
m.Error("Mattermost Error", map[string]interface{}{
"Error": err,
})
} else {
alreadySend[p] = append(alreadySend[p], mail.ID)
}
alreadySend[p] = append(alreadySend[p], mail.ID)
err = writeToFile(alreadySend, m.Config.General.File)

if err != nil {
Expand All @@ -91,5 +103,4 @@ func (m Mail2Most) Run() error {
})
time.Sleep(time.Duration(m.Config.General.TimeInterval) * time.Second)
}

}
Loading

0 comments on commit 34b7fd9

Please sign in to comment.