توضّح هذه المقالة كيفية إنشاء تطبيق App Engine بلغة Python يرسل رسائل إلكترونية مشروحة إلى المستخدمين ويطلب منهم تأكيد الاشتراك في قائمة بريدية مباشرةً من بريدهم الوارد، ويجمع الاشتراكات في Datastore.
المتطلبات الأساسية وإعداد المشروع
يفترض هذا الدليل أنّك ثبّت حزمة تطوير البرامج (SDK) الخاصة بـ App Engine وتعرف كيفية إنشاء مشاريع App Engine وتشغيلها ونشرها.
أولاً، أنشئ دليلًا لمشروعك. ضَع جميع ملفات تطبيقك في هذا الدليل.
انسخ الرمز التالي في ملف باسم app.yaml واستبدِل العنصر النائب {{ 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، واستبدال العنصر النائب 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)
يستمع الصف `SubscribeHandler` إلى طلبات class listens to bothPOSTandGETrequests sent to the app root url ( المرسَلة إلى عنوان URL الجذر للتطبيق (`https://APP-ID.appspot.com`). يستخدم Gmail طلبات ).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 الجذر للتطبيق لعرض الاشتراكات التي تم جمعها. يجلب معالج الطلب أولاً جميع الاشتراكات من Datastore ثم يعرضها في الصفحة، بالإضافة إلى عدّاد بسيط.
اختبار التطبيق
انشر تطبيقك على App Engine وانتقِل إلى https://APP-ID.appspot.com/email (استبدِل APP-ID برقم تعريف تطبيق App Engine) لإرسال الرسالة الإلكترونية المشروحة إلى نفسك.

بعد نشر تطبيقك وإدراج بعض الاشتراكات، انتقِل إلى تطبيقك على https://APP-ID.appspot.com للحصول على صفحة تلخّص الاشتراكات.