Golang AWS SES xlsx附件已损坏



在golang,我试图发送一封附有XLSX文件的电子邮件。我使用github.com/tealeg/xlsx/v3将XLSX文件生成为字节数组,当与这样的web服务器(这里是gin(一起使用时,它工作得很好:

c.Header("Content-Description", "File Transfer")
c.Header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
c.Header("Content-Disposition", "attachment; filename="+time.Now().UTC().Format("daily-alerts-20060102.xlsx"))
c.Data(http.StatusOK, "application/octet-stream", fileContent)

但是,当使用SES发送时,虽然CSV文件得到了正确的服务,但6ko XLSX文件会变成10ko XL SX文件,并且不可能使用Excel:打开它

func (s *EmailSenderParams) SendEmailWithAttachment(content string, data *models.RawEmailData, attachment []byte, attachmentFilename string) error {
sess, err := session.NewSession(&aws.Config{
Region: aws.String(s.awsRegion)},
)
creds := credentials.NewStaticCredentials(s.apiID, s.apiKey, "")
// Create an SES session.
svc := ses.New(sess, &aws.Config{Credentials: creds})
// Assemble the email.
buf := new(bytes.Buffer)
writer := multipart.NewWriter(buf)
// email main header:
h := make(textproto.MIMEHeader)
//h.Set("From", source)
h.Set("To", data.ReceiverMail)
//h.Set("Return-Path", source)
h.Set("Subject", data.Subject)
h.Set("Content-Language", "en-US")
h.Set("Content-Type", "multipart/mixed; boundary=""+writer.Boundary()+""")
h.Set("MIME-Version", "1.0")
_, err = writer.CreatePart(h)
if err != nil {
return err
}
// body:
h = make(textproto.MIMEHeader)
h.Set("Content-Transfer-Encoding", "7bit")
h.Set("Content-Type", "text/plain; charset=us-ascii")
part, err := writer.CreatePart(h)
if err != nil {
return err
}
_, err = part.Write([]byte(content))
if err != nil {
return err
}
// file attachment:
h = make(textproto.MIMEHeader)
h.Set("Content-Disposition", "attachment; filename="+attachmentFilename)
h.Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; x-unix-mode=0644; name=""+attachmentFilename+""")
h.Set("Content-Transfer-Encoding", "7bit")
part, err = writer.CreatePart(h)
if err != nil {
return err
}
_, err = part.Write(attachment)
if err != nil {
return err
}
err = writer.Close()
if err != nil {
return err
}
// Strip boundary line before header (doesn't work with it present)
st := buf.String()
if strings.Count(st, "n") < 2 {
return fmt.Errorf("invalid e-mail content")
}
st = strings.SplitN(st, "n", 2)[1]
raw := ses.RawMessage{
Data: []byte(st),
}
input := &ses.SendRawEmailInput{
Destinations: []*string{aws.String(data.ReceiverMail)},
Source:       aws.String(s.senderEmail),
RawMessage:   &raw,
}
// Attempt to send the email.
_, err = svc.SendRawEmail(input)
// Display error messages if they occur.
if err != nil {
if aerr, ok := err.(awserr.Error); ok {
switch aerr.Code() {
case ses.ErrCodeMessageRejected:
logrus.Warnln(ses.ErrCodeMessageRejected, aerr.Error())
case ses.ErrCodeMailFromDomainNotVerifiedException:
logrus.Warnln(ses.ErrCodeMailFromDomainNotVerifiedException, aerr.Error())
case ses.ErrCodeConfigurationSetDoesNotExistException:
logrus.Warnln(ses.ErrCodeConfigurationSetDoesNotExistException, aerr.Error())
default:
logrus.Warnln(aerr.Error())
}
} else {
logrus.Warnln(err.Error())
}
logrus.Warnln(err)
return err
}
logrus.Infoln("SES Email Sent to " + data.ReceiverName + " at address: " + data.ReceiverMail)
return nil
}

我认为MIMEHeaders、多部分或编码可能有问题,但我正在努力寻找原因。你知道有什么成功的方法可以发送带有AWS SES的XLSX文件的电子邮件吗?

解决方案是对文件进行base64编码,并将Content-Transfer-Encoding标头设置为base64

h.Set("Content-Transfer-Encoding", "base64")
part, err = writer.CreatePart(h)
if err != nil {
return err
}
b := make([]byte, base64.StdEncoding.EncodedLen(len(attachment)))
base64.StdEncoding.Encode(b, attachment)
_, err = part.Write(b)

相关内容

  • 没有找到相关文章

最新更新