সেট আপ করুন এবং পুশ বিজ্ঞপ্তি গ্রহণ করুন

ডেটা ফর্মে পরিবর্তন হলে বিজ্ঞপ্তি পেতে আপনি ওয়াচেস সংগ্রহের পদ্ধতিগুলি ব্যবহার করতে পারেন। এই পৃষ্ঠাটি পুশ বিজ্ঞপ্তি সেট আপ এবং গ্রহণ করার জন্য একটি ধারণাগত ওভারভিউ এবং নির্দেশাবলী প্রদান করে।

সংক্ষিপ্ত বিবরণ

Google Forms API পুশ নোটিফিকেশন বৈশিষ্ট্যটি ফর্মগুলিতে ডেটা পরিবর্তন হলে অ্যাপ্লিকেশনগুলিকে বিজ্ঞপ্তিগুলিতে সাবস্ক্রাইব করার অনুমতি দেয়। বিজ্ঞপ্তিগুলি সাধারণত পরিবর্তনের কয়েক মিনিটের মধ্যেই একটি ক্লাউড পাব/সাব টপিকে পৌঁছে দেওয়া হয়।

পুশ নোটিফিকেশন পেতে, আপনাকে একটি ক্লাউড পাব/সাব টপিক সেট আপ করতে হবে এবং উপযুক্ত ইভেন্ট টাইপের জন্য একটি ঘড়ি তৈরি করার সময় সেই টপিকের নাম প্রদান করতে হবে।

এই ডকুমেন্টেশনে ব্যবহৃত মূল ধারণাগুলির সংজ্ঞা নীচে দেওয়া হল:

  • টার্গেট হলো এমন একটি জায়গা যেখানে বিজ্ঞপ্তি পাঠানো হয়। একমাত্র সমর্থিত টার্গেট হলো ক্লাউড পাব/সাব টপিক।
  • ইভেন্ট টাইপ হলো বিজ্ঞপ্তির একটি বিভাগ যা একটি তৃতীয় পক্ষের অ্যাপ্লিকেশন সাবস্ক্রাইব করতে পারে।
  • একটি ওয়াচ হল ফর্মস এপিআই-এর একটি নির্দেশ যা একটি নির্দিষ্ট ফর্মের উপর একটি নির্দিষ্ট ইভেন্ট ধরণের জন্য একটি লক্ষ্যবস্তুতে বিজ্ঞপ্তি সরবরাহ করে।

একবার আপনি একটি নির্দিষ্ট ফর্মে ইভেন্ট টাইপের জন্য একটি ঘড়ি তৈরি করলে, সেই ঘড়ির টার্গেট (যা একটি ক্লাউড পাব/সাব বিষয়) ঘড়ির মেয়াদ শেষ না হওয়া পর্যন্ত সেই ফর্মের ইভেন্টগুলি থেকে বিজ্ঞপ্তি পাবে। আপনার ঘড়িটি এক সপ্তাহ স্থায়ী হয়, তবে আপনি watches.renew() এর কাছে অনুরোধ করে মেয়াদ শেষ হওয়ার আগে যেকোনো সময় এটি বাড়িয়ে দিতে পারেন।

আপনার ক্লাউড পাব/সাব টপিক শুধুমাত্র সেই ফর্মগুলির বিষয়ে বিজ্ঞপ্তি পায় যা আপনি আপনার সরবরাহ করা শংসাপত্রের সাহায্যে দেখতে পারেন। উদাহরণস্বরূপ, যদি ব্যবহারকারী আপনার অ্যাপ্লিকেশন থেকে অনুমতি প্রত্যাহার করে নেয় বা কোনও দেখা ফর্মের সম্পাদনা অ্যাক্সেস হারায়, তাহলে বিজ্ঞপ্তি আর সরবরাহ করা হবে না।

উপলব্ধ ইভেন্টের ধরণ

গুগল ফর্মস এপিআই বর্তমানে দুটি ধরণের ইভেন্ট অফার করে:

  • EventType.SCHEMA , যা একটি ফর্মের বিষয়বস্তু এবং সেটিংসে সম্পাদনা সম্পর্কে অবহিত করে।
  • EventType.RESPONSES , যা ফর্মের প্রতিক্রিয়া (নতুন এবং আপডেট উভয়) জমা দেওয়ার সময় সূচিত করে।

বিজ্ঞপ্তির প্রতিক্রিয়া

বিজ্ঞপ্তিগুলি JSON দিয়ে এনকোড করা হয় এবং এতে থাকে:

  • ট্রিগারিং ফর্মের আইডি
  • ট্রিগারিং ঘড়ির আইডি
  • যে ধরণের ইভেন্ট বিজ্ঞপ্তিটি ট্রিগার করেছে
  • ক্লাউড পাব/সাব দ্বারা সেট করা অন্যান্য ক্ষেত্র, যেমন messageId এবং publishTime

