Ошибка «Имя или служба неизвестна», когда App Engine вызывает Amazon SES (Simple Email Service) - PullRequest
0 голосов
/ 04 ноября 2019

Иногда - не всегда - я получаю ошибку name or service not known при вызове Amazon SES из Google App Engine / Python 2.7.

Я вызываю пример кода Amazon, который я вставлю вконец этого вопроса, но он доступен здесь: https://docs.aws.amazon.com/ses/latest/DeveloperGuide/examples-send-using-smtp.html

Конечно, я ввожу свои учетные данные учетной записи Amazon и использую белый адрес электронной почты для отправки и действительный адрес для получения. Код работает безупречно, каждый раз, когда я запускаю его на моей настольной системе Python.

Вот обратная трассировка:

File "/base/data/home/apps/m~/1.4222/emailer_test.py", line 79, in <module>
    server = smtplib.SMTP(HOST, PORT)
  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/79cf/python27/python27_dist/lib/python2.7/smtplib.py", line 256, in __init__
    (code, msg) = self.connect(host, port)
  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/79cf/python27/python27_dist/lib/python2.7/smtplib.py", line 316, in connect
    self.sock = self._get_socket(host, port, self.timeout)
  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/79cf/python27/python27_dist/lib/python2.7/smtplib.py", line 291, in _get_socket
    return socket.create_connection((host, port), timeout)
  File "/base/alloc/tmpfs/dynamic_runtimes/python27g/79cf/python27/python27_dist/lib/python2.7/socket.py", line 560, in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
gaierror: [Errno -2] Name or service not known

Я не нашел ничего, что могло бы иногда вызывать сбой в App Engine, а не в других. Этот вопрос StackOverflow рассказывает о настройке брандмауэра для MailGun.

Java Google App Engine не будет отправлять электронную почту через Mailgun SMTP

Мне нужно включить биллинг для настройки брандмауэра, а я не хочуесли не нужно. Кроме того, почему это иногда работает, если это ошибка конфигурации брандмауэра?

Вот пример кода Amazon, адаптированный так, как я его использую. Кроме того, моя учетная запись SES находится в зоне Запад-2 (Орегон).

import smtplib  
import email.utils
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

# Replace sender@example.com with your "From" address. 
# This address must be verified.
SENDER = 'sender@example.com'  
SENDERNAME = 'Sender Name'

# Replace recipient@example.com with a "To" address. If your account 
# is still in the sandbox, this address must be verified.
RECIPIENT  = 'recipient@example.com'

# Replace smtp_username with your Amazon SES SMTP user name.
USERNAME_SMTP = "smtp_username"

# Replace smtp_password with your Amazon SES SMTP password.
PASSWORD_SMTP = "smtp_password"

# (Optional) the name of a configuration set to use for this message.
# If you comment out this line, you also need to remove or comment out
# the "X-SES-CONFIGURATION-SET:" header below.
CONFIGURATION_SET = "ConfigSet"

# If you're using Amazon SES in an AWS Region other than US West (Oregon), 
# replace email-smtp.us-west-2.amazonaws.com with the Amazon SES SMTP  
# endpoint in the appropriate region.
HOST = "email-smtp.us-west-2.amazonaws.com"
PORT = 587

# The subject line of the email.
SUBJECT = 'Amazon SES Test (Python smtplib)'

# The email body for recipients with non-HTML email clients.
BODY_TEXT = ("Amazon SES Test\r\n"
             "This email was sent through the Amazon SES SMTP "
             "Interface using the Python smtplib package."
            )
import time
# The HTML body of the email.
BODY_HTML = """<html>
<head></head>
<body>
  <h1>Amazon SES SMTP Email Test</h1>
  <p>This email was sent with Amazon SES using the
    <a href='https://www.python.org/'>Python</a>
    <a href='https://docs.python.org/3/library/smtplib.html'>
    smtplib</a> library at %s.</p>
</body>
</html>
            """ % time.asctime()

# Create message container - the correct MIME type is multipart/alternative.
msg = MIMEMultipart('alternative')
msg['Subject'] = SUBJECT
msg['From'] = email.utils.formataddr((SENDERNAME, SENDER))
msg['To'] = RECIPIENT
# Comment or delete the next line if you are not using a configuration set
#msg.add_header('X-SES-CONFIGURATION-SET',CONFIGURATION_SET)

# Record the MIME types of both parts - text/plain and text/html.
part1 = MIMEText(BODY_TEXT, 'plain')
part2 = MIMEText(BODY_HTML, 'html')

# Attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(part1)
msg.attach(part2)

# Try to send the message.
if 1: #try:  
    server = smtplib.SMTP(HOST, PORT)
    server.ehlo()
    server.starttls()
    #stmplib docs recommend calling ehlo() before & after starttls()
    server.ehlo()
    server.login(USERNAME_SMTP, PASSWORD_SMTP)
    server.sendmail(SENDER, RECIPIENT, msg.as_string())
    server.close()
# Display an error message if something goes wrong.
"""
except Exception as e:
    print ("Error: ", e)
else:
    print ("Email sent!")
"""

РЕДАКТИРОВАТЬ : кажется, что SMTP не совместим с AppEngine: Может ли Google App Engineиспользовать сторонний SMTP-сервер?

1 Ответ

0 голосов
/ 07 ноября 2019

Как вы упомянули, при попытке использовать внешнюю службу SMTP с использованием сокетов возникают некоторые проблемы. Мой совет - использовать Amazon SES API в качестве альтернативы.

Синтаксис запроса для python для отправки электронного письма будет выглядеть так:

response = client.send_email(
Source='string',
Destination={
    'ToAddresses': [
        'string',
    ],
    'CcAddresses': [
        'string',
    ],
    'BccAddresses': [
        'string',
    ]
},
Message={
    'Subject': {
        'Data': 'string',
        'Charset': 'string'
    },
    'Body': {
        'Text': {
            'Data': 'string',
            'Charset': 'string'
        },
        'Html': {
            'Data': 'string',
            'Charset': 'string'
        }
    }
},
ReplyToAddresses=[
    'string',
],
ReturnPath='string',
SourceArn='string',
ReturnPathArn='string',
Tags=[
    {
        'Name': 'string',
        'Value': 'string'
    },
],
ConfigurationSetName='string'
)

Пример дляотправка простого электронного письма:

import boto3

client = boto3.client(
    'ses',
    region_name=region,
    aws_access_key_id='aws_access_key_string',
    aws_secret_access_key='aws_secret_key_string'
)

    response = client.send_email(
    Destination={
        'ToAddresses': ['recipient1@domain.com', 'recipient2@domain.com],
    },
    Message={
        'Body': {
            'Text': {
                'Charset': 'UTF-8',
                'Data': 'email body string',
            },
        },
        'Subject': {
            'Charset': 'UTF-8',
            'Data': 'email subject string',
        },
    },
    Source='sender.email@domain.com',
)

Вот больше методов, которые вы можете использовать для SES API.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...