पुश नोटिफ़िकेशन सेट अप करना और पाना

फ़ॉर्म में डेटा में बदलाव होने पर सूचनाएं पाने के लिए, Watches कलेक्शन में मौजूद तरीकों का इस्तेमाल किया जा सकता है. इस पेज पर, पुश नोटिफ़िकेशन सेट अप करने और पाने के बारे में कॉन्सेप्ट की खास जानकारी और निर्देश दिए गए हैं.

खास जानकारी

Google Forms API की पुश नोटिफ़िकेशन सुविधा की मदद से, ऐप्लिकेशन, फ़ॉर्म में डेटा में बदलाव होने पर सूचनाएं पाने के लिए सदस्यता ले सकते हैं. सूचनाएं, Cloud Pub/Sub के किसी विषय पर डिलीवर की जाती हैं. आम तौर पर, बदलाव होने के कुछ ही मिनटों में सूचनाएं डिलीवर हो जाती हैं.

पुश नोटिफ़िकेशन पाने के लिए, आपको Cloud Pub/Sub का कोई विषय सेट अप करना होगा. साथ ही, इवेंट के सही टाइप के लिए वॉच बनाते समय, उस विषय का नाम देना होगा.

इस दस्तावेज़ में इस्तेमाल किए गए मुख्य कॉन्सेप्ट की परिभाषाएं यहां दी गई हैं:

  • टारगेट वह जगह होती है जहां सूचनाएं भेजी जाती हैं. सिर्फ़ Cloud Pub/Sub के विषय को टारगेट के तौर पर इस्तेमाल किया जा सकता है.
  • इवेंट टाइप सूचनाओं की वह कैटगरी होती है जिसकी सदस्यता, तीसरे पक्ष का कोई ऐप्लिकेशन ले सकता है.
  • वॉच, Forms API को दिया गया वह निर्देश होता है जिसके तहत, किसी खास इवेंट टाइप के लिए सूचनाएं, किसी टारगेट को डिलीवर की जाती हैं.

किसी फ़ॉर्म पर किसी इवेंट टाइप के लिए वॉच बनाने के बाद, उस वॉच का टारगेट (जो कि Cloud Pub/Sub का कोई विषय होता है) उस फ़ॉर्म पर उन इवेंट से जुड़ी सूचनाएं तब तक पाता है, जब तक वॉच की समयसीमा खत्म नहीं हो जाती. watches.renew()

Cloud Pub/Sub का आपका विषय, सिर्फ़ उन फ़ॉर्म के बारे में सूचनाएं पाता है जिन्हें आपके दिए गए क्रेडेंशियल से देखा जा सकता है. उदाहरण के लिए, अगर उपयोगकर्ता आपके ऐप्लिकेशन से अनुमति वापस ले लेता है या देखी जा रही किसी फ़ॉर्म में बदलाव करने का ऐक्सेस खो देता है, तो सूचनाएं डिलीवर नहीं की जाती हैं.

उपलब्ध इवेंट टाइप

फ़िलहाल, Google Forms API में इवेंट की दो कैटगरी उपलब्ध हैं:

  • EventType.SCHEMA. इससे, फ़ॉर्म के कॉन्टेंट और सेटिंग में किए गए बदलावों के बारे में सूचना मिलती है.
  • EventType.RESPONSES. इससे, फ़ॉर्म के जवाब (नए और अपडेट किए गए, दोनों) सबमिट होने पर सूचना मिलती है.

सूचना के जवाब

सूचनाएं JSON में कोड की जाती हैं. इनमें ये चीज़ें शामिल होती हैं:

  • सूचना को ट्रिगर करने वाले फ़ॉर्म का आईडी
  • सूचना को ट्रिगर करने वाली वॉच का आईडी
  • उस इवेंट का टाइप जिसने सूचना को ट्रिगर किया
  • Cloud Pub/Sub की ओर से सेट किए गए अन्य फ़ील्ड, जैसे कि messageId और publishTime