বিজ্ঞপ্তিগুলিতে বিস্তারিত ফর্ম বা প্রতিক্রিয়া ডেটা থাকে না । প্রতিটি বিজ্ঞপ্তি পাওয়ার পরে, নতুন ডেটা আনার জন্য একটি পৃথক API কল প্রয়োজন। এটি কীভাবে সম্পন্ন করবেন তার জন্য প্রস্তাবিত ব্যবহার দেখুন।

নিম্নলিখিত স্নিপেটটি স্কিমা পরিবর্তনের জন্য একটি নমুনা বিজ্ঞপ্তি প্রদর্শন করে:

{
  "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"
}

একটি ক্লাউড পাব/সাব বিষয় সেট আপ করুন

ক্লাউড পাব/সাব বিষয়গুলিতে বিজ্ঞপ্তিগুলি সরবরাহ করা হয়। ক্লাউড পাব/সাব থেকে, আপনি ওয়েব হুকে অথবা সাবস্ক্রিপশন এন্ডপয়েন্ট পোল করে বিজ্ঞপ্তিগুলি পেতে পারেন।

ক্লাউড পাব/সাব টপিক সেট আপ করতে, নিম্নলিখিতগুলি করুন:

  1. ক্লাউড পাব/সাব পূর্বশর্তগুলি পূরণ করুন।
  2. একটি ক্লাউড পাব/সাব ক্লায়েন্ট সেট আপ করুন
  3. ক্লাউড পাব/সাব মূল্য পর্যালোচনা করুন এবং আপনার গুগল ক্লাউড কনসোল প্রকল্পের জন্য বিলিং সক্ষম করুন।
  4. তিনটি উপায়ের মধ্যে যেকোনো একটি উপায়ে ক্লাউড পাব/সাব টপিক তৈরি করুন:

  5. ক্লাউড পাব/সাব-এ একটি সাবস্ক্রিপশন তৈরি করুন যাতে ক্লাউড পাব/সাব-কে আপনার বিজ্ঞপ্তিগুলি কীভাবে সরবরাহ করতে হয় তা বলা যায়।

  6. অবশেষে, আপনার বিষয়কে লক্ষ্য করে ঘড়ি তৈরি করার আগে, আপনার বিষয় প্রকাশের জন্য ফর্ম বিজ্ঞপ্তি পরিষেবা অ্যাকাউন্ট (forms-notifications@system.gserviceaccount.com) কে অনুমতি দিতে হবে।

একটি ঘড়ি তৈরি করুন

একবার আপনার কাছে এমন একটি বিষয় থাকে যেখানে Forms API পুশ নোটিফিকেশন পরিষেবা অ্যাকাউন্ট প্রকাশ করতে পারে, তাহলে আপনি watches.create() পদ্ধতি ব্যবহার করে বিজ্ঞপ্তি তৈরি করতে পারেন। এই পদ্ধতিটি যাচাই করে যে প্রদত্ত ক্লাউড পাব/সাব বিষয়টি পুশ নোটিফিকেশন পরিষেবা অ্যাকাউন্টের মাধ্যমে পৌঁছানো যেতে পারে, এবং যদি এটি বিষয়টিতে পৌঁছাতে না পারে তবে এটি ব্যর্থ হয়; উদাহরণস্বরূপ, যদি বিষয়টি বিদ্যমান না থাকে বা আপনি তাকে সেই বিষয়ে প্রকাশের অনুমতি না দিয়ে থাকেন।

পাইথন

ফর্ম/স্নিপেট/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)

নোড.জেএস

ফর্ম/স্নিপেট/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;
}

একটি ঘড়ি মুছুন

পাইথন

ফর্ম/স্নিপেট/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)

নোড.জেএস

ফর্ম/স্নিপেট/ডিলিট_ওয়াচ.জেএস
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() এ কলগুলি অবশ্যই একটি অনুমোদন টোকেন দিয়ে অনুমোদিত হতে হবে। টোকেনে এমন একটি সুযোগ থাকতে হবে যা কোন বিজ্ঞপ্তিগুলি পাঠানো হচ্ছে সে সম্পর্কে ডেটাতে পড়ার অ্যাক্সেস প্রদান করে।

বিজ্ঞপ্তিগুলি বিতরণের জন্য, অ্যাপ্লিকেশনটিকে প্রয়োজনীয় স্কোপ সহ অনুমোদিত ব্যবহারকারীর কাছ থেকে একটি OAuth অনুদান ধরে রাখতে হবে। ব্যবহারকারী যদি অ্যাপ্লিকেশনটি সংযোগ বিচ্ছিন্ন করে, তাহলে বিজ্ঞপ্তিগুলি বন্ধ হয়ে যেতে পারে এবং একটি ত্রুটির কারণে ঘড়িটি স্থগিত করা হতে পারে। অনুমোদন পুনরুদ্ধারের পরে বিজ্ঞপ্তিগুলি পুনরায় শুরু করতে, একটি ঘড়ি পুনর্নবীকরণ দেখুন।

