במאמר הזה נסביר איך ליצור אפליקציית App Engine ב-Python ששולחת אימיילים עם הערות למשתמשים ומבקשת מהם לאשר את ההרשמה לרשימת התפוצה ישירות מתיבת הדואר הנכנס שלהם, ואוספת את ההרשמות ב-Datastore.
תנאים מוקדמים והגדרת הפרויקט
במדריך הזה אנו מביאים בחשבון שכבר התקנתם את App Engine SDK ואתם יודעים איך ליצור, להריץ ולפרסם פרויקטים ב-App Engine.
קודם יוצרים ספרייה לפרויקט. צריך להעביר את כל הקבצים של האפליקציה לספרייה הזו.
מעתיקים את הקוד הבא לקובץ בשם app.yaml
ומחליפים את placeholder {{ APPID }}
במזהה האפליקציה הייחודי שלכם ב-App Engine:
application: {{ APPID }}
version: 1
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
script: main.app
libraries:
- name: jinja2
version: latest
יוצרים קובץ בשם main.py
בתיקיית הפרויקט ב-App Engine ומעתיקים את הקוד הבא כדי להגדיר את הטיפולים לאיסוף ולרישום של מינויים, ולשליחת אימיילים עם הערות:
import webapp2
from emailsender import EmailSender
from subscribe import SubscribeHandler
app = webapp2.WSGIApplication([('/', SubscribeHandler), ('/email', EmailSender)], debug=True)
הוספת נתונים מובְנים לאימייל
נתחיל בהודעת אימייל פשוטה מאוד שבה המשתמש מתבקש לאשר את המינוי לרשימת תפוצה:
<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>
אפשר להוסיף נתונים מובְנים באחד מהפורמטים הנתמכים (JSON-LD או מיקרו-נתונים) אל head
של האימייל כדי להגדיר את המסעדה ולהוסיף OneClickAction. Gmail תומך ב-OneClickAction
ומציג למשתמשים ממשק משתמש ספציפי כדי לאפשר להם לאשר את המינוי מתיבת הדואר הנכנס.
מעתיקים את הרכיב הבא לקובץ בשם 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>
מיקרו נתונים
<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>
הנתונים המובְנים שלמעלה מתארים רשימת תפוצה בשם 'XYZ' ו-ConfirmAction
. הטיפול בפעולה הוא HttpActionHandler
ששולח בקשות POST לכתובת ה-URL שצוינה בנכס url
.
שליחת בקשות להרשמה למשתמשים
מעתיקים את הקוד הבא לקובץ בשם emailsender.py
בתיקיית הפרויקט ב-App Engine:
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)
בכיתה EmailSender
, המשתמש צריך להיות מחובר כדי שאפשר יהיה לאחזר את כתובת האימייל שלו. לאחר מכן, המערכת טוענת את תוכן האימייל מ-mail_template.html
, מחליפה את placeholder confirm_url
בו בכתובת ה-URL ברמה הבסיסית של אפליקציית App Engine (https://APP-ID.appspot.com
) ושולחת את האימייל למשתמש שמחובר כרגע לחשבון שלו.
איסוף מינויים והצגתם ברשימה
מעתיקים את הקוד הבא לקובץ בשם subscribe.py
בתיקיית הפרויקט ב-App Engine:
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)
הפרמטר 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` שתואם למשתמש, כמו בדוגמה הבאה:
https://subscribe.appspot.com/?user_id=123abcd
בורר הבקשות פשוט בודק שה-user_id הנדרש מוגדר, ולאחר מכן מאחסן את המינוי ב-Datastore. כתוצאה מכך, קוד התגובה HTTP 200
יישלח חזרה ל-Gmail כדי לסמן שהבקשה בוצעה בהצלחה. אם הבקשה לא כוללת את השדה הנדרש, בורר הבקשות יחזיר קוד תגובה HTTP 400
, שמציין שהבקשה לא חוקית.
בקשות GET
לכתובת ה-URL ברמה הבסיסית של האפליקציה משמשות כדי לרשום את המינויים שנאספו. תחילה, בורר הבקשות מאחזר את כל המינויים ממאגר הנתונים, ואז מדפיס אותם בדף יחד עם מונה פשוט.
בדיקת האפליקציה
פורסים את האפליקציה ב-App Engine ונכנסים לכתובת https://APP-ID.appspot.com/email
(מחליפים את APP-ID
במזהה האפליקציה ב-App Engine) כדי לשלוח לעצמכם את האימייל עם ההערות.
אחרי שפורסים את האפליקציה ומוסיפים כמה מינויים, אפשר להיכנס לאפליקציה בכתובת https://APP-ID.appspot.com
כדי לראות דף עם סיכום של המינויים.