email - 使用亚马逊SES发送带有附件的电子邮件

标签 email symfony amazon-web-services

我正在尝试使用亚马逊 SES API 发送一封包含附件(pdf 文件)的电子邮件。

我正在使用 Symfony2,因此我将 AmazonWebServiceBundle 包含在我的项目中。 我可以使用以下代码轻松发送一封简单的电子邮件(没有附件):

$ses = $this->container->get('aws_ses');
$recip = array("ToAddresses"=>array("Quilly@yourownpoet.com"));
$message = array("Subject.Data"=>"My Subject","Body.Text.Data"=>"My Mail body");
$result = $ses->send_email("Quilly@yourownpoet.com",$recip, $message);

不幸的是,要发送带有附件的电子邮件,我需要使用 sendRawEmail函数而不是 send_email 函数。

我无法找到如何使用此功能,有人可以帮忙吗?

最佳答案

是的,使用 SES 发送带有附件的电子邮件很痛苦。也许这会帮助那些仍在苦苦挣扎的人。我编写了一个简单的类,有助于简化对 sendRawEmail 的调用。

用法:

$subject_str = "Some Subject";
$body_str = "<strong>Some email body</strong>";
$attachment_str = file_get_contents("/htdocs/test/sample.pdf");

//send the email
$result = SESUtils::deliver_mail_with_attachment(
    array('email1@gmail.com', 'email2@lutz-engr.com'),       
    $subject_str, $body_str, 'sender@verifiedbyaws', 
    $attachment_str);

//now handle the $result if you wish

类(class):

<?php
require 'AWSSDKforPHP/aws.phar';
use Aws\Ses\SesClient;

/**
 * SESUtils is a tool to make it easier to work with Amazon Simple Email Service
 * Features:
 * A client to prepare emails for use with sending attachments or not
 * 
 * There is no warranty - use this code at your own risk.  
 * @author sbossen 
 * http://right-handed-monkey.blogspot.com
 */
class SESUtils {

    const version = "1.0";
    const AWS_KEY = "your_aws_key";
    const AWS_SEC = "your_aws_secret";
    const AWS_REGION = "us-east-1";
    const BOUNCER = "bouncer@yourdomain.com";  //if used, this also needs to be a verified email
    const LINEBR = "\n";
    const MAX_ATTACHMENT_NAME_LEN = 60;

