parse multipart emails
This commit is contained in:
parent
fcf82bc359
commit
1a809a1184
1 changed files with 56 additions and 13 deletions
69
main.go
69
main.go
|
@ -1,11 +1,15 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"log/slog"
|
||||
"mime"
|
||||
"mime/multipart"
|
||||
"net/mail"
|
||||
"net/url"
|
||||
"os"
|
||||
|
@ -27,22 +31,55 @@ type ReceivedEmail struct {
|
|||
body string
|
||||
}
|
||||
|
||||
func (re *ReceivedEmail) String() string {
|
||||
return fmt.Sprintf(`FROM: %s
|
||||
TO: %s,
|
||||
BODY: %s`, re.Msg.Header.Get("From"), re.Recipients, re.Body())
|
||||
}
|
||||
|
||||
func (re *ReceivedEmail) Body() string {
|
||||
func (re *ReceivedEmail) Body() (string, error) {
|
||||
if re.body == "" {
|
||||
body, err := io.ReadAll(re.Msg.Body)
|
||||
if err != nil {
|
||||
slog.Error("failed to read email body", slog.String("err", err.Error()))
|
||||
// Get the Content-Type header
|
||||
contentType := re.Msg.Header.Get("Content-Type")
|
||||
|
||||
if contentType == "" {
|
||||
body, err := io.ReadAll(re.Msg.Body)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to read email body: %w", err)
|
||||
}
|
||||
re.body = string(body)
|
||||
} else {
|
||||
mediaType, params, err := mime.ParseMediaType(contentType)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to parse Content-Type: %v", err)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(mediaType, "multipart/alternative") {
|
||||
// Parse the multipart message
|
||||
mr := multipart.NewReader(re.Msg.Body, params["boundary"])
|
||||
for {
|
||||
part, err := mr.NextPart()
|
||||
if err != nil {
|
||||
break // End of parts
|
||||
}
|
||||
defer part.Close()
|
||||
|
||||
// Print part headers
|
||||
fmt.Printf("Part Content-Type: %s\n", part.Header.Get("Content-Type"))
|
||||
|
||||
// Set body if this is the text/plain part
|
||||
if strings.HasPrefix(part.Header.Get("Content-Type"), "text/plain") {
|
||||
// Read the part's body
|
||||
body := new(bytes.Buffer)
|
||||
_, err = body.ReadFrom(part)
|
||||
if err != nil {
|
||||
slog.Error("Failed to read part body", slog.String("err", err.Error()))
|
||||
return "", fmt.Errorf("failed to read part body: %w", err)
|
||||
}
|
||||
|
||||
re.body = body.String()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
re.body = string(body)
|
||||
}
|
||||
|
||||
return re.body
|
||||
return re.body, nil
|
||||
}
|
||||
|
||||
type Config struct {
|
||||
|
@ -138,7 +175,13 @@ func (bkd *Backend) forwardEmail(email ReceivedEmail) error {
|
|||
destinationURL := r.GetTargetURL()
|
||||
destinationURL.RawQuery = urlParams.Encode()
|
||||
|
||||
if err := shoutrrr.Send(destinationURL.String(), email.Body()); err != nil {
|
||||
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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue