AWS SES SDK отправить письмо с вложениями

Я использую официальный AWS Golang SDK для интеграции с SES, но не могу найти никакой информации о том, как добавить некоторые вложения (pdf-файл, представленный в виде байта [] в коде) в электронное письмо.

Не могли бы вы помочь мне?

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

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
}

3 ответа

Решение

Чтобы отправлять вложения, используйте API SendRawEmail вместо SendEmail. В документации AWS это обычно называется созданием "необработанного сообщения", а не явным указанием, как отправлять вложения.

пример

Ссылка на API-интерфейс AWS SDK для Go приведена ниже:

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)

Дальнейшее чтение

после нескольких потраченных впустую часов, вещи, которые вы должны знать о необработанных электронных письмах.

следуйте такой структуре:

      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)
  

Пример с 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== // 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--

Не забудьте после заголовков по одной пустой строке до и после содержимого

Для 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;
}

Необработанные сообщения SES должны быть закодированы в base64. Итак, вам нужно получить содержимое файла в виде буфера и закодировать его как вложение строки base64. Кроме того, вам не нужно создавать новый буфер для необработанных данных сообщения, поскольку он уже принимает строковый тип данных.

ДОПОЛНИТЕЛЬНО: вы также можете опустить параметр « Назначения » , поскольку вы уже указали поле « Кому » в необработанных данных сообщения. (Вы также можете указать поля Cc и Bcc )

Вы можете попробовать это, например:

      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();
    });
  });
};

ПРИМЕЧАНИЕ. Замена регулярного выражения /([^\0]{76})/ разбивает ваши длинные строки, чтобы убедиться, что почтовые серверы не жалуются на слишком длинные строки сообщения, когда есть закодированное вложение, что может привести к временной подпрыгивать.

Другие вопросы по тегам