একটি ফর্মের ঘড়ির তালিকা তৈরি করুন।

পাইথন

ফর্ম/স্নিপেট/লিস্ট_ওয়াচস.পি
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)

নোড.জেএস

ফর্ম/স্নিপেট/লিস্ট_ওয়াচস.জেএস
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;
}

একটি ঘড়ি নবায়ন করুন

পাইথন

ফর্ম/স্নিপেট/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)

নোড.জেএস

ফর্ম/স্নিপেট/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;
}

থ্রটলিং

বিজ্ঞপ্তিগুলি থ্রোটল করা হয়—প্রতিটি ঘড়ি প্রতি ত্রিশ সেকেন্ডে সর্বাধিক একটি বিজ্ঞপ্তি পেতে পারে। ফ্রিকোয়েন্সির এই সীমা পরিবর্তন সাপেক্ষে।

থ্রটলিংয়ের কারণে, একটি একক বিজ্ঞপ্তি একাধিক ইভেন্টের সাথে সম্পর্কিত হতে পারে। অন্য কথায়, একটি বিজ্ঞপ্তি ইঙ্গিত দেয় যে শেষ বিজ্ঞপ্তির পর থেকে এক বা একাধিক ঘটনা ঘটেছে।

সীমা

যেকোনো সময়, একটি নির্দিষ্ট ফর্ম এবং ইভেন্টের ধরণের জন্য, প্রতিটি ক্লাউড কনসোল প্রকল্পে থাকতে পারে:

  • মোট ২০টি ঘড়ি পর্যন্ত
  • প্রতি ব্যবহারকারীর জন্য সর্বোচ্চ একটি ঘড়ি

উপরন্তু, যেকোনো সময়, সমস্ত ক্লাউড কনসোল প্রকল্পে প্রতিটি ফর্মের জন্য মোট ৫০টি ঘড়ির মধ্যে সীমাবদ্ধ।

একটি ঘড়ি যখন কোনও ব্যবহারকারীর জন্য শংসাপত্র তৈরি বা পুনর্নবীকরণ করা হয় তখন তার সাথে যুক্ত থাকে। যদি সংশ্লিষ্ট ব্যবহারকারী ফর্মের অ্যাক্সেস হারান বা ফর্মে অ্যাপের অ্যাক্সেস প্রত্যাহার করেন তবে একটি ঘড়ি স্থগিত করা হয়।

নির্ভরযোগ্যতা

অসাধারণ পরিস্থিতিতে ছাড়া প্রতিটি ঘটনার পর প্রতিটি ঘড়িকে অন্তত একবার অবহিত করা হয়। বেশিরভাগ ক্ষেত্রে, একটি ঘটনার কয়েক মিনিটের মধ্যেই একটি বিজ্ঞপ্তি পৌঁছে দেওয়া হয়।

ত্রুটি

যদি কোনও ঘড়ির জন্য বিজ্ঞপ্তিগুলি ক্রমাগতভাবে বিতরণ করা না হয়, তাহলে ঘড়ির অবস্থা SUSPENDED হয়ে যায় এবং ঘড়ির errorType ক্ষেত্রটি সেট করা হয়। একটি স্থগিত ঘড়ির অবস্থা ACTIVE এ রিসেট করতে এবং বিজ্ঞপ্তিগুলি পুনরায় শুরু করতে, একটি ঘড়ি পুনর্নবীকরণ দেখুন।

প্রস্তাবিত ব্যবহার

  • অনেক ঘড়ির লক্ষ্যবস্তু হিসেবে একটি ক্লাউড পাব/সাব বিষয় ব্যবহার করুন।
  • কোনও বিষয়ে বিজ্ঞপ্তি পাওয়ার সময়, ফর্ম আইডিটি নোটিফিকেশন পেলোডে অন্তর্ভুক্ত থাকে। কোন ডেটা আনতে হবে এবং কোন ফর্ম থেকে আনতে হবে তা জানতে ইভেন্ট টাইপের সাথে এটি ব্যবহার করুন।
  • EventType.RESPONSES ব্যবহার করে বিজ্ঞপ্তি প্রকাশের পর আপডেট করা ডেটা আনতে, forms.responses.list() কল করুন।
    • অনুরোধের ফিল্টারটি timestamp > timestamp_of_the_last_response_you_fetched এ সেট করুন।
  • EventType.SCHEMA দিয়ে বিজ্ঞপ্তির পরে আপডেট করা ডেটা আনতে, forms.get() কল করুন।