Сообщение электронной почты без части тела при прикреплении файла и отправке через SMTP в Голанге - PullRequest
1 голос
/ 12 июня 2019

Я пытаюсь отправить сообщение электронной почты с текстом и вложенным файлом (файл CSV) в Go (Golang).

Я следую стандарту mime сообщения, состоящего из нескольких частей, однако я не очень хорошо знаком со структурой сообщений, следующих этому стандарту. Я смутно следую отрывку кода Python от коллеги в качестве руководства, использующего библиотеку Python email (я думаю, что это из стандартной библиотеки), например. MIMEText и MIMEMultipart.

В теле сообщения электронной почты не отображается при выполнении следующего кода Go:

  • Что с ним не так?
  • Как я могу отправить сообщение электронной почты с вложенным файлом и телом сообщения электронной почты?

Эта функция должна возвращать фрагмент байта, который будет использоваться в качестве параметра для вызова smtp.SendMail из стандартной библиотеки Go. См. Комментарии ниже, объясняющие, что происходит с полученным сообщением электронной почты (THIS DOES NOT SHOW UP [...] и THIS ALSO DOES NOT SHOW UP [...]).

func msgWithAttachment(subject, filePath string) ([]byte, error) {
    // this is the separator used for the various parts of the MIME message structure
    // identified as "boundary"
    bPlaceholder := "our-custom-separator"

    // the message setup of the common/standard initial part
    mime := bytes.NewBuffer(nil)
    mime.WriteString(fmt.Sprintf("Subject: %s\r\nMIME-Version: 1.0\r\n", subject))
    mime.WriteString(fmt.Sprintf("Content-Type: multipart/mixed; boundary=%s\r\n", bPlaceholder))

    // THIS DOES NOT SHOW UP AS THE BODY OF THE EMAIL...
    // mime.WriteString("\r\n")
    // mime.WriteString(fmt.Sprintf("--%s\r\n", bPlaceholder))
    // mime.WriteString("This should be the email message body (v1)...")
    // mime.WriteString("\r\n")

    // THIS ALSO DOES NOT SHOW UP AS THE BODY OF THE EMAIL...
    // BUT IS NEEDED OTHERWISE THE EMAIL MESSAGE SEEMS TO CONTAIN AS ATTACHMENT THE EMAIL MESSAGE ITSELF
    // (CONTAINING ITSELF THE REAL ATTACHMENT)
    mime.WriteString(fmt.Sprintf("--%s\r\n", bPlaceholder))
    mime.WriteString("Content-Type: text/plain; charset=utf-8\r\n")
    mime.WriteString("This should be the email message body (v2)...")

    // attach a file from the filesystem
    _, msgFilename := filepath.Split(filePath)
    mime.WriteString(fmt.Sprintf("\n--%s\r\n", bPlaceholder))
    mime.WriteString("Content-Type: application/octet-stream\r\n")
    mime.WriteString("Content-Description: " + msgFilename + "\r\n")
    mime.WriteString("Content-Transfer-Encoding: base64\r\n")
    mime.WriteString("Content-Disposition: attachment; filename=\"" + msgFilename + "\"\r\n\r\n")
    fileContent, err := ioutil.ReadFile(filePath) // read and encode the content of the file
    if err != nil {
        return nil, err
    }
    b := make([]byte, base64.StdEncoding.EncodedLen(len(fileContent)))
    base64.StdEncoding.Encode(b, fileContent)
    mime.Write(b)

    // footer of the email message
    mime.WriteString("\r\n--" + bPlaceholder + "--\r\n\r\n")

    return mime.Bytes(), nil
}
...