सूचनाओं में, फ़ॉर्म या जवाब का ज़्यादा जानकारी वाला डेटा शामिल नहीं होता. हर सूचना मिलने के बाद, नया डेटा फ़ेच करने के लिए, एपीआई का अलग से कॉल करना ज़रूरी होता है. इसे पूरा करने का तरीका जानने के लिए, इस्तेमाल के सुझाव देखें.

यहां दिए गए स्निपेट में, स्कीमा में बदलाव के लिए सूचना का एक सैंपल दिखाया गया है:

{
  "attributes": {
    "eventType": "SCHEMA",
    "formId": "18Xgmr4XQb-l0ypfCNGQoHAw2o82foMr8J0HPHdagS6g",
    "watchId": "892515d1-a902-444f-a2fe-42b718fe8159"
  },
  "messageId": "767437830649",
  "publishTime": "2021-03-31T01:34:08.053Z"
}

यहां दिए गए स्निपेट में, नए जवाब के लिए सूचना का एक सैंपल दिखाया गया है:

{
  "attributes": {
    "eventType": "RESPONSES",
    "formId": "18Xgmr4XQb-l0ypfCNGQoHAw2o82foMr8J0HPHdagS6g",
    "watchId": "5d7e5690-b1ff-41ce-8afb-b469912efd7d"
  },
  "messageId": "767467004397",
  "publishTime": "2021-03-31T01:43:57.285Z"
}

Cloud Pub/Sub का कोई विषय सेट अप करना

सूचनाएं, Cloud Pub/Sub के विषयों पर डिलीवर की जाती हैं. Cloud Pub/Sub से, वेब हुक पर सूचनाएं पाई जा सकती हैं. इसके अलावा, सदस्यता वाले एंडपॉइंट को पोल करके भी सूचनाएं पाई जा सकती हैं.

Cloud Pub/Sub का कोई विषय सेट अप करने के लिए, यह तरीका अपनाएं:

  1. Cloud Pub/Sub की ज़रूरी शर्तें पूरी करें.
  2. Cloud Pub/Sub का कोई क्लाइंट सेट अप करें.
  3. Cloud Pub/Sub की कीमत की समीक्षा करें. साथ ही, Google Cloud Console के अपने प्रोजेक्ट के लिए बिलिंग की सुविधा चालू करें.
  4. Cloud Pub/Sub का कोई विषय, इन तीन तरीकों में से किसी एक से बनाएं:

    • Google Cloud Console का इस्तेमाल करके
    • कमांड लाइन टूल का इस्तेमाल करके (प्रोग्राम के ज़रिए आसान तरीके से इस्तेमाल करने के लिए) या
    • Cloud Pub/Sub API का इस्तेमाल करके.
  5. Cloud Pub/Sub में सदस्यता बनाएं , ताकि Cloud Pub/Sub को यह पता चल सके कि आपकी सूचनाएं कैसे डिलीवर करनी हैं.

  6. आखिर में, अपने विषय को टारगेट करने वाली वॉच बनाने से पहले, आपको Forms की सूचनाओं के सेवा खाते (forms-notifications@system.gserviceaccount.com) को अपने विषय पर पब्लिश करने की अनुमति देनी होगी.

वॉच बनाना

Forms API की पुश नोटिफ़िकेशन सेवा खाते के पास, जिस विषय पर पब्लिश करने की अनुमति होती है उसके लिए, watches.create() तरीके का इस्तेमाल करके सूचनाएं बनाई जा सकती हैं. यह तरीका, पुष्टि करता है कि पुश नोटिफ़िकेशन सेवा का खाता, दिए गए Cloud Pub/Sub के विषय तक पहुंच सकता है या नहीं. अगर वह विषय तक नहीं पहुंच पाता है, तो यह तरीका काम नहीं करता. उदाहरण के लिए, अगर विषय मौजूद नहीं है या आपने उसे उस विषय पर पब्लिश करने की अनुमति नहीं दी है.

Python

forms/snippets/create_watch.py
from apiclient import discovery
from httplib2 import Http
from oauth2client import client, file, tools

SCOPES = "https://www.googleapis.com/auth/drive"
DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1"

