API Mail per Python

In questa pagina viene descritto come utilizzare l'API Mail, uno dei servizi in bundle legacy, con il runtime Python dell'ambiente standard. La tua app può accedere ai servizi in bundle tramite l'SDK dei servizi App Engine per Python.

Panoramica

In Python, la funzionalità di gestione della posta è inclusa nel google.appengine.api.mail. Questo è diverso da Python 2, in cui il modulo mail_handlers è stato fornito dall'app web. The Mail L'API per Python può essere utilizzata per ricevere email e notifiche di mancato recapito.

Utilizzo dell'API Mail

La tua app riceve email quando viene inviata un'email come corpo della richiesta in un POST HTTP richiesta. Affinché l'app possa gestire le email in arrivo, l'app deve corrispondere all'URL con il percorso /_ah/mail/[ADDRESS]. La parte [ADDRESS] di di solito il percorso è un indirizzo email con il suffisso @<Cloud-Project-ID>.appspotmail.com. Email inviate all'app in questo formato verrà indirizzato alla funzione.

Python non richiede all'app di specificare uno script gestore nel app.yaml del file, in modo da poter rimuovere tutte le sezioni handler in app.yaml.

Il file app.yaml deve contenere le seguenti righe:

inbound_services:
- mail
- mail_bounce

Invio di messaggi

Non è necessario apportare modifiche alla configurazione dell'app quando esegui l'upgrade a come Python. Comportamento, funzioni e istruzioni di configurazione per l'invio della posta rimane la stessa. Per ulteriori dettagli, consulta le seguenti guide:

Ricezione di messaggi

Per ricevere la posta, devi importare il modulo google.appengine.api.mail e utilizza la classe InboundEmailMessage per rappresentare un'email. Questo corso deve creare un'istanza per recuperare i contenuti dell'email dalla richiesta HTTP in entrata.

In precedenza, in Python 2, le app potevano accedere alla classe InboundEmailMessage tramite eseguendo l'override del metodo receive() nel gestore di app web InboundEmailHandler. Questa operazione non è necessaria in Python. l'app deve creare un'istanza per un nuovo oggetto.

Framework web

Quando utilizzi i framework web Python, il costruttore InboundEmailMessage accetta i byte del corpo della richiesta HTTP. Esistono diversi modi per creare InboundEmailMessage in Python. Di seguito sono riportati alcuni esempi di Flask e Djago:

Python 3 (Flask)

In Flask, request.get_data() fornisce i byte della richiesta.

@app.route("/_ah/bounce", methods=["POST"])
def receive_bounce():
    bounce_message = mail.BounceNotification(dict(request.form.lists()))

    # Do something with the message
    print("Bounce original: ", bounce_message.original)
    print("Bounce notification: ", bounce_message.notification)

    return "OK", 200

Python 3 (Django)

In Django, request.body fornisce i byte del corpo della richiesta HTTP.

def receive_mail(request):
    message = mail.InboundEmailMessage(request.body)

    print(f"Received greeting for {message.to} at {message.date} from {message.sender}")
    for _, payload in message.bodies("text/plain"):
        print(f"Text/plain body: {payload.decode()}")
        break

    return HttpResponse("OK")

Per visualizzare gli esempi di codice completi di questa guida, consulta GitHub.

Altri framework conformi a WSGI

Per altri framework conformi a WSGI, consigliamo di utilizzare lo stesso metodo del Esempi di Flask e Django per creare InboundEmailMessage. Questo metodo funziona quando i byte del corpo della richiesta HTTP sono direttamente disponibili.

App WSGI senza framework web

Se la tua app è un'app WSGI che non utilizza un framework web, è possibile che i byte del corpo della richiesta HTTP non sono direttamente disponibili. Se i byte di del corpo della richiesta HTTP sono disponibili direttamente, ti consigliamo di utilizzare una framework web.

In Python, viene definito un metodo di fabbrica denominato from_environ InboundEmailMessage. Si tratta di un metodo della classe che utilizza Dizionario WSGI environ come input e può essere utilizzato per qualsiasi applicazione WSGI.

Nell'esempio seguente, osserva come environ viene preso come input per ottenere mail_message:

Python 3 (app WSGI)

def HelloReceiver(environ, start_response):
    if environ["REQUEST_METHOD"] != "POST":
        return ("", http.HTTPStatus.METHOD_NOT_ALLOWED, [("Allow", "POST")])

    message = mail.InboundEmailMessage.from_environ(environ)

    print(f"Received greeting for {message.to} at {message.date} from {message.sender}")
    for content_type, payload in message.bodies("text/plain"):
        print(f"Text/plain body: {payload.decode()}")
        break

    response = http.HTTPStatus.OK
    start_response(f"{response.value} {response.phrase}", [])
    return ["success".encode("utf-8")]

Ricezione di notifiche di mancato recapito

