title: Email message with no body part when attaching a file and sending via SMTP in Golang
body: <p>I am trying to send an email message with both an email body and a file attachment (a CSV file) in Go (Golang).</p>
  
  <p>I am following the <code>mime</code> standard of a multi-part message, however I am not  very familiar with the structure of the messages following that standard. I am vaguely following a Python code snippet from a colleague as a guide which is using the Python library <code>email</code> (I think this is from the standard library) e.g. <code>MIMEText</code> and <code>MIMEMultipart</code>.</p>
  
  <p><strong>The email message body is not showing up</strong> when executing the following Go code:</p>
  
  <ul>
  <li>What is wrong with it?</li>
  <li>How can I send an email message with both that file attachment and an email message body?</li>
  </ul>
  
  <p>This function should return a byte slice to be used as a parameter for the call to <code>smtp.SendMail</code> from the Go standard library. See the comments below explaining what's happening to the received email message (the <code>THIS DOES NOT SHOW UP [...]</code> and the <code>THIS ALSO DOES NOT SHOW UP [...]</code>).</p>
  
  <pre><code>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
  }
  </code></pre>