एंड-टू-एंड एन्क्रिप्शन का उदाहरण

इस दस्तावेज़ में, Python में App Engine ऐप्लिकेशन बनाने का तरीका बताया गया है. यह ऐप्लिकेशन, लोगों को एनोटेट किए गए ईमेल भेजता है. इन ईमेल में, लोगों से सीधे उनके इनबॉक्स में जाकर, ईमेल पाने वाली सूची की सदस्यता की पुष्टि करने के लिए कहा जाता है. साथ ही, यह ऐप्लिकेशन 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

अपने App Engine प्रोजेक्ट फ़ोल्डर में main.py नाम की फ़ाइल बनाएं. इसके बाद, सदस्यताएं इकट्ठा करने और उनकी सूची बनाने के लिए हैंडलर सेट अप करने के लिए, यहां दिया गया कोड कॉपी करें. साथ ही, एनोटेट किए गए ईमेल भेजने के लिए भी यह कोड कॉपी करें:

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>

ईमेल के head में, स्ट्रक्चर्ड डेटा को इन फ़ॉर्मैट में से किसी एक में जोड़ा जा सकता है: JSON-LD या माइक्रोडेटा. इससे ईमेल मैसेज को तय किया जा सकता है और 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 होता है. यह url प्रॉपर्टी में दिए गए यूआरएल पर POST अनुरोध भेजता है.

अहम जानकारी: ऊपर दिए गए कोड में, कोई भी ईमेल भेजने से पहले, {{ confirm_url }} प्लेसहोल्डर को अपने App Engine ऐप्लिकेशन के यूआरएल (जैसे कि https://mailing-list.appspot.com) से बदलें. नीचे दिए गए चरणों में बताया गया कोड, इस बदलाव को मैनेज करता है.

उपयोगकर्ताओं को सदस्यता के अनुरोध भेजना

नीचे दिए गए कोड को, App Engine प्रोजेक्ट फ़ोल्डर में मौजूद emailsender.py नाम की फ़ाइल में कॉपी करें:

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 प्लेसहोल्डर को App Engine ऐप्लिकेशन (https://APP-ID.appspot.com) के रूट यूआरएल से बदल देता है. इसके बाद, यह ईमेल को लॉग-इन किए गए उपयोगकर्ता को भेज देता है.

सदस्यताएं इकट्ठा करना और उनकी सूची बनाना

नीचे दिए गए कोड को, App Engine प्रोजेक्ट फ़ोल्डर में मौजूद subscribe.py नाम की फ़ाइल में कॉपी करें:

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 क्लास, ऐप्लिकेशन के रूट यूआरएल (https://APP-ID.appspot.com) पर भेजे गए POST और GET, दोनों तरह के अनुरोधों को मैनेज करती है. POST अनुरोधों का इस्तेमाल Gmail, नई सदस्यताएं जोड़ने के लिए करता है. इनमें user_id पैरामीटर भी शामिल होता है, जो उपयोगकर्ता से जुड़ा होता है. उदाहरण के लिए:

https://subscribe.appspot.com/?user_id=123abcd

अनुरोध हैंडलर यह जांच करता है कि ज़रूरी user_id तय किया गया है या नहीं. साथ ही, यह सदस्यता को Datastore में सेव करता है. इससे Gmail को HTTP 200 रिस्पॉन्स कोड वापस भेजा जाता है, ताकि अनुरोध पूरा होने की सूचना दी जा सके. अगर अनुरोध में ज़रूरी फ़ील्ड शामिल नहीं है, तो अनुरोध हैंडलर, HTTP 400 रिस्पॉन्स कोड दिखाता है. इससे पता चलता है कि अनुरोध अमान्य है.

GET ऐप्लिकेशन के रूट यूआरएल के लिए किए गए अनुरोधों में, इकट्ठा की गई सदस्यताओं की सूची दिखती है. अनुरोध हैंडलर, Datastore से सभी सदस्यताओं को फ़ेच करता है और उन्हें पेज पर काउंटर के साथ दिखाता है.

ऐप्लिकेशन को टेस्ट करना

अपने ऐप्लिकेशन को App Engine पर डिप्लॉय करें और https://APP-ID.appspot.com/email पर जाएं. APP-ID को अपने App Engine ऐप्लिकेशन आईडी से बदलें, ताकि खुद को एनोटेट किया गया ईमेल भेजा जा सके.

Gmail में की गई कार्रवाइयां

ऐप्लिकेशन को डिप्लॉय करने और सदस्यताएं जोड़ने के बाद, https://APP-ID.appspot.com पर जाकर अपने ऐप्लिकेशन पर जाएं. यहां आपको सदस्यता के बारे में खास जानकारी देने वाला पेज दिखेगा.