refactor: Reorganize SMTP2Shoutrrr code into separate files
This commit is contained in:
parent
9625807106
commit
31f2102031
4 changed files with 232 additions and 222 deletions
116
backend.go
Normal file
116
backend.go
Normal file
|
@ -0,0 +1,116 @@
|
|||
package smtp2shoutrrr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/mail"
|
||||
"net/url"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/containrrr/shoutrrr"
|
||||
"github.com/emersion/go-sasl"
|
||||
"github.com/emersion/go-smtp"
|
||||
)
|
||||
|
||||
type Backend struct {
|
||||
config *Config
|
||||
}
|
||||
|
||||
func (bkd *Backend) NewSession(c *smtp.Conn) (smtp.Session, error) {
|
||||
return &Session{
|
||||
forwarderFunc: bkd.forwardEmail,
|
||||
config: bkd.config,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (bkd *Backend) forwardEmail(email ReceivedEmail) error {
|
||||
slog.Info("forwading message", slog.String("to", strings.Join(email.Recipients, ",")))
|
||||
|
||||
for _, r := range bkd.config.Recipients {
|
||||
for _, a := range email.Recipients {
|
||||
if slices.Contains(r.Addresses, a) {
|
||||
urlParams := url.Values{
|
||||
"title": {email.Msg.Header.Get("Subject")},
|
||||
}
|
||||
|
||||
destinationURL := r.GetTargetURL()
|
||||
destinationURL.RawQuery = urlParams.Encode()
|
||||
|
||||
body, err := email.Body()
|
||||
if err != nil {
|
||||
slog.Error("Error getting email body", slog.String("err", err.Error()))
|
||||
continue
|
||||
}
|
||||
|
||||
if err := shoutrrr.Send(destinationURL.String(), body); err != nil {
|
||||
slog.Error("Error sending message", slog.String("err", err.Error()))
|
||||
continue
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
addresses []string
|
||||
body string
|
||||
|
||||
config *Config
|
||||
|
||||
forwarderFunc func(ReceivedEmail) error
|
||||
}
|
||||
|
||||
func (s *Session) AuthMechanisms() []string {
|
||||
return []string{sasl.Plain}
|
||||
}
|
||||
|
||||
func (s *Session) Auth(mech string) (sasl.Server, error) {
|
||||
return sasl.NewPlainServer(func(identity, username, password string) error {
|
||||
if username != s.config.Username && password != s.config.Password {
|
||||
return fmt.Errorf("invalid credentials")
|
||||
}
|
||||
return nil
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (s *Session) Mail(from string, opts *smtp.MailOptions) error {
|
||||
slog.Debug("Mail from", slog.String("from", from))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Session) Rcpt(to string, opts *smtp.RcptOptions) error {
|
||||
slog.Debug("Rcpt to", slog.String("to", to))
|
||||
s.addresses = append(s.addresses, to)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Session) Data(r io.Reader) error {
|
||||
msg, err := mail.ReadMessage(r)
|
||||
if err != nil {
|
||||
slog.Error("Error reading data", slog.String("err", err.Error()))
|
||||
return fmt.Errorf("Error reading data: %w", err)
|
||||
}
|
||||
|
||||
slog.Info("Received email", slog.String("destination", strings.Join(s.addresses, ",")))
|
||||
|
||||
if err := s.forwarderFunc(ReceivedEmail{
|
||||
Recipients: s.addresses,
|
||||
Msg: msg,
|
||||
}); err != nil {
|
||||
slog.Error("Error forwarding email", slog.String("err", err.Error()))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Session) Reset() {}
|
||||
|
||||
func (s *Session) Logout() error {
|
||||
return nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue