94 lines
1.8 KiB
Go
94 lines
1.8 KiB
Go
package imap
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"io"
|
|
"mime"
|
|
"mime/multipart"
|
|
"net/mail"
|
|
"strings"
|
|
|
|
imapTypes "github.com/emersion/go-imap/v2"
|
|
)
|
|
|
|
type EmailAddress struct {
|
|
Name string `json:"name"`
|
|
Address string `json:"address"`
|
|
}
|
|
|
|
func addressesToJSON(addrs []imapTypes.Address) []byte {
|
|
result := make([]EmailAddress, 0, len(addrs))
|
|
for _, a := range addrs {
|
|
result = append(result, EmailAddress{
|
|
Name: a.Name,
|
|
Address: a.Addr(),
|
|
})
|
|
}
|
|
b, _ := json.Marshal(result)
|
|
return b
|
|
}
|
|
|
|
func parseBody(raw []byte) (text string, html string) {
|
|
if len(raw) == 0 {
|
|
return "", ""
|
|
}
|
|
|
|
msg, err := mail.ReadMessage(bytes.NewReader(raw))
|
|
if err != nil {
|
|
return string(raw), ""
|
|
}
|
|
|
|
contentType := msg.Header.Get("Content-Type")
|
|
if contentType == "" {
|
|
contentType = "text/plain"
|
|
}
|
|
|
|
mediaType, params, err := mime.ParseMediaType(contentType)
|
|
if err != nil {
|
|
body, _ := io.ReadAll(msg.Body)
|
|
return string(body), ""
|
|
}
|
|
|
|
if strings.HasPrefix(mediaType, "multipart/") {
|
|
return parseMultipart(msg.Body, params["boundary"])
|
|
}
|
|
|
|
body, _ := io.ReadAll(msg.Body)
|
|
if mediaType == "text/html" {
|
|
return "", string(body)
|
|
}
|
|
return string(body), ""
|
|
}
|
|
|
|
func parseMultipart(r io.Reader, boundary string) (text string, html string) {
|
|
mr := multipart.NewReader(r, boundary)
|
|
for {
|
|
part, err := mr.NextPart()
|
|
if err != nil {
|
|
break
|
|
}
|
|
|
|
partType := part.Header.Get("Content-Type")
|
|
mediaType, params, _ := mime.ParseMediaType(partType)
|
|
|
|
switch {
|
|
case mediaType == "text/plain":
|
|
body, _ := io.ReadAll(part)
|
|
text = string(body)
|
|
case mediaType == "text/html":
|
|
body, _ := io.ReadAll(part)
|
|
html = string(body)
|
|
case strings.HasPrefix(mediaType, "multipart/"):
|
|
t, h := parseMultipart(part, params["boundary"])
|
|
if text == "" {
|
|
text = t
|
|
}
|
|
if html == "" {
|
|
html = h
|
|
}
|
|
}
|
|
}
|
|
return text, html
|
|
}
|