Как связать Сенгрида с Контактной формой в Flask для пересылки электронной почты

#python #email #flask #sendgrid

Вопрос:

Я пишу веб-приложение и пытаюсь использовать sendgrid для обработки служб доставки электронной почты.

Я пишу заявление в колбе.

Прямо сейчас у меня есть контактная форма, и моя проблема в том, что электронное письмо доставляется только в том случае, если я отправляю электронное письмо с моего предварительно утвержденного адреса электронной почты с помощью sendgrid. Очевидно, что это нехорошо, так как все остальные, кто заполняет форму электронной почты, не будут ее проходить.

Вот код, который у меня есть:

маршрут

 app.config['MAIL_SERVER'] = 'smtp.sendgrid.net'
app.config['MAIL_PORT'] = 587
app.config['MAIL_USE_TLS'] = True
app.config['MAIL_USERNAME'] = 'apikey'
app.config['MAIL_PASSWORD'] = os.environ.get('SENDGRID_API_KEY')
app.config['MAIL_DEFAULT_SENDER'] = os.environ.get('MAIL_DEFAULT_SENDER')


@app.route('/contact', methods=['GET', 'POST'])
def contactpage():
    if request.method == 'POST':
        print("Message sent")
        print(request.form.to_dict())
        m = message(request.form.to_dict())
        m.send()
    title = "Jonathan Bechtel contact form"
    description = "Contact Jonathan Bechtel with questions about teaching or working with him"
    return render_template("contact.html",
                            title=title,
                            description=description)
 

Вот мой код для фактической отправки электронного письма:

 import os
from sendgrid import SendGridAPIClient
from sendgrid.helpers.mail import Mail
class message():

    def __init__(self, message_data):
        for key in message_data:
            print(key, message_data[key])
            setattr(self, key, message_data[key])

    def send(self):
        message      = Mail(
        from_email   = self.email,
        to_emails    = 'jonathanbechtel@gmail.com',
        subject      = 'Sample Email Message',
        html_content = f'<strong>From: {self.email}</strong><br><strong>Reason: {self.reason}</strong><br><strong>Message:</strong>{self.message}')
        try:
            sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
            response = sg.send(message)
        except Exception as e:
            print(e)
 

Если я укажу from адрес в своей контактной форме на свой собственный, электронная почта будет работать нормально. Однако, если я использую любой другой, сообщение не проходит и генерирует 403 код состояния.

Я думаю, это означает, что я просто не использую правильную часть API, но не знаю, с чего начать.

Спасибо.

Ответ №1:

Евангелист-разработчик Twilio SendGrid здесь.

SendGrid не позволяет отправлять электронные письма только с любого адреса электронной почты. Я вижу, что в этом случае вы просто пытаетесь создать контактную форму, которая отправляет электронные письма только на ваш адрес электронной почты, поэтому возможность отправки с любого адреса электронной почты может быть полезной. Но подумайте о форме, которая позволяла пользователям задавать адреса «кому» и «от», и вы увидите, как этим можно злоупотреблять.

Вы можете прочитать больше об идентификации отправителя и SendGrid здесь.

В то же время, для вашего случая использования вот что я бы предложил.

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

Я полагаю, что вы можете задать ответ с mail reply_to помощью метода объекта:

     def send(self):
        message      = Mail(
        from_email   = APPROVED_SENDGRID_EMAIL,
        to_emails    = 'jonathanbechtel@gmail.com',
        subject      = 'Sample Email Message',
        html_content = f'<strong>From: {self.email}</strong><br><strong>Reason: {self.reason}</strong><br><strong>Message:</strong>{self.message}')

        # Set the reply-to email
        message.reply_to(self.email)

        try:
            sg = SendGridAPIClient(os.environ.get('SENDGRID_API_KEY'))
            response = sg.send(message)
        except Exception as e:
            print(e)
 

Более подробную информацию смотрите в примерах вспомогательной библиотеки.