Не удалось подключиться к SMTP-почте AWS Lambda

#python #docker #aws-lambda #gmail #smtplib

Вопрос:

Я пытаюсь отправить электронное письмо из контейнера python, работающего на AWS lambda. Он отлично работает, когда я тестирую локально свой Лямбда-контейнер. Но как только я попробую то же самое на AWS Lambda, произойдет сбой со следующей обратной трассировкой:

Возврат функции

{ "errorMessage": "can only concatenate str (not "bytes") to str", "errorType": "TypeError", "stackTrace": [ " File "/var/lang/lib/python3.8/imp.py", line 234, in load_modulen return load_source(name, filename, file)n", " File "/var/lang/lib/python3.8/imp.py", line 171, in load_sourcen module = _load(spec)n", " File "<frozen importlib._bootstrap>", line 702, in _loadn", " File "<frozen importlib._bootstrap>", line 671, in _load_unlockedn", " File "<frozen importlib._bootstrap_external>", line 848, in exec_modulen", " File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removedn", " File "/var/task/app.py", line 65, in <module>n handler(None, None)n", " File "/var/task/app.py", line 62, in handlern __send_email(msg)n", " File "/var/task/app.py", line 22, in __send_emailn server.login(gmail_user, gmail_password)n", " File "/var/lang/lib/python3.8/smtplib.py", line 732, in loginn (code, resp) = self.auth(n", " File "/var/lang/lib/python3.8/smtplib.py", line 635, in authn (code, resp) = self.docmd("AUTH", mechanism " " response)n" ] }

Вывод журнала:

 [ERROR] TypeError: can only concatenate str (not "bytes") to str
Traceback (most recent call last):
  File "/var/lang/lib/python3.8/imp.py", line 234, in load_module
    return load_source(name, filename, file)
  File "/var/lang/lib/python3.8/imp.py", line 171, in load_source
    module = _load(spec)
  File "<frozen importlib._bootstrap>", line 702, in _load
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 848, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/var/task/app.py", line 65, in <module>
    handler(None, None)
  File "/var/task/app.py", line 62, in handler
    __send_email(msg)
  File "/var/task/app.py", line 22, in __send_email
    server.login(gmail_user, gmail_password)
  File "/var/lang/lib/python3.8/smtplib.py", line 732, in login
    (code, resp) = self.auth(
  File "/var/lang/lib/python3.8/smtplib.py", line 635, in auth
    (code, resp) = self.docmd("AUTH", mechanism   " "   response)
 

Код

 def __send_email(msg:str) -> None:
    gmail_user = os.getenv('EMAIL_USER')
    gmail_password = os.getenv('EMAIL_PASSWORD')

    # Create Email
    mail_from = gmail_user
    mail_to = gmail_user
    mail_subject = f'DB Update today {datetime.today().strftime("%m/%d/%Y")}'
    mail_message = f'Subject: {mail_subject}nn{msg}'

    # Send Email
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login(gmail_user, gmail_password)

    server.sendmail(mail_from, mail_to, mail_message)
    server.close()
 

Другие переменные env работают хорошо, поэтому я не думаю, что проблема исходит отсюда.

Я использую следующий образ докера : public.ecr.aws/лямбда/python:3.8.

Спасибо вам за вашу помощь!

Ответ №1:

Я проверил вашу функцию, как она работает, и она сработала:

 import os
from datetime import datetime

os.environ["EMAIL_USER"] = "<test_email>"
os.environ["EMAIL_PASSWORD"] = "<test password>"

def __send_email(msg:str) -> None:
    gmail_user = os.getenv('EMAIL_USER')
    gmail_password = os.getenv('EMAIL_PASSWORD')

    # Create Email
    mail_from = gmail_user
    mail_to = gmail_user
    mail_subject = f'DB Update today {datetime.today().strftime("%m/%d/%Y")}'
    mail_message = f'Subject: {mail_subject}nn{msg}'

    # Send Email
    server = smtplib.SMTP('smtp.gmail.com', 587)
    server.starttls()
    server.login(gmail_user, gmail_password)

    server.sendmail(mail_from, mail_to, mail_message)
    server.close()


__send_email("hello world")
 

Кроме того, я посмотрел на одну из своих лямбд, и вот как я отправляю электронные письма с помощью SMTP:

 import smtplib

smtp_server = "smtp.gmail.com"
smtp_port = 465
smtp_username = "<test_email>"
smtp_passwword = "<test password>"
send_to = "<send_to_email_address>"
send_from = "<send_from_email_address>"
message_to_send = "hello world"


def send_email(msg):
    server = smtplib.SMTP_SSL(smtp_server, smtp_port)
    server.login(smtp_username, smtp_passwword)
    message = f"""From: {send_to}
To: {send_to}
Subject: Test message

{msg}."""
    server.sendmail(send_from, send_to, message)
    server.quit()


send_email(message_to_send)
 

Можете ли вы проверить переменные env для имени пользователя и пароля и посмотреть, правильно ли они переданы.

Комментарии:

1. Спасибо за ваш ответ. Я дважды проверил все свои переменные и только что понял, что забыл обновить файл CI/CD .yaml… Он должен правильно работать с этим обновленным. Еще раз спасибо!