store = file.Storage("token.json")
creds = None
if not creds or creds.invalid:
  flow = client.flow_from_clientsecrets("client_secret.json", SCOPES)
  creds = tools.run_flow(flow, store)

service = discovery.build(
    "forms",
    "v1",
    http=creds.authorize(Http()),
    discoveryServiceUrl=DISCOVERY_DOC,
    static_discovery=False,
)

watch = {
    "watch": {
        "target": {"topic": {"topicName": "<YOUR_TOPIC_PATH>"}},
        "eventType": "RESPONSES",
    }
}

form_id = "<YOUR_FORM_ID>"

# Print JSON response after form watch creation
result = service.forms().watches().create(formId=form_id, body=watch).execute()
print(result)

Node.js

forms/snippets/create_watch.js
import path from 'node:path';
import {authenticate} from '@google-cloud/local-auth';
import {forms} from '@googleapis/forms';

// TODO: Replace with a valid form ID.
const formID = '<YOUR_FORM_ID>';

/**
 * Creates a watch on a form to get notifications for new responses.
 */
async function createWatch() {
  // Authenticate with Google and get an authorized client.
  const authClient = await authenticate({
    keyfilePath: path.join(__dirname, 'credentials.json'),
    scopes: 'https://www.googleapis.com/auth/drive',
  });

  // Create a new Forms API client.
  const formsClient = forms({
    version: 'v1',
    auth: authClient,
  });

  // The request body to create a watch.
  const watchRequest = {
    watch: {
      target: {
        topic: {
          // TODO: Replace with a valid Cloud Pub/Sub topic name.
          topicName: 'projects/<YOUR_TOPIC_PATH>',
        },
      },
      // The event type to watch for. 'RESPONSES' is the only supported type.
      eventType: 'RESPONSES',
    },
  };

  // Send the request to create the watch.
  const result = await formsClient.forms.watches.create({
    formId: formID,
    requestBody: watchRequest,
  });

  console.log(result.data);
  return result.data;
}

वॉच मिटाना

Python

forms/snippets/delete_watch.py
from apiclient import discovery
from httplib2 import Http
from oauth2client import client, file, tools

SCOPES = "https://www.googleapis.com/auth/drive"
DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1"

store = file.Storage("token.json")
creds = None
if not creds or creds.invalid:
  flow = client.flow_from_clientsecrets("client_secret.json", SCOPES)
  creds = tools.run_flow(flow, store)
service = discovery.build(
    "forms",
    "v1",
    http=creds.authorize(Http()),
    discoveryServiceUrl=DISCOVERY_DOC,
    static_discovery=False,
)

form_id = "<YOUR_FORM_ID>"
watch_id = "<YOUR_WATCH_ID>"

# Print JSON response after deleting a form watch
result = (
    service.forms().watches().delete(formId=form_id, watchId=watch_id).execute()
)
print(result)

Node.js

forms/snippets/delete_watch.js
import path from 'node:path';
import {authenticate} from '@google-cloud/local-auth';
import {forms} from '@googleapis/forms';

// TODO: Replace with a valid form ID.
const formID = '<YOUR_FORM_ID>';
// TODO: Replace with a valid watch ID.
const watchID = '<YOUR_FORMS_WATCH_ID>';

/**
 * Deletes a watch from a form.
 */
async function deleteWatch() {
  // Authenticate with Google and get an authorized client.
  const authClient = await authenticate({
    keyfilePath: path.join(__dirname, 'credentials.json'),
    scopes: 'https://www.googleapis.com/auth/drive',
  });

  // Create a new Forms API client.
  const formsClient = forms({
    version: 'v1',
    auth: authClient,
  });

  // Send the request to delete the watch.
  const result = await formsClient.forms.watches.delete({
    formId: formID,
    watchId: watchID,
  });

  console.log(result.data);
  return result.data;
}

अनुमति देना

