当前位置: 首页 > 知识库问答 >
问题:

如何将原始电子邮件(MIME)从AWS SES转换为Gmail?

曾喜
2023-03-14

我有一个gmail帐户链接到我的域名帐户。

AWS SES将向我的S3存储桶发送消息。从那里,SNS将把原始格式的信息转发到我的gmail地址。

如何将原始邮件自动转换为标准电子邮件格式?

共有2个答案

马弘和
2023-03-14

对于那些得到这个错误:

'bytes' object has no attribute 'encode'

在这方面:

body = MIMEText(mailobject.get_payload(decode=True), 'UTF-8')

我能做到。我不是这方面的专家,所以代码可能需要一些改进。此外,电子邮件正文还包含html标记。但至少它被送到了。

如果解码电子邮件仍然失败,错误消息将出现在您的CloudWatch日志中。您还将收到一封包含错误消息的电子邮件。

payload = mailobject.get_payload(decode=True)
try:
    decodedPayload = payload.decode()
    body = MIMEText(decodedPayload, 'UTF-8')
    msg.attach(body)
except Exception as error:
    errorMsg = "An error occured when decoding the email payload:\n" + str(error)
    print(errorMsg)
    body = errorMsg + "\nPlease download it manually from the S3 bucket."
    msg.attach(MIMEText(body, 'plain'))

这取决于你想在错误邮件中添加哪些信息,比如主题或发件人地址。

还有一个提示:使用上面的代码,您将得到一个错误,因为subject_original未定义。只需删除以下几行。

# The file name to use for the attached message. Uses regex to remove all
# non-alphanumeric characters, and appends a file extension.
filename = re.sub('[^0-9a-zA-Z]+', '_', subject_original)

# Create a new MIME object.
att = MIMEApplication(file_dict["file"], filename)
att.add_header("Content-Disposition", 'attachment', filename=filename)

# Attach the file object to the message.
msg.attach(att)

据我所知,这段代码应该添加原始电子邮件作为附件,这不是我想要的。

魏健柏
2023-03-14

原始邮件采用标准电子邮件格式。我想你想知道的是如何将标准的原始电子邮件解析成一个你可以操纵的对象,这样你就可以把它转发给你自己,让它看起来像一封标准的电子邮件。AWS提供了一个教程,介绍如何通过SES通过lambda函数转发电子邮件,首先将它们存储在S3存储桶中:https://aws.amazon.com/blogs/messaging-and-targeting/forward-incoming-email-to-an-external-destination/

如果你按照这些说明去做,你会发现你收到的邮件是一个附件,看起来不像一封标准的邮件。下面的代码是对AWS提供的Python代码的修改,它实现了您想要的功能(将此代码替换为教程中提供的代码):

# Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
# Altered from original by Adam Winter
#
# This file is licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License. A copy of the
# License is located at
#
# http://aws.amazon.com/apache2.0/
#
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
# OF ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.

import os
import boto3
import email
import re
import html
from botocore.exceptions import ClientError
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.mime.application import MIMEApplication
from email.mime.image import MIMEImage

region = os.environ['Region']

def get_message_from_s3(message_id):

    incoming_email_bucket = os.environ['MailS3Bucket']
    incoming_email_prefix = os.environ['MailS3Prefix']

    if incoming_email_prefix:
        object_path = (incoming_email_prefix + "/" + message_id)
    else:
        object_path = message_id

    object_http_path = (f"http://s3.console.aws.amazon.com/s3/object/{incoming_email_bucket}/{object_path}?region={region}")

    # Create a new S3 client.
    client_s3 = boto3.client("s3")

    # Get the email object from the S3 bucket.
    object_s3 = client_s3.get_object(Bucket=incoming_email_bucket,
        Key=object_path)
    # Read the content of the message.
    file = object_s3['Body'].read()

    file_dict = {
        "file": file,
        "path": object_http_path
    }

    return file_dict

