用于Python的AWS Lambda发送带附件的电子邮件

时间:2017-12-17 14:41:23

标签: python aws-lambda email-attachments

我创建了静态网站,我打算在S3存储桶中托管。此HTML具有表单和附件功能,当用户附加文件并点击“上传”时,该功能将发送到我的电子邮件ID。以下是我的HTML代码段 -

<form enctype="multipart/form-data"  name="fileinfo">
            <label>Your email address:</label>
            <input id = "email "type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br />
            <label>Custom file label:</label>
            <input type="text" name="filelabel" size="12" maxlength="32" /><br />
            <label>File to stash:</label>
            <input type="file" name="file" id = "fileUpload" required />
             <input type="button" id = "upload" value="Upload!" />
        </form>​

然后Jquery触发对AWS API网关的POST请求

$('#upload').on("click", function (){
  var oOutput = document.querySelector("div"),
      oData = new FormData(form);

    var xhttp = new XMLHttpRequest();

    xhttp.onreadystatechange = function() {
          if (this.readyState == 4 && this.status == 200) {
            // Typical action to be performed when the document is ready:
             console.log(xhttp.responseText);
            console.log(xhttp.statusText);
            console.log(xhttp.status);
            oOutput.innerHTML = xhttp.responseText;
            } else {
                oOutput.innerHTML = "Error " + xhttp.status + " occurred when trying to upload your file.<br \/>";
            }
          };

    xhttp.open("POST", "https://myLambdaAPIURL", true);
    xhttp.setRequestHeader("Content-type", "application/json;charset=UTF-8");
    xhttp.send(JSON.stringify({Email:$('#email').val(),fileUpload:$('#fileUpload').val()}));

AWS中的API网关具有处理json格式的所有默认配置。

我的AWS lambda代码可以正常发送电子邮件。

import smtplib , os
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.application import MIMEApplication
from email.mime.base import MIMEBase
from email.message import Message
from email.encoders import encode_base64
from email.mime.text import MIMEText
from mimetypes import guess_type


def lambda_handler(event, context):
    msg = MIMEMultipart()
    msg['Subject'] = 'File Uploaded'
    msg['From'] = 'user@gmail.com'
    msg['To'] = 'user@gmail.com'
    emailFrom = "user@gmail.com"
    emailTo ="user@gmail.com"

    for file in event['fileUpload']:
        mimetype, encoding = guess_type(file)
        if mimetype == None:
            mimetype = "text/plain"
        mimetype = mimetype.split('/',1)    
        fp = open(file, "rb")       
        attachment.set_payload(fp.read())
        fp.close()
        encode_base64(attachment)
        attachment.add_header('Content-Disposition', 'attachment', file=os.path.basename(file))
        msg.attach(attachment)
    s = smtplib.SMTP('smtp.gmail.com:587')
    s.starttls()
    s.login('user@gmail.com','password')
    response = s.sendmail(emailFrom, emailTo, msg.as_string())
    s.quit()

return response

但是当我附加一个文件并尝试处理它时,假路径错误就会出现

  

{“stackTrace”:[[“/ var /task / pyLambda.py”,24,“lambda_handler”,“fo = open(filename,\”rb \“)”]],“errorType”:“IOError “,”errorMessage“:”[Errno 2]没有这样的文件或目录:u'C:\\ fakepath \\ testing.txt'“}

所以我想我可以在AWS lambda中使用\ tmp目录,但不知道该怎么做。

非常感谢任何帮助或任何指导。

2 个答案:

答案 0 :(得分:0)

您正在做的是向您的AWS Lambda函数提交POST - 请求,其中包含要上传的文件的文件名。在AWS Lambda端,然后尝试打开具有该名称的文件。

您收到错误消息,因为文件名是相对于发送表单的用户的计算机而且AWS Lambda根本不知道该文件的路径。

您可能想要做的是更改您的Javascript代码,以便将文件内容(编码为base64)放入请求的JSON主体中,并在AWS Lambda函数中读取该数据。然后,您不再需要在AWS Lambda端读取物理文件,而只需从请求中获取文件内容。

如何使用Javascript上传文件内容还包括其他问题,例如:JavaScript: Upload file

答案 1 :(得分:0)

import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from smtplib import SMTPException
import base64
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from operator import itemgetter
import json
import boto3
from smtplib import SMTPException
from email import encoders

def lambda_handler(event, context):
    msg = MIMEMultipart()
    email = event['from'] 
    password =event['password'] 
    msg['Subject'] = event["subject"]
    you = event["to"]
    body = event["message"]
    msg['From']=email
    msg['To']= ", ".join(you)
    if len(you) ==0 or email=="":
        return {
        'status': 'False',
       'statusCode': 400,
       'message': 'Email not sent, From or To cannot be blank'
      }
    msg.attach(MIMEText(body, 'plain'))
    if(len(event['files'])==len(event['attach_base64'])):
        for i in range(len(event['attach_base64'])):
            filename = event['files'][i]
            data = event['attach_base64'][i]
            data1 = data
            attach_file = base64.b64decode(data1)
            #msg.attach(MIMEText(body, "plain"))
            part = MIMEBase('application', 'octet-stream')
            part.set_payload(attach_file)
            #part.set_payload(attach_file)
            encoders.encode_base64(part)
             #encoders.encode_base64(part)

            part.add_header(
                    "Content-Disposition",
                    "decoded_data; filename=%s" % filename)
            msg.attach(part)
    else:
        return {
        'status': 'False',
       'statusCode': 400,
       'message': 'Missing filename OR base64 of some file'
      }

    if event["message"] =="" and event["subject"] =="" and len(event['files'])==0 and len(event['attach_base64'])==0 :
        return {
        'status': 'False',
       'statusCode': 400,
       'message': 'Email cannot be blank'
      }

    try:
        smtpObj = smtplib.SMTP(host='smtp.gmail.com', port=587)
        smtpObj.starttls()
        smtpObj.login(email,password)
        smtpObj.sendmail(email, you, msg.as_string())
        print("in try --------------------------------------->")
        smtpObj.quit()
    except smtplib.SMTPException as e:
        print ("Error: unable to send email due to",e)
        error_msg = "Error: unable to send email due to "
        error_msg = error_msg + str(e)
        return {
        'status': 'False',
       'statusCode': 417,
       'body': error_msg
      }

    return {
        'status': 'True',
       'statusCode': 400,
       'message': 'Email Successfully Sent'
      }