Una notifica di mancato recapito è un messaggio automatico proveniente da un sistema email che indica un problema di recapito dei messaggi dell'app. Per elaborare il rimbalzo notifiche, la tua app deve corrispondere ai percorsi degli URL in arrivo con /_ah/bounce del tuo percorso di apprendimento.

Come InboundEmailMessage, la classe BounceNotification per Python 2 era accessibile eseguendo l'override del metodo receive() nel gestore dell'app web BounceNotificationHandler.

In Python, l'app deve creare un'istanza dell'oggetto BounceNotification, che possono essere creati in diversi modi a seconda del framework web Python utilizzato.

Framework web

L'oggetto BounceNotification è inizializzato con i valori che sono recuperata chiamando post_vars.get(key).

Quando utilizzi un framework web Python come Flask o Django, il metodo Il costruttore BounceNotification utilizza un dizionario denominato post_vars, che contiene la richiesta POST dei dati del modulo. Per recuperare i dati, il metodo get() deve essere definito nell'oggetto di input. key è un elenco di input valori che possono essere letti e recuperati da BounceNotification e possono essere uno qualsiasi di le seguenti:

original-to, original-cc, original-bcc, original-subject, original-text, notification-from, notification-to, notification-cc, notification-bcc, notification-subject, notification-text, raw-message

Nella maggior parte dei framework web, questi dati sono disponibili come dizionari multipli nel di richiesta di addestramento. La maggior parte di questi tipi può essere convertita in un dizionario basato su caratteri stringhe.

Per tutte le chiavi tranne raw-message, il valore può essere qualsiasi cosa. Di solito, il valore è un singolo valore come una stringa o un elenco di valori, come {'to': ['bob@example.com', 'alice@example.com']}. Il valore predefinito per tutti i campi è una stringa vuota. Questi valori verranno inseriti nei campi original e notification proprietà.

Per la chiave raw-message, il valore deve essere un input valido per il costruttore di EmailMessage Può essere un valore singolo o un elenco a valore singolo. La chiave raw-message viene utilizzato per inizializzare la proprietà original_raw_message dell'oggetto.

Python 2 (webapp2)

class LogBounceHandler(BounceNotificationHandler):
    def receive(self, bounce_message):
        logging.info('Received bounce post ... [%s]', self.request)
        logging.info('Bounce original: %s', bounce_message.original)
        logging.info('Bounce notification: %s', bounce_message.notification)

Python 3 (Flask)

In Flask, request.form di tipo werkzeug.datastructures.MultiDict fornisce le variabili POST. Tuttavia, il metodo get() per questo tipo restituisce solo anche se sono presenti più valori per la chiave.

Per ottenere tutti i valori corrispondenti a una chiave, l'app deve chiamare dict(request.form.lists()), il che genera un dizionario in cui ogni valore è un elenco.

@app.route("/_ah/bounce", methods=["POST"])
def receive_bounce():
    bounce_message = mail.BounceNotification(dict(request.form.lists()))

    # Do something with the message
    print("Bounce original: ", bounce_message.original)
    print("Bounce notification: ", bounce_message.notification)

    return "OK", 200

Python 3 (Django)

In Django, request.POST di tipo django.http.QueryDict fornisce le variabili POST. Tuttavia, il metodo get() per questo tipo restituisce solo anche se sono presenti più valori per la chiave.

Per ottenere tutti i valori corrispondenti a una chiave, l'app deve chiamare dict(request.POST.lists()), il che genera un dizionario in cui ogni valore è un elenco.

def receive_bounce(request):
    bounce_message = mail.BounceNotification(dict(request.POST.lists()))

    # Do something with the message
    print(f"Bounce original: {bounce_message.original}")
    print(f"Bounce notification: {bounce_message.notification}")

    return HttpResponse("OK")

App WSGI senza framework web

Se la tua app è un'app WSGI che non utilizza un framework web, è possibile che le variabili di forma della richiesta POST HTTP non sono disponibili direttamente in un dizionario.

In Python, viene definito un metodo di fabbrica denominato from_environ BounceNotification. Si tratta di un metodo delle classi che utilizza il metodo WSGI dizionario environ come input e può essere utilizzato per qualsiasi applicazione WSGI.

Nell'esempio seguente, osserva come environ viene preso come input per ottenere bounce_message:

Python 3

def BounceReceiver(environ, start_response):
    if environ["REQUEST_METHOD"] != "POST":
        return ("", http.HTTPStatus.METHOD_NOT_ALLOWED, [("Allow", "POST")])

    bounce_message = mail.BounceNotification.from_environ(environ)

    # Do something with the message
    print("Bounce original: ", bounce_message.original)
    print("Bounce notification: ", bounce_message.notification)

    # Return suitable response
    response = http.HTTPStatus.OK
    start_response(f"{response.value} {response.phrase}", [])
    return ["success".encode("utf-8")]

Esempi di codice

Per visualizzare gli esempi di codice completi di questa guida, consulta GitHub.