英文:
AWS SES SDK send email with attachments
问题
我正在使用官方的 AWS Golang SDK与 SES 进行集成,但找不到关于如何将一些附件(代码中表示为 []byte 的 PDF 文件)添加到电子邮件中的任何信息。
你能帮助我吗?
当前的电子邮件发送代码如下所示:
sesEmailInput := &ses.SendEmailInput{
Destination: &ses.Destination{
ToAddresses: []*string{aws.String("收件人地址")},
},
Message: &ses.Message{
Subject: &ses.Content{
Data: aws.String("一些文本"),
},
Body: &ses.Body{
Html: &ses.Content{
Data: aws.String("一些文本"),
},
},
},
Source: aws.String("发件人地址"),
ReplyToAddresses: []*string{
aws.String("发件人地址"),
},
}
if _, err := s.sesSession.SendEmail(sesEmailInput); err != nil {
return err
}
英文:
I'm using the official AWS Golang SDK to integrate with SES but can't find any information about how to add some attachments (pdf file represented as []byte in code) to the email.
Could you help me?
The current email sending code looks like this:
sesEmailInput := &ses.SendEmailInput{
Destination: &ses.Destination{
ToAddresses: []*string{aws.String("To address")},
},
Message: &ses.Message{
Subject: &ses.Content{
Data: aws.String("Some text"),
},
Body: &ses.Body{
Html: &ses.Content{
Data: aws.String("Some Text"),
},
},
},
Source: aws.String("From address"),
ReplyToAddresses: []*string{
aws.String("From address"),
},
}
if _, err := s.sesSession.SendEmail(sesEmailInput); err != nil {
return err
}
答案1
得分: 16
要发送附件,请使用SendRawEmail API而不是SendEmail。AWS文档通常将其称为构建“原始消息”,而不是明确说明如何发送附件。
以下是一个示例,来自AWS SDK for Go API参考文档:
params := &ses.SendRawEmailInput{
RawMessage: &ses.RawMessage{ // Required
Data: []byte("PAYLOAD"), // Required
},
ConfigurationSetName: aws.String("ConfigurationSetName"),
Destinations: []*string{
aws.String("Address"), // Required
// More values...
},
FromArn: aws.String("AmazonResourceName"),
ReturnPathArn: aws.String("AmazonResourceName"),
Source: aws.String("Address"),
SourceArn: aws.String("AmazonResourceName"),
Tags: []*ses.MessageTag{
{ // Required
Name: aws.String("MessageTagName"), // Required
Value: aws.String("MessageTagValue"), // Required
},
// More values...
},
}
resp, err := svc.SendRawEmail(params)
进一步阅读:
- Amazon SES API参考 - SendRawEmail
- AWS SDK for Go API参考 - SendRawEmail
- AWS SES文档 - 使用Amazon SES API发送原始邮件 - 这是关于电子邮件标准和构建原始消息的良好入门指南(包括有关附件的部分)。
英文:
To send attachments, use the SendRawEmail API instead of SendEmail. AWS documentation will generally refer to this as constructing a 'raw message' instead of explicitly calling out how to send attachments.
Example
From the AWS SDK for Go API Reference, linked below:
params := &ses.SendRawEmailInput{
RawMessage: &ses.RawMessage{ // Required
Data: []byte("PAYLOAD"), // Required
},
ConfigurationSetName: aws.String("ConfigurationSetName"),
Destinations: []*string{
aws.String("Address"), // Required
// More values...
},
FromArn: aws.String("AmazonResourceName"),
ReturnPathArn: aws.String("AmazonResourceName"),
Source: aws.String("Address"),
SourceArn: aws.String("AmazonResourceName"),
Tags: []*ses.MessageTag{
{ // Required
Name: aws.String("MessageTagName"), // Required
Value: aws.String("MessageTagValue"), // Required
},
// More values...
},
}
resp, err := svc.SendRawEmail(params)
Further Reading
-
AWS SES Documentation - Sending Raw Email Using the Amazon SES API - This is a good primer for email standards and constructing raw messages (including a section about attachments).
答案2
得分: 2
几个关于原始邮件的重要事项:
遵循以下结构:
boundary=boundary_name \n\n (使用 boundary= 和 \n\n 创建一个边界)
--boundary_name (使用 -- 开始一个边界)
Header (使用 Content-Type: 添加头部)
(使用 \n 添加一个空行)
html 或 text 或 file (添加你的内容)
(使用 \n 添加一个空行)
--boundary_name-- \n\n (使用 -- -- 和 \n\n 关闭边界)
PHP 代码示例:
$boundary = md5(time());
$html = "<h1>E-mail Test</h1>";
$html .= "<img src=\"cid:{$attachment['filename']}\">"; // Content-ID
$text = "You need HTML enabled";
$raw = '';
$raw .= "From:{$from}\n";
$raw .= "To:{$to}\n";
$raw .= "Subject:{$subject}\n";
$raw .= "MIME-Version: 1.0\n";
$raw .= "Content-Type: multipart/mixed; boundary=\"{$boundary}\"\n\n";
$raw .= "--{$boundary}\n";
$raw .= "Content-Type: multipart/alternative; boundary=\"sub_{$boundary}\"\n\n";
$raw .= "--sub_{$boundary}\n";
$raw .= "Content-Type: text/plain; charset=\"UTF-8\"\n";
$raw .= "\n";
$raw .= "{$text}\n";
$raw .= "\n";
$raw .= "--sub_{$boundary}\n";
$raw .= "Content-Type: text/html; charset=\"UTF-8\"\n";
$raw .= "Content-Disposition: inline\n";
$raw .= "\n";
$raw .= "{$html}\n";
$raw .= "\n";
$raw .= "--sub_{$boundary}--\n\n";
foreach ($this->email->getFiles() as $attachment) {
$raw .= "--{$boundary}\n";
$raw .= "Content-Type:{$attachment['mimetype']}; name=\"{$attachment['filename']}\"\n"; // name
$raw .= "Content-Transfer-Encoding:base64\n";
$raw .= "Content-Disposition:attachment;filename=\"{$attachment['filename']}\"\n"; // filename
#$raw .= "Content-Disposition:inline;name={$file_name}\n";
$raw .= "Content-ID:<{$attachment['filename']}>\n";
$raw .= "\n";
$raw .= base64_encode($attachment['content']) . "\n";
$raw .= "\n";
}
$raw .= "--{$boundary}--\n\n";
最终的原始消息示例:
From:Name From<name@from.com>
To:email@to.com,second@to.com
Subject:Your subject
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="b4f53df7c26ae6945f29c42d5c2bb55f"
--b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type: multipart/alternative; boundary="sub_b4f53df7c26ae6945f29c42d5c2bb55f"
--sub_b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type: text/plain; charset="UTF-8"
You need HTML enabled
--sub_b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type: text/html; charset="UTF-8"
Content-Disposition: inline
<h1>E-mail Test</h1>
<img src="cid:qrcode.png"> // <-- from Header Content-ID:<name>
--sub_b4f53df7c26ae6945f29c42d5c2bb55f--
--b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type:image/png; name="qrcode.png"
Content-Transfer-Encoding:base64
Content-Disposition:attachment;filename="qrcode.png"
Content-ID:<qrcode.png> // you can use <img src="cid:qrcode.png"> in html
iVBORw0K== // base64 编码的文件内容
--b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type:image/png; name="another_file.png"
Content-Transfer-Encoding:base64
Content-Disposition:attachment;filename="another_file.png"
Content-ID:<another_file.png>
iVBORw0KGg== // base64 编码的文件内容
--b4f53df7c26ae6945f29c42d5c2bb55f--
不要忘记,在头部之后和内容之前都要有一个空行。
对于 PHP AWS SDK:
try {
$client = new SesClient($options);
$result = $client->sendRawEmail([
'RawMessage' => [
'Data' => $raw
],
]);
echo $result['MessageId'];
}
catch (AwsException $e) {
echo $e->getAwsErrorMessage();
return false;
}
英文:
after several wasted hours, things you should know about raw emails.
follow a structure like this:
boundary=boundary_name \n\n (create a boundary with boundary= and \n\n)
--boundary_name (start a boundary with --)
Header (add headers with Content-Type:)
(one blank line with \n)
html or text or file (add your content)
(one blank line with \n)
--boundary_name-- \n\n (close boundary with -- -- and \n\n)
Example with PHP code:
$boundary = md5(time());
$html = "<h1>E-mail Test</h1>";
$html .= "<img src=\"cid:{$attachment['filename']}\">"; // Content-ID
$text = "You need HTML enabled";
$raw = '';
$raw .= "From:{$from}\n";
$raw .= "To:{$to}\n";
$raw .= "Subject:{$subject}\n";
$raw .= "MIME-Version: 1.0\n";
$raw .= "Content-Type: multipart/mixed; boundary=\"{$boundary}\"\n\n";
$raw .= "--{$boundary}\n";
$raw .= "Content-Type: multipart/alternative; boundary=\"sub_{$boundary}\"\n\n";
$raw .= "--sub_{$boundary}\n";
$raw .= "Content-Type: text/plain; charset=\"UTF-8\"\n";
$raw .= "\n";
$raw .= "{$text}\n";
$raw .= "\n";
$raw .= "--sub_{$boundary}\n";
$raw .= "Content-Type: text/html; charset=\"UTF-8\"\n";
$raw .= "Content-Disposition: inline\n";
$raw .= "\n";
$raw .= "{$html}\n";
$raw .= "\n";
$raw .= "--sub_{$boundary}--\n\n";
foreach ($this->email->getFiles() as $attachment) {
$raw .= "--{$boundary}\n";
$raw .= "Content-Type:{$attachment['mimetype']}; name=\"{$attachment['filename']}\"\n"; // name
$raw .= "Content-Transfer-Encoding:base64\n";
$raw .= "Content-Disposition:attachment;filename=\"{$attachment['filename']}\"\n"; // filename
#$raw .= "Content-Disposition:inline;name={$file_name}\n";
$raw .= "Content-ID:<{$attachment['filename']}>\n";
$raw .= "\n";
$raw .= base64_encode($attachment['content']) . "\n";
$raw .= "\n";
}
$raw .= "--{$boundary}--\n\n";
Final raw Message example:
From:Name From<name@from.com>
To:email@to.com,second@to.com
Subject:Your subject
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="b4f53df7c26ae6945f29c42d5c2bb55f"
--b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type: multipart/alternative; boundary="sub_b4f53df7c26ae6945f29c42d5c2bb55f"
--sub_b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type: text/plain; charset="UTF-8"
You need HTML enabled
--sub_b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type: text/html; charset="UTF-8"
Content-Disposition: inline
<h1>E-mail Test</h1>
<img src="cid:qrcode.png"> // <-- from Header Content-ID:<name>
--sub_b4f53df7c26ae6945f29c42d5c2bb55f--
--b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type:image/png; name="qrcode.png"
Content-Transfer-Encoding:base64
Content-Disposition:attachment;filename="qrcode.png"
Content-ID:<qrcode.png> // you can use <img src="cid:qrcode.png"> in html
iVBORw0K== // base64encoded file contents
--b4f53df7c26ae6945f29c42d5c2bb55f
Content-Type:image/png; name="another_file.png"
Content-Transfer-Encoding:base64
Content-Disposition:attachment;filename="another_file.png"
Content-ID:<another_file.png>
iVBORw0KGg== // base64encoded file contents
--b4f53df7c26ae6945f29c42d5c2bb55f--
Don't forget, after Headers, one blank lines before and after content
For PHP AWS SDK
try {
$client = new SesClient($options);
$result = $client->sendRawEmail([
'RawMessage' => [
'Data' => $raw
],
]);
echo $result['MessageId'];
}
catch (AwsException $e) {
echo $e->getAwsErrorMessage();
return false;
}
答案3
得分: 1
SES原始消息必须进行base64编码。因此,您需要将文件内容作为缓冲区获取,并将其编码为base64字符串附件。此外,您不需要为原始消息数据创建新的缓冲区,因为它已经接受字符串数据类型。
可选:您还可以省略Destinations参数,因为您已经在原始消息数据中提供了To字段。(您也可以提供Cc和Bcc字段)
您可以尝试以下示例代码:
const sendAttachmentEmail = async () => {
// 您可以使用以下方式
const DATA = await workbook.writeToBuffer(); // 这是生成的Excel工作簿
// 或者使用以下方式
const DATA = fs.readFileSync("files/demo-invoice.xlsx"); // 这是files文件夹中的Excel文件
const SOURCE_EMAIL = "xyz@gmail.com";
const TO_EMAIL = "abc@gmail.com";
let ses_mail = "From: 'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">\n";
ses_mail += "To: " + TO_EMAIL + "\n";
ses_mail += "Subject: AWS SES Attachment Example\n";
ses_mail += "MIME-Version: 1.0\n";
ses_mail += "Content-Type: multipart/mixed; boundary=\"NextPart\"\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: text/html\n\n";
ses_mail += "This is the body of the email.\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: application/octet-stream; name=\"demo-invoice.xlsx\"\n";
ses_mail += "Content-Transfer-Encoding: base64\n";
ses_mail += "Content-Disposition: attachment\n\n";
ses_mail += DATA.toString("base64").replace(/([^const sendAttachmentEmail = async () => {
// 您可以使用以下方式
const DATA = await workbook.writeToBuffer(); // 这是生成的Excel工作簿
// 或者使用以下方式
const DATA = fs.readFileSync("files/demo-invoice.xlsx"); // 这是files文件夹中的Excel文件
const SOURCE_EMAIL = "xyz@gmail.com";
const TO_EMAIL = "abc@gmail.com";
let ses_mail = "From: 'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">\n";
ses_mail += "To: " + TO_EMAIL + "\n";
ses_mail += "Subject: AWS SES Attachment Example\n";
ses_mail += "MIME-Version: 1.0\n";
ses_mail += "Content-Type: multipart/mixed; boundary=\"NextPart\"\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: text/html\n\n";
ses_mail += "This is the body of the email.\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: application/octet-stream; name=\"demo-invoice.xlsx\"\n";
ses_mail += "Content-Transfer-Encoding: base64\n";
ses_mail += "Content-Disposition: attachment\n\n";
ses_mail += DATA.toString("base64").replace(/([^\0]{76})/g, "$1\n") + "\n\n";
ses_mail += "--NextPart--";
const params = {
RawMessage: {
Data: ses_mail
},
Source: "'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">'"
};
return new Promise((resolve, reject) => {
ses.sendRawEmail(params, (err) => {
if (err) {
return reject(err);
}
return resolve();
});
});
};
]{76})/g, "$1\n") + "\n\n";
ses_mail += "--NextPart--";
const params = {
RawMessage: {
Data: ses_mail
},
Source: "'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">'"
};
return new Promise((resolve, reject) => {
ses.sendRawEmail(params, (err) => {
if (err) {
return reject(err);
}
return resolve();
});
});
};
注意:正则表达式替换/([^\0]{76})/g
会将您的长行拆分,以确保邮件服务器不会因为有编码附件而抱怨消息行过长而导致暂时性退回。
英文:
SES raw messages must be base64-encoded. So, you'll need to get the file content as buffer and encode it as base64 string attachment. Also, you don't need to create a new buffer for raw message data since it already accepts a string data type.
OPTIONAL: You can also omit the Destinations parameter since you're already providing the To field in the raw message data. (You can also provide the Cc and Bcc fields as well)
You could try this for example:
const sendAttachmentEmail = async () => {
// Yo can use by this way
const DATA = await workbook.writeToBuffer(); // This workbook is excel generated
// Or this way
const DATA = fs.readFileSync("files/demo-invoice.xlsx"); // This is excel file in files folder
const SOURCE_EMAIL = "xyz@gmail.com";
const TO_EMAIL = "abc@gmail.com";
let ses_mail = "From: 'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">\n";
ses_mail += "To: " + TO_EMAIL + "\n";
ses_mail += "Subject: AWS SES Attachment Example\n";
ses_mail += "MIME-Version: 1.0\n";
ses_mail += "Content-Type: multipart/mixed; boundary=\"NextPart\"\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: text/html\n\n";
ses_mail += "This is the body of the email.\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: application/octet-stream; name=\"demo-invoice.xlsx\"\n";
ses_mail += "Content-Transfer-Encoding: base64\n";
ses_mail += "Content-Disposition: attachment\n\n";
ses_mail += data.toString("base64").replace(/([^const sendAttachmentEmail = async () => {
// Yo can use by this way
const DATA = await workbook.writeToBuffer(); // This workbook is excel generated
// Or this way
const DATA = fs.readFileSync("files/demo-invoice.xlsx"); // This is excel file in files folder
const SOURCE_EMAIL = "xyz@gmail.com";
const TO_EMAIL = "abc@gmail.com";
let ses_mail = "From: 'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">\n";
ses_mail += "To: " + TO_EMAIL + "\n";
ses_mail += "Subject: AWS SES Attachment Example\n";
ses_mail += "MIME-Version: 1.0\n";
ses_mail += "Content-Type: multipart/mixed; boundary=\"NextPart\"\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: text/html\n\n";
ses_mail += "This is the body of the email.\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: application/octet-stream; name=\"demo-invoice.xlsx\"\n";
ses_mail += "Content-Transfer-Encoding: base64\n";
ses_mail += "Content-Disposition: attachment\n\n";
ses_mail += data.toString("base64").replace(/([^\0]{76})/g, "$1\n") + "\n\n";
ses_mail += "--NextPart--";
const params = {
RawMessage: {
Data: ses_mail
},
Source: "'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">'"
};
return new Promise((resolve, reject) => {
ses.sendRawEmail(params, (err) => {
if (err) {
return reject(err);
}
return resolve();
});
});
};
]{76})/g, "$1\n") + "\n\n";
ses_mail += "--NextPart--";
const params = {
RawMessage: {
Data: ses_mail
},
Source: "'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">'"
};
return new Promise((resolve, reject) => {
ses.sendRawEmail(params, (err) => {
if (err) {
return reject(err);
}
return resolve();
});
});
};
NOTE: The /([^\0]{76})/ regular expression replacement breaks your long lines to make sure that mail servers do not complain about message lines being too long when there is an encoded attachment, which might result in a transient bounce.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论