ตัวอย่างตั้งแต่ต้นจนจบ

บทความนี้แสดงวิธีสร้างแอป App Engine ใน Python ที่ส่งอีเมลที่มีคำอธิบายประกอบไปยังผู้ใช้เพื่อขอให้ยืนยันการสมัครรับข้อมูลรายชื่ออีเมลจากกล่องจดหมายของผู้ใช้โดยตรง และรวบรวมการสมัครใช้บริการใน Datastore

สิ่งที่ต้องมีก่อนและการตั้งค่าโปรเจ็กต์

คู่มือนี้จะถือว่าคุณติดตั้ง App Engine SDK แล้ว และทราบวิธีสร้าง เรียกใช้ และเผยแพร่โปรเจ็กต์ 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)

การเพิ่ม Structured Data ไปยังอีเมล

เริ่มต้นด้วยอีเมลง่ายๆ ที่ขอให้ผู้ใช้ยืนยันการสมัครรับข้อมูลรายชื่ออีเมล:

<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 หรือ Microdata) ไปยัง head ของอีเมลเพื่อกำหนดร้านอาหารและเพิ่ม OneClickAction Gmail รองรับ OneClickAction และแสดง UI ที่เจาะจงแก่ผู้ใช้เพื่อให้ผู้ใช้ยืนยันการสมัครรับข้อมูลจากกล่องจดหมายของตนเองได้

คัดลอกมาร์กอัปต่อไปนี้ลงในไฟล์ชื่อ 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>

Microdata

<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)

พารามิเตอร์ SubscriptionHandlerclass listens to bothPOSTandGETrequests sent to the app root url (https://APP-ID.appspot.com).POSTrequests are used by Gmail to insert new subscriptions including theuser_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) เพื่อส่งอีเมลที่มีคำอธิบายประกอบถึงตัวคุณเอง

การดำเนินการใน Gmail

เมื่อคุณทำให้แอปใช้งานได้และใส่การสมัครใช้บริการบางส่วนแล้ว ให้ไปที่แอปที่ https://APP-ID.appspot.com เพื่อดูหน้าสรุปการสมัครใช้บริการ