    /**
     * Usage
     * $result = SESUtils::deliver_mail_with_attachment(array('receipt@r.com', 'receipt2@b.com'), $subject_str, $body_str, 'validatedsender@aws', $attachment_str);
     * use $result->success to check if it was successful
     * use $result->message_id to check later with Amazon for further processing
     * use $result->result_text to look for error text if the task was not successful
     * 
     * @param type $to - individual address or array of email addresses
     * @param type $subject - UTF-8 text for the subject line
     * @param type $body - Text for the email
     * @param type $from - email address of the sender (Note: must be validated with AWS as a sender)
     * @return \ResultHelper
     */
    public static function deliver_mail_with_attachment($to, $subject, $body, $from, &$attachment = "", $attachment_name = "doc.pdf", $attachment_type = "Application/pdf", $is_file = false, $encoding = "base64", $file_arr = null) {
        $result = new ResultHelper();
        //get the client ready
        $client = SesClient::factory(array(
                    'key' => self::AWS_KEY,
                    'secret' => self::AWS_SEC,
                    'region' => self::AWS_REGION
        ));
        //build the message
        if (is_array($to)) {
            $to_str = rtrim(implode(',', $to), ',');
        } else {
            $to_str = $to;
        }
        $msg = "To: $to_str".self::LINEBR;
        $msg .="From: $from".self::LINEBR;
        //in case you have funny characters in the subject
        $subject = mb_encode_mimeheader($subject, 'UTF-8');
        $msg .="Subject: $subject".self::LINEBR;
        $msg .="MIME-Version: 1.0".self::LINEBR;
        $msg .="Content-Type: multipart/alternative;".self::LINEBR;
        $boundary = uniqid("_Part_".time(), true); //random unique string
        $msg .=" boundary=\"$boundary\"".self::LINEBR;
        $msg .=self::LINEBR;
        //now the actual message
        $msg .="--$boundary".self::LINEBR;
        //first, the plain text
        $msg .="Content-Type: text/plain; charset=utf-8".self::LINEBR;
        $msg .="Content-Transfer-Encoding: 7bit".self::LINEBR;
        $msg .=self::LINEBR;
        $msg .=strip_tags($body);
        $msg .=self::LINEBR;
        //now, the html text
        $msg .="--$boundary".self::LINEBR;
        $msg .="Content-Type: text/html; charset=utf-8".self::LINEBR;
        $msg .="Content-Transfer-Encoding: 7bit".self::LINEBR;
        $msg .=self::LINEBR;
        $msg .=$body;
        $msg .=self::LINEBR;
        //add attachments
        if (!empty($attachment)) {
            $msg .="--$boundary".self::LINEBR;
            $msg .="Content-Transfer-Encoding: base64".self::LINEBR;
            $clean_filename = mb_substr($attachment_name, 0, self::MAX_ATTACHMENT_NAME_LEN);
            $msg .="Content-Type: $attachment_type; name=$clean_filename;".self::LINEBR;
            $msg .="Content-Disposition: attachment; filename=$clean_filename;".self::LINEBR;
            $msg .=self::LINEBR;
            $msg .=base64_encode($attachment);
            //only put this mark on the last entry
            if (!empty($file_arr))
                $msg .="==".self::LINEBR;
            $msg .="--$boundary";
        }
        if (!empty($file_arr) && is_array($file_arr)) {
            foreach ($file_arr as $file) {
                $msg .="Content-Transfer-Encoding: base64".self::LINEBR;
                $clean_filename = mb_substr($attachment_name, 0, self::MAX_ATTACHMENT_NAME_LEN);
                $msg .="Content-Type: application/octet-stream; name=$clean_filename;".self::LINEBR;
                $msg .="Content-Disposition: attachment; filename=$clean_filename;".self::LINEBR;
                $msg .=self::LINEBR;
                $msg .=base64_encode($attachment);
                //only put this mark on the last entry
                if (!empty($file_arr))
                    $msg .="==".self::LINEBR;
                $msg .="--$boundary";
            }
        }
        //close email
        $msg .="--".self::LINEBR;

        //now send the email out
        try {
            $ses_result = $client->sendRawEmail(array(
                'RawMessage' => array('Data' => base64_encode($msg))), array('Source' => $from, 'Destinations' => $to_str));
            if ($ses_result) {
                $result->message_id = $ses_result->get('MessageId');
            } else {
                $result->success = false;
                $result->result_text = "Amazon SES did not return a MessageId";
            }
        } catch (Exception $e) {
            $result->success = false;
            $result->result_text = $e->getMessage()." - To: $to_str, Sender: $from, Subject: $subject";
        }
        return $result;
    }

}


class ResultHelper {

    public $success = true;
    public $result_text = "";
    public $message_id = "";

}

?>

我写了一篇博客文章来解决这个问题,也许它对您或其他人有用:http://righthandedmonkey.com/2013/06/how-to-use-amazon-ses-to-send-email-php.html

关于email - 使用亚马逊SES发送带有附件的电子邮件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11098285/

相关文章:

php - symfony:如何处理实体类型的二级链接选择?

symfony - assetic.ERROR "DoctrineBundle:Collector:db.html.twig"包含错误 : Unknown "profiler_dump" function

amazon-web-services - 代码部署失败,没有任何错误消息

amazon-web-services - 弹性 beantalk 领导人选举的问题

java - 解决从 java swing 使用 javamail api 发送电子邮件时产生的异常

email - 使用 alfresco 作为 smtp 邮件服务器

php - 使用 Symfony 2.8 进行 LDAP 身份验证

amazon-web-services - "Value of property CidrIp must be of type String"云信息

html - rails 发送多封电子邮件?

python - 使用 Python (smtplib) 发送邮件时指定发件人