package utils import ( "bytes" "crypto/rand" "encoding/base64" "io" "mime" "mime/quotedprintable" "net/mail" "strings" ) type Email struct { MimeVersion string Date string From string To string Subject string ContentType string Body string } func GenerateRandomString(length int) (string, error) { bytes := make([]byte, length) _, err := rand.Read(bytes) if err != nil { return "", err } return base64.URLEncoding.EncodeToString(bytes), nil } func DecodeMail(message string) (*Email, error) { msg, err := mail.ReadMessage(strings.NewReader(message)) if err != nil { return nil, err } decodedBody, err := io.ReadAll(msg.Body) if err != nil { return nil, err } decodedBodyString, err := DecodeQuotedPrintable(string(decodedBody)) if err != nil { return nil, err } decodedSubject, err := DecodeRFC2047(msg.Header.Get("Subject")) if err != nil { return nil, err } email := &Email{} // Populate the headers email.MimeVersion = msg.Header.Get("Mime-Version") email.Date = msg.Header.Get("Date") email.From = msg.Header.Get("From") email.To = msg.Header.Get("To") email.Subject = decodedSubject email.Body = decodedBodyString email.ContentType = msg.Header.Get("Content-Type") return email, nil } func DecodeRFC2047(encoded string) (string, error) { decoder := new(mime.WordDecoder) decoded, err := decoder.DecodeHeader(encoded) if err != nil { return "", err } return decoded, nil } func DecodeQuotedPrintable(encodedString string) (string, error) { // Decode quoted-printable encoding reader := quotedprintable.NewReader(strings.NewReader(encodedString)) decodedBytes := new(bytes.Buffer) _, err := decodedBytes.ReadFrom(reader) if err != nil { return "", err } return decodedBytes.String(), nil } func EncodeQuotedPrintable(s string) string { var buf bytes.Buffer // Use Quoted-Printable encoder qp := quotedprintable.NewWriter(&buf) // Write the UTF-8 encoded string to the Quoted-Printable encoder qp.Write([]byte(s)) qp.Close() // Encode the result into a MIME header return mime.QEncoding.Encode("UTF-8", buf.String()) }