寻找一个发送包含附件的原始邮件的Amazon SES示例



Amazon SES文档对我来说不是很清楚。所以,如果你能帮我举一个例子,如何发送包含PDF附件的原始文本电子邮件,这将帮助我很多。我使用Python 2.5和Google App引擎。我必须使用"raw",因为如果包含附件,这是唯一的SES选项。

我现在的问题:

  • post request的内容是什么?
  • 我应该在header中放入哪些消息字段。
  • 如何处理"returnPath"
  • 如何处理文本主体。它应该是:Content-Type: text/plain;charset = utf - 8;格式=流动;delsp = yes。Content-Transfer-Encoding: base64
  • 我如何构建这篇文章的HMAC签名。我知道如何制作签名,但是原始字符串如何寻找签名函数。

使用多部分正文(plain/html/attachment)发送SES原始电子邮件的示例代码:

from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.multipart import MIMEMultipart
from google.appengine.api import urlfetch
from google.appengine.runtime import DeadlineExceededError
import urllib
import hmac
import base64
import hashlib
from datetime import datetime
import logging

def ses_multi_part(msg_subject, msg_to, msg_body='', msg_cc=None, msg_bcc=None, file_name=None, file_reader=None,
                      msg_type='plain', msg_from='noreply@....', msg_reply_to='contact@....'):
    """ send an html or plain e-mail. Use file_name and file_reader to pass an attachment
        inspiration: https://codeadict.wordpress.com/2010/02/11/send-e-mails-with-attachment-in-python/
    """
    msg = MIMEMultipart()
    msg.set_charset("utf-8")
    msg['Subject'] = msg_subject
    msg['From'] = msg_from
    msg['Reply-to'] = msg_reply_to
    msg['To'] = msg_to
    if msg_cc:
        msg['Cc'] = msg_cc
    if msg_bcc:
        msg['Bcc'] = msg_bcc
    logging.debug(msg)
    msg.preamble = 'Multipart massage.n'
    part = MIMEText(msg_body, msg_type, "utf-8")
    msg.attach(part)
    if file_name:
        part = MIMEApplication(file_reader.read())
        part.add_header('Content-Disposition', 'attachment', filename=file_name)
        msg.attach(part)
    return msg.as_string()

class SES(object):
    """ SES send RAW e-mail
        inspiration: https://github.com/richieforeman/python-amazon-ses-api/blob/master/amazon_ses.py
    """
    def __init__(self, accessKeyID, secretAccessKey, return_path='contact@....'):
        self._accessKeyID = accessKeyID
        self._secretAccessKey = secretAccessKey
        self.ses_return_path = return_path
    def _getSignature(self, dateValue):
        h = hmac.new(key=self._secretAccessKey, msg=dateValue, digestmod=hashlib.sha256)
        return base64.b64encode(h.digest()).decode()
    def _getHeaders(self):
        headers = {'Content-type': 'application/x-www-form-urlencoded', 'Return-Path': self.ses_return_path}
        d = datetime.utcnow()
        dateValue = d.strftime('%a, %d %b %Y %H:%M:%S GMT')
        headers['Date'] = dateValue
        signature = self._getSignature(dateValue)
        headers['X-Amzn-Authorization'] = 'AWS3-HTTPS AWSAccessKeyId=%s, Algorithm=HMACSHA256, Signature=%s' % (self._accessKeyID, signature)
        return headers
    def _performAction(self, actionName, params=None):
        if not params:
            params = {}
        params['Action'] = actionName
        response = None
        #https://email.us-east-1.amazonaws.com/
        retry = 0  # download error retry
        while retry <= 1:  # dan een eenmalige retry
            try:
                url = 'https://email.us-east-1.amazonaws.com'
                response = urlfetch.fetch(url=url, payload=urllib.urlencode(params), method=urlfetch.POST, headers=self._getHeaders())
                break
            except (urlfetch.DownloadError, DeadlineExceededError), e:
                logging.debug('Amazon SES download or deadline error : %d' % (retry + 1))
                if retry == 0:
                    retry += 1
                    continue  # retry
                else:
                    logging.warning('fetcherror' + str(e))
                    raise  # bij een dubbele fout stoppen
        if response.status_code != 200:
            logging.warning(response.headers)
            logging.warning(response.content)
            raise ValueError('status_code : %s' % (str(response.status_code)))
        logging.debug(response.content)
        return response.content
    def sendRawEmail(self, raw_msg_data):
        return self._performAction("SendRawEmail", params={"RawMessage.Data": base64.b64encode(raw_msg_data)})

使用例子:

ses = SES(settings.AMAZON_ACCESS_KEY_ID, settings.AMAZON_SECRET_ACCESS_KEY, settings.SES_RETURN_PATH[country])
raw_msg_data = ses_multi_part(msg_subject=subject.encode('utf-8'), msg_to=mail_to, msg_body=body_text.encode('utf-8'),
                                 msg_bcc=settings.MAIL_BCC, msg_reply_to=reply_to, msg_from=sender, msg_type=msg_type)
ses.sendRawEmail(raw_msg_data)

我正在使用的过程概述在这个要点中。它主要来自下面给出的示例。

当您可以通过他们的标准SMTP接口发送附件和所有内容时,为什么要使用raw与他们的API ?此外,上次我检查raw不支持密件。

SMTP接口:http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/SMTP.html

批准的MIME类型列表(否则SES会生气):http://docs.amazonwebservices.com/ses/latest/DeveloperGuide/MIMETypes.html

相关内容

  • 没有找到相关文章

最新更新