go-gomail / gomail

The best way to send emails in Go.
MIT License
4.32k stars 572 forks source link

m.Attach issue with more than one files #99

Open gnsx opened 6 years ago

gnsx commented 6 years ago

I'm trying to send attachments by directly reading from the file buffer instead of physical files on the disk.

Attachment Struct

type FileAttachment struct {
    Filename    string
    FileContent []byte
}

After attaching 3 files, tried doing the following

for i := range fileAttachment {
            m.Attach(fileAttachment[i].Filename, gomail.SetCopyFunc(func(w io.Writer) error {
                _, err := w.Write(fileAttachment[i].FileContent)
                return err
            }))
        }

The files get sent successfully but, all the files become of the same filesize of the last file that was attached. Eg: File A 1kB, File B 2kB, FIle C 3kB. ALl the files become 3kB.

However if the files are manually attached like shown below, they get sent just fine with the correct content being reproduced on the email

m.Attach(fileAttachment[0].Filename, gomail.SetCopyFunc(func(w io.Writer) error {
      _ , err := w.Write(fileAttachment[0].FileContent)
      return err
}))
m.Attach(fileAttachment[1].Filename, gomail.SetCopyFunc(func(w io.Writer) error {
      _ , err := w.Write(fileAttachment[1].FileContent)
      return err
}))
m.Attach(fileAttachment[2].Filename, gomail.SetCopyFunc(func(w io.Writer) error {
      _ , err := w.Write(fileAttachment[2].FileContent)
      return err
}))
middelink commented 6 years ago

Your anonymous function in SetCopyFunc does not bind i, so by the time the function is called (during message assembly; so way later) all their i have 2 in them.

Instead use a closure, which binds the required i. Like so https://play.golang.org/p/CZgr8aq9KE