Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

amazon web services - extract email attachment from AWS SES mail in S3 with Python on AWS Lambda

I want to build a basic email attachment processor on AWS. I followed this example (https://medium.com/caspertechteam/processing-email-attachments-with-aws-a35a1411a0c4), got everything on AWS talking to each other (SES, S3, Lambda).

I can read the content of a plain email (text only). Now, I switch to messages with attachments. I have this code (in AWS Lambda, Python 3.8)

import boto3
import email 

def lambda_handler(event, context):
    s3 = boto3.resource('s3')
    
    bucket = 'myBucket'
    key = 'inbound/cl2kjuud8oaqm6ihac491hs5s404krv6nkpq7781' # with csv attachment
    # key = 'inbound/kvqlcdlaqaqhq8i5a3m51nsr8ehehhsl227hu881' # no att
    
    obj = s3.Bucket(bucket).Object(key)
    body = obj.get()["Body"].read().decode('utf-8') # decode necessary, or error message
    
    msg = email.message_from_string(body)
    
    attachment = get_attachment(msg, 'text/plain')
    
# this code is copy&paste from tutorial above
def get_attachment(msg, content_type):
    """
    Moves through a tree of email Messages to find an attachment.
    :param msg: An email Message object containing an attachment in its Message tree
    :param content_type: The type of attachment that is being searched for
    :return: An email Message object containing base64 encoded contents (i.e. the attachment)
    """
    attachment = None
    msg_content_type = msg.get_content_type()

    if ((msg_content_type == content_type or msg_content_type == 'text/plain')
            and is_base64(msg.get_payload())):
        attachment = msg

    elif msg_content_type.startswith('multipart/'):
        for part in msg.get_payload():
            attachment = get_attachment(part, content_type)
            attachment_content_type = attachment.get_content_type()

            if (attachment and (attachment_content_type == content_type
                                or attachment_content_type == 'text/plain')
                    and is_base64(attachment.get_payload())):
                break
            else:
                attachment = None

    return attachment

I get this error

Response:
{
  "errorMessage": "'NoneType' object has no attribute 'get_content_type'",
  "errorType": "AttributeError",
  "stackTrace": [
    "  File "/var/task/lambda_function.py", line 24, in lambda_handler
    attachment = get_attachment(msg, 'text/plain')
",
    "  File "/var/task/lambda_function.py", line 58, in get_attachment
    attachment_content_type = attachment.get_content_type()
"
  ]
}

I tried it with Python 2.8 runtime, played with message_from_bytes(), nothing seems to work. Now I'm stuck. Can you share some advice?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...