In diesem Artikel erfahren Sie, wie Sie eine App Engine-Anwendung in Python erstellen, die E-Mails mit Anmerkungen an Nutzer sendet, die das Abonnement einer Mailingliste direkt aus ihrem Posteingang bestätigen müssen, und die Abonnements im Datenspeicher abruft.
Voraussetzungen und Projekteinrichtung
In diesem Leitfaden wird davon ausgegangen, dass Sie das App Engine SDK bereits installiert haben und wissen, wie App Engine-Projekte erstellt, ausgeführt und veröffentlicht werden.
Erstellen Sie zuerst ein Verzeichnis für Ihr Projekt. Legen Sie alle Dateien für Ihre Anwendung in diesem Verzeichnis ab.
Kopieren Sie den folgenden Code in eine Datei mit dem Namen app.yaml
und ersetzen Sie den Platzhalter {{ APPID }}
durch Ihre eindeutige App Engine-Anwendungs-ID:
application: {{ APPID }}
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
Erstellen Sie in Ihrem App Engine-Projektordner eine Datei mit dem Namen main.py
und kopieren Sie den folgenden Code, um die Handler zum Erfassen und Auflisten von Abos sowie zum Senden von E-Mails mit Anmerkungen einzurichten:
import webapp2
from emailsender import EmailSender
from subscribe import SubscribeHandler
app = webapp2.WSGIApplication([('/', SubscribeHandler), ('/email', EmailSender)], debug=True)
Der E-Mail strukturierte Daten hinzufügen
Beginnen wir mit einer sehr einfachen E-Mail, in der der Nutzer aufgefordert wird, das Abonnement einer Mailingliste zu bestätigen:
<html>
<head>
<title>Please confirm your subscription to Mailing-List XYZ?</title>
</head>
<body>
<p>
Dear John, please confirm that you wish to be subscribed to the
mailing list XYZ
</p>
</body>
</html>
Du kannst strukturierte Daten in einem der unterstützten Formate (JSON-LD oder Mikrodaten) zum head
der E-Mail hinzufügen, um das Restaurant zu definieren und eine OneClickAction hinzuzufügen. Gmail unterstützt die OneClickAction
und zeigt Nutzern eine spezielle Benutzeroberfläche, über die sie ihr Abo über ihren Posteingang bestätigen können.
Kopieren Sie das folgende Markup in eine Datei mit dem Namen mail_template.html
:
JSON-LD
<html>
<head>
<title>Please confirm your subscription to Mailing-List XYZ?</title>
</head>
<body>
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "EmailMessage",
"potentialAction": {
"@type": "ConfirmAction",
"name": "Confirm Subscription",
"handler": {
"@type": "HttpActionHandler",
"url": "{{ confirm_url }}",
"method": "http://schema.org/HttpRequestMethod/POST",
}
},
"description": "Confirm subscription to mailing list XYZ"
}
</script>
<p>
Dear John, please confirm that you wish to be subscribed to the mailing list XYZ.
</p>
</body>
</html>
Mikrodaten
<html>
<head>
<title>Please confirm your subscription to Mailing-List XYZ?</title>
</head>
<body>
<div itemscope itemtype="http://schema.org/EmailMessage">
<div itemprop="potentialAction" itemscope itemtype="http://schema.org/ConfirmAction">
<meta itemprop="name" content="Approve Expense"/>
<div itemprop="handler" itemscope itemtype="http://schema.org/HttpActionHandler">
<link itemprop="url" href="https://myexpenses.com/approve?expenseId=abc123"/>
<meta itemprop="url" content="{{ confirm_url }}"/>
<link itemprop="method" href="http://schema.org/HttpRequestMethod/POST"/>
</div>
</div>
<meta itemprop="description" content="Approval request for John's $10.13 expense for office supplies"/>
</div>
<p>
Dear John, please confirm that you wish to be subscribed to the mailing list XYZ.
</p>
</body>
</html>
Die oben aufgeführten strukturierten Daten beschreiben eine Mailingliste namens „XYZ“ und ConfirmAction
. Der Handler für die Aktion ist ein HttpActionHandler
, der POST-Anfragen an die in der Eigenschaft url
angegebene URL sendet.
Aboanfragen an Nutzer senden
Kopieren Sie den folgenden Code in eine Datei mit dem Namen emailsender.py
im App Engine-Projektordner:
import jinja2
import os
import webapp2
from google.appengine.api import mail
from google.appengine.api import users
from urlparse import urlparse
class EmailSender(webapp2.RequestHandler):
def get(self):
# require users to be logged in to send emails
user = users.get_current_user()
if not user:
self.redirect(users.create_login_url(self.request.uri))
return
email = user.email()
# The confirm url corresponds to the App Engine app url
pr = urlparse(self.request.url)
confirm_url = '%s://%s?user=%s' % (pr.scheme, pr.netloc, user.user_id())
# load the email template and replace the placeholder with the confirm url
jinja_environment = jinja2.Environment(
loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
template = jinja_environment.get_template('mail_template.html')
email_body = template.render({'confirm_url': confirm_url})
message = mail.EmailMessage(
sender = email,
to = email,
subject = 'Please confirm your subscription to Mailing-List XYZ',
html = email_body)
try:
message.send()
self.response.write('OK')
except:
self.error(500)
Für die Klasse EmailSender
muss der Nutzer angemeldet sein, damit seine E-Mail-Adresse abgerufen werden kann. Anschließend wird der E-Mail-Text aus mail_template.html
geladen, der Platzhalter confirm_url
darin durch die Stamm-URL der App Engine-Anwendung (https://APP-ID.appspot.com
) ersetzt und die E-Mail an den aktuell angemeldeten Nutzer als sich selbst gesendet.
Abonnements erfassen und auflisten
Kopieren Sie den folgenden Code in eine Datei mit dem Namen subscribe.py
im App Engine-Projektordner:
import webapp2
from emailsender import EmailSender
from google.appengine.ext import db
class SubscribeHandler(webapp2.RequestHandler):
def post(self):
user_id = self.request.get('user')
# insert the subscription into the Datastore
subscription = Subscription(user_id=user_id)
subscription.put()
def get(self):
# retrieve up to 1000 subscriptions from the Datastore
subscriptions = Subscription.all().fetch(1000)
if not subscriptions:
self.response.write('No subscriptions')
return
count = len(subscriptions)
for s in subscriptions:
self.response.write('%s subscribed<br/>' % (s.user_id))
self.response.write('<br/>')
self.response.write('%d subscriptions.' % (count))
class Subscription(db.Model):
user_id = db.TextProperty(required=True)
Der SubscribeHandlerclass listens to both
POSTand
GETrequests sent to the app root url (
https://APP-ID.appspot.com).
POSTrequests are used by Gmail to insert new subscriptions including the
user_id`-Parameter, der dem Nutzer entspricht, wie im folgenden Beispiel:
https://subscribe.appspot.com/?user_id=123abcd
Der Anfrage-Handler prüft einfach, ob die erforderliche user_id definiert ist, und speichert das Abo dann im Datenspeicher. Dies führt dazu, dass ein HTTP 200
-Antwortcode an Gmail zurückgesendet wird, um die erfolgreiche Anfrage zu signalisieren. Falls die Anfrage das erforderliche Feld nicht enthält, gibt der Anfrage-Handler einen HTTP 400
-Antwortcode zurück, der die ungültige Anfrage signalisiert.
GET
-Anfragen an die Stamm-URL der App werden verwendet, um die erfassten Abos aufzulisten. Der Anfrage-Handler ruft zuerst alle Abos aus dem Datenspeicher ab und gibt sie zusammen mit einem einfachen Zähler auf der Seite aus.
Anwendung testen
Stellen Sie Ihre Anwendung in App Engine bereit und rufen Sie https://APP-ID.appspot.com/email
auf (ersetzen Sie APP-ID
durch Ihre App Engine-App-ID), um die mit Anmerkungen versehene E-Mail an sich selbst zu senden.
Nachdem Sie Ihre App bereitgestellt und einige Abos eingefügt haben, rufen Sie Ihre App unter https://APP-ID.appspot.com
auf. Sie erhalten dann eine Seite mit einer Zusammenfassung der Abos.