def create_message(file_dict):

    stringMsg = file_dict['file'].decode('utf-8')

    # Create a MIME container.
    msg = MIMEMultipart('alternative')

    sender = os.environ['MailSender']
    recipient = os.environ['MailRecipient']

    # Parse the email body.
    mailobject = email.message_from_string(file_dict['file'].decode('utf-8'))
    #print(mailobject.as_string())

    # Get original sender for reply-to
    from_original = mailobject['Return-Path']
    from_original = from_original.replace('<', '');
    from_original = from_original.replace('>', '');
    print(from_original)

    # Create a new subject line.
    subject = mailobject['Subject']
    print(subject)

    if mailobject.is_multipart():

        index = stringMsg.find('Content-Type: multipart/')
        stringBody = stringMsg[index:]
        #print(stringBody)
        stringData = 'Subject: ' + subject + '\nTo: ' + sender + '\nreply-to: ' + from_original + '\n' + stringBody

        message = {
            "Source": sender,
            "Destinations": recipient,
            "Data": stringData
        }
        return message

        for part in mailobject.walk():
            ctype = part.get_content_type()
            cdispo = str(part.get('Content-Disposition'))

            # case for each common content type
            if ctype == 'text/plain' and 'attachment' not in cdispo:
                bodyPart = MIMEText(part.get_payload(decode=True), 'plain', part.get_content_charset())
                msg.attach(bodyPart)

            if ctype == 'text/html' and 'attachment' not in cdispo:
                mt = MIMEText(part.get_payload(decode=True), 'html', part.get_content_charset())
                email.encoders.encode_quopri(mt)
                del mt['Content-Transfer-Encoding']
                mt.add_header('Content-Transfer-Encoding', 'quoted-printable')
                msg.attach(mt)

            if 'attachment' in cdispo and 'image' in ctype:
                mi = MIMEImage(part.get_payload(decode=True), ctype.replace('image/', ''))
                del mi['Content-Type']
                del mi['Content-Disposition']
                mi.add_header('Content-Type', ctype)
                mi.add_header('Content-Disposition', cdispo)
                msg.attach(mi)

            if 'attachment' in cdispo and 'application' in ctype:
                ma = MIMEApplication(part.get_payload(decode=True), ctype.replace('application/', ''))
                del ma['Content-Type']
                del ma['Content-Disposition']
                ma.add_header('Content-Type', ctype)
                ma.add_header('Content-Disposition', cdispo)
                msg.attach(ma)


    # not multipart - i.e. plain text, no attachments, keeping fingers crossed
    else:
        body = MIMEText(mailobject.get_payload(decode=True), 'UTF-8')
        msg.attach(body)

    # The file name to use for the attached message. Uses regex to remove all
    # non-alphanumeric characters, and appends a file extension.
    filename = re.sub('[^0-9a-zA-Z]+', '_', subject_original)

    # Add subject, from and to lines.
    msg['Subject'] = subject
    msg['From'] = sender
    msg['To'] = recipient
    msg['reply-to'] = mailobject['Return-Path']

    # Create a new MIME object.
    att = MIMEApplication(file_dict["file"], filename)
    att.add_header("Content-Disposition", 'attachment', filename=filename)

    # Attach the file object to the message.
    msg.attach(att)
    message = {
        "Source": sender,
        "Destinations": recipient,
        "Data": msg.as_string()
    }
    return message

def send_email(message):
    aws_region = os.environ['Region']
# Create a new SES client.
    client_ses = boto3.client('ses', region)
    # Send the email.
    try:
        #Provide the contents of the email.
        response = client_ses.send_raw_email(
            Source=message['Source'],
            Destinations=[
                message['Destinations']
            ],
            RawMessage={
                'Data':message['Data']
            }
        )

    # Display an error if something goes wrong.
    except ClientError as e:
        print('send email ClientError Exception')
        output = e.response['Error']['Message']
    else:
        output = "Email sent! Message ID: " + response['MessageId']

    return output

def lambda_handler(event, context):
    # Get the unique ID of the message. This corresponds to the name of the file
    # in S3.
    message_id = event['Records'][0]['ses']['mail']['messageId']
    print(f"Received message ID {message_id}")

    # Retrieve the file from the S3 bucket.
    file_dict = get_message_from_s3(message_id)

    # Create the message.
    message = create_message(file_dict)

    # Send the email and print the result.
    result = send_email(message)
    print(result)
 类似资料:
  • 问题内容: 到目前为止,我一直尝试使用JavaMail api 创建类型的对象,然后获取其原始表示,但没有成功。我唯一可以获得的是电子邮件 内容 的原始表示形式,但是不包括标题,主题或收件人。我对可以帮助我创建电子邮件对象并获得其原始表示形式的任何建议,任何Java库感兴趣。原始表示应如下所示: 问题答案: 您正在寻找的是MimeMessag#writeTo,它将消息作为RFC 822格式流输出。

  • 我能够通过IMAP连接到Gmail并进行解析,但是在电子邮件正文中,我获得了Gmail特定的内容,例如

  • 我有Microsoft Exchange: 有办法做到这一点吗?要通读原始电子邮件信息,查看回复者是谁并转发到该电子邮件地址? 如果我们不能将其作为宏来完成,那么我们是否可以将发送到:mail@domain.com的所有邮件转发到脚本中,并让脚本处理解析呢?

  • 我能得到php mime电子邮件解析器/解码器的帮助吗https://code.google.com/p/php-mime-mail-parser/不涉及任何安装。我甚至试过phpclasses的Zend和decoder。org,但没有帮助。我找不到如何将输入输入程序并从中获取输出,因为没有这方面的教程 我的目标:我需要将mime邮件从输入流转换为可读文本 请帮帮忙

  • 问题内容: 看起来很容易 等通过 假设这是原始电子邮件字符串,看起来像这样。 问题 您如何通过python获取此电子邮件的? 到目前为止,这是我所知道的唯一代码,但我尚未对其进行测试。 这是正确的方法吗? 或者也许有一些更简单的事情,例如… ? 问题答案: 使用Message.get_payload

  • 问题内容: 我希望我的网站能够发送电子邮件而不刷新页面。所以我想使用Javascript。 这是我要调用的函数的方式,但是我不确定要在javascript函数中放入什么。通过研究,我发现了一个使用mailto方法的示例,但是我的理解是实际上并没有直接从站点发送邮件。 所以我的问题是,我在哪里可以找到要放在JavaScript函数中的内容,以便直接从网站发送电子邮件。 问题答案: 您不能直接使用ja