يوضّح هذا المستند كيفية إنشاء تطبيق 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="Confirm Subscription"/>
<div itemprop="handler" itemscope itemtype="http://schema.org/HttpActionHandler">
<meta itemprop="url" content="{{ confirm_url }}"/>
<link itemprop="method" href="http://schema.org/HttpRequestMethod/POST"/>
</div>
</div>
<meta itemprop="description" content="Confirm subscription to mailing list XYZ"/>
</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.
ملاحظة مهمة: في الرمز السابق، استبدِل العنصر النائب
{{ confirm_url }}
بعنوان URL لتطبيق App Engine (مثل
https://mailing-list.appspot.com) قبل إرسال أي رسائل إلكترونية. تتعامل التعليمات البرمجية الموضّحة في الخطوات التالية مع عملية الاستبدال هذه.
إرسال طلبات الاشتراك إلى المستخدمين
انسخ الرمز التالي في ملف باسم 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 مع طلبات POST وGET التي يتم إرسالها إلى عنوان URL الأساسي للتطبيق (https://APP-ID.appspot.com). يستخدم Gmail طلبات POST لإدراج اشتراكات جديدة، بما في ذلك المَعلمة 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 للاطّلاع على صفحة تلخّص الاشتراكات.