Forms API के सभी कॉल की तरह, watches.create() के कॉल को भी अनुमति वाले टोकन से अनुमति देनी होगी. टोकन में, ऐसा स्कोप शामिल होना चाहिए जो उस डेटा को पढ़ने का ऐक्सेस देता हो जिसके बारे में सूचनाएं भेजी जा रही हैं.

  • स्कीमा में बदलाव के लिए, इसका मतलब है कि कोई भी ऐसा स्कोप जो फ़ॉर्म का इस्तेमाल करके, forms.get()को पढ़ने का ऐक्सेस देता हो.
  • जवाबों के लिए, इसका मतलब है कि कोई भी ऐसा स्कोप जो फ़ॉर्म के जवाबोंको पढ़ने का ऐक्सेस देता हो. उदाहरण के लिए, forms.responses.list()का इस्तेमाल करके.

सूचनाएं डिलीवर करने के लिए, ऐप्लिकेशन के पास ज़रूरी स्कोप के साथ, अनुमति वाले उपयोगकर्ता से मिली OAuth की अनुमति होनी चाहिए. अगर उपयोगकर्ता, ऐप्लिकेशन को डिसकनेक्ट कर देता है, तो सूचनाएं बंद हो जाती हैं. साथ ही, गड़बड़ी के साथ वॉच को निलंबित किया जा सकता है. अनुमति वापस पाने के बाद, सूचनाएं फिर से पाने के लिए, वॉच को रिन्यू करना देखें.

किसी फ़ॉर्म की वॉच की सूची देखना

Python

forms/snippets/list_watches.py
from apiclient import discovery
from httplib2 import Http
from oauth2client import client, file, tools

SCOPES = "https://www.googleapis.com/auth/drive"
DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1"

store = file.Storage("token.json")
creds = None
if not creds or creds.invalid:
  flow = client.flow_from_clientsecrets("client_secrets.json", SCOPES)
  creds = tools.run_flow(flow, store)
service = discovery.build(
    "forms",
    "v1",
    http=creds.authorize(Http()),
    discoveryServiceUrl=DISCOVERY_DOC,
    static_discovery=False,
)

form_id = "<YOUR_FORM_ID>"

# Print JSON list of form watches
result = service.forms().watches().list(formId=form_id).execute()
print(result)

Node.js

forms/snippets/list_watches.js
import path from 'node:path';
import {authenticate} from '@google-cloud/local-auth';
import {forms} from '@googleapis/forms';

// TODO: Replace with a valid form ID.
const formID = '<YOUR_FORM_ID>';

/**
 * Lists the watches for a given form.
 */
async function listWatches() {
  // Authenticate with Google and get an authorized client.
  const auth = await authenticate({
    keyfilePath: path.join(__dirname, 'credentials.json'),
    scopes: 'https://www.googleapis.com/auth/forms.responses.readonly',
  });

  // Create a new Forms API client.
  const formsClient = forms({
    version: 'v1',
    auth,
  });

  // Get the list of watches for the form.
  const result = await formsClient.forms.watches.list({
    formId: formID,
  });

  console.log(result.data);
  return result.data;
}

वॉच को रिन्यू करना

Python

forms/snippets/renew_watch.py
from apiclient import discovery
from httplib2 import Http
from oauth2client import client, file, tools

SCOPES = "https://www.googleapis.com/auth/drive"
DISCOVERY_DOC = "https://forms.googleapis.com/$discovery/rest?version=v1"

store = file.Storage("token.json")
creds = None
if not creds or creds.invalid:
  flow = client.flow_from_clientsecrets("client_secrets.json", SCOPES)
  creds = tools.run_flow(flow, store)
service = discovery.build(
    "forms",
    "v1",
    http=creds.authorize(Http()),
    discoveryServiceUrl=DISCOVERY_DOC,
    static_discovery=False,
)

form_id = "<YOUR_FORM_ID>"
watch_id = "<YOUR_WATCH_ID>"

# Print JSON response after renewing a form watch
result = (
    service.forms().watches().renew(formId=form_id, watchId=watch_id).execute()
)
print(result)

Node.js

forms/snippets/renew_watch.js
import path from 'node:path';
import {authenticate} from '@google-cloud/local-auth';
import {forms} from '@googleapis/forms';

// TODO: Replace with a valid form ID.
const formID = '<YOUR_FORM_ID>';
// TODO: Replace with a valid watch ID.
const watchID = '<YOUR_FORMS_WATCH_ID>';

/**
 * Renews a watch on a form.
 */
async function renewWatch() {
  // Authenticate with Google and get an authorized client.
  const authClient = await authenticate({
    keyfilePath: path.join(__dirname, 'credentials.json'),
    scopes: 'https://www.googleapis.com/auth/drive',
  });

  // Create a new Forms API client.
  const formsClient = forms({
    version: 'v1',
    auth: authClient,
  });

  // Send the request to renew the watch.
  const result = await formsClient.forms.watches.renew({
    formId: formID,
    watchId: watchID,
  });

  console.log(result.data);
  return result.data;
}

थ्रॉटलिंग

सूचनाओं पर थ्रॉटलिंग लागू होती है. हर वॉच को हर 30 सेकंड में ज़्यादा से ज़्यादा एक सूचना मिल सकती है. फ़्रीक्वेंसी की इस सीमा में बदलाव किया जा सकता है.

थ्रॉटलिंग की वजह से, एक सूचना कई इवेंट से जुड़ी हो सकती है. दूसरे शब्दों में, सूचना से पता चलता है कि पिछली सूचना के बाद एक या उससे ज़्यादा इवेंट हुए हैं.

सीमाएं

किसी भी समय, दिए गए फ़ॉर्म और इवेंट टाइप के लिए, हर Cloud Console प्रोजेक्ट में ये चीज़ें हो सकती हैं:

  • कुल 20 वॉच
  • हर असली उपयोगकर्ता के लिए एक वॉच

इसके अलावा, किसी भी समय, हर फ़ॉर्म के लिए, सभी Cloud Console प्रोजेक्ट में कुल मिलाकर, हर इवेंट टाइप के लिए 50 वॉच की सीमा होती है.

किसी असली उपयोगकर्ता के क्रेडेंशियल का इस्तेमाल करके वॉच बनाने या उसे रिन्यू करने पर, वह वॉच उस असली उपयोगकर्ता से जुड़ जाती है. अगर असली उपयोगकर्ता के पास फ़ॉर्म का ऐक्सेस नहीं रहता है या वह ऐप्लिकेशन को फ़ॉर्म का ऐक्सेस वापस ले लेता है, तो वॉच को निलंबित कर दिया जाता है.

विश्वसनीयता

हर वॉच को, हर इवेंट के बाद कम से कम एक बार सूचना मिलती है. हालांकि, कुछ असाधारण मामलों में ऐसा नहीं होता. ज़्यादातर मामलों में, किसी इवेंट के कुछ ही मिनटों में सूचना डिलीवर हो जाती है.

गड़बड़ियां

अगर किसी वॉच के लिए सूचनाएं लगातार डिलीवर नहीं हो पाती हैं, तो वॉच का स्टेटस SUSPENDED हो जाता है. साथ ही, वॉच का errorType फ़ील्ड सेट हो जाता है. निलंबित की गई वॉच के स्टेटस को ACTIVE पर रीसेट करने और सूचनाएं फिर से पाने के लिए, वॉच को रिन्यू करना देखें.

इस्तेमाल के सुझाव

  • Cloud Pub/Sub के किसी एक विषय को, कई वॉच के टारगेट के तौर पर इस्तेमाल करें.
  • किसी विषय पर सूचना मिलने पर, फ़ॉर्म का आईडी, सूचना के पेलोड में शामिल होता है. इसका इस्तेमाल, इवेंट टाइप के साथ करें, ताकि यह पता चल सके कि कौनसे डेटा को फ़ेच करना है और उसे किस फ़ॉर्म से फ़ेच करना है.
  • EventType.RESPONSES वाली सूचना के बाद, अपडेट किया गया डेटा फ़ेच करने के लिए, forms.responses.list() को कॉल करें.
    • अनुरोध पर फ़िल्टर को timestamp > timestamp_of_the_last_response_you_fetched पर सेट करें.
  • EventType.SCHEMA वाली सूचना के बाद, अपडेट किया गया डेटा फ़ेच करने के लिए, forms.get() को कॉल करें.