اعلان‌های فشاری را تنظیم و دریافت کنید

شما می‌توانید از متدهای مجموعه Watches برای دریافت اعلان‌ها هنگام تغییر داده‌ها در فرم‌ها استفاده کنید. این صفحه یک مرور کلی مفهومی و دستورالعمل‌هایی برای تنظیم و دریافت اعلان‌های فوری ارائه می‌دهد.

نمای کلی

قابلیت اعلان‌های فوری API فرم‌های گوگل به برنامه‌ها اجازه می‌دهد تا هنگام تغییر داده‌ها در فرم‌ها، در اعلان‌ها مشترک شوند. اعلان‌ها معمولاً ظرف چند دقیقه پس از تغییر، به یک موضوع Cloud Pub/Sub ارسال می‌شوند.

برای دریافت اعلان‌های فوری، باید یک موضوع Cloud Pub/Sub تنظیم کنید و هنگام ایجاد watch برای نوع رویداد مناسب، نام آن موضوع را ارائه دهید.

در زیر تعاریف مفاهیم کلیدی مورد استفاده در این سند آمده است:

  • یک هدف ، مکانی است که اعلان‌ها به آنجا ارسال می‌شوند. تنها هدف پشتیبانی‌شده، یک موضوع Cloud Pub/Sub است.
  • نوع رویداد ، دسته‌ای از اعلان‌ها است که یک برنامه شخص ثالث می‌تواند در آن مشترک شود.
  • یک watch دستورالعملی به Forms API است تا اعلان‌هایی را برای یک نوع رویداد خاص در یک فرم خاص به یک هدف ارسال کند.

زمانی که برای یک نوع رویداد در یک فرم خاص، یک watch ایجاد می‌کنید، هدف آن watch (که یک Cloud Pub/Sub topic است) تا زمان انقضای watch، اعلان‌هایی از آن رویدادها در آن فرم دریافت می‌کند. watch شما یک هفته طول می‌کشد، اما می‌توانید با ارسال درخواستی به watches.renew() آن را در هر زمانی قبل از انقضا تمدید کنید.

موضوع Cloud Pub/Sub شما فقط اعلان‌هایی درباره فرم‌هایی دریافت می‌کند که می‌توانید با اعتبارنامه‌هایی که ارائه می‌دهید مشاهده کنید. به عنوان مثال، اگر کاربر مجوز برنامه شما را لغو کند یا دسترسی ویرایش به یک فرم مشاهده شده را از دست بدهد، دیگر اعلان‌هایی ارسال نمی‌شود.

انواع رویدادهای موجود

API فرم‌های گوگل در حال حاضر دو دسته رویداد ارائه می‌دهد:

  • EventType.SCHEMA که در مورد ویرایش‌های محتوا و تنظیمات فرم اطلاع می‌دهد.
  • EventType.RESPONSES ، که زمان ارسال پاسخ‌های فرم (چه جدید و چه به‌روزرسانی‌شده) را اطلاع می‌دهد.

پاسخ‌های اعلان

اعلان‌ها با JSON کدگذاری می‌شوند و شامل موارد زیر هستند:

  • شناسه فرم فعال کننده
  • شناسه ساعت فعال کننده
  • نوع رویدادی که باعث ایجاد اعلان شده است
  • فیلدهای دیگر تنظیم شده توسط Cloud Pub/Sub، مانند 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"
}

یک موضوع فرعی/میخانه ابری تنظیم کنید

اعلان‌ها به موضوعات Cloud Pub/Sub ارسال می‌شوند. از Cloud Pub/Sub، می‌توانید اعلان‌ها را از طریق وب هوک یا با نظرسنجی از یک نقطه پایانی اشتراک دریافت کنید.

برای تنظیم یک موضوع Cloud Pub/Sub، موارد زیر را انجام دهید:

  1. پیش‌نیازهای Cloud Pub/Sub را تکمیل کنید.
  2. یک کلاینت Cloud Pub/Sub راه‌اندازی کنید .
  3. قیمت‌گذاری Cloud Pub/Sub را بررسی کنید و برای پروژه کنسول Google Cloud خود، پرداخت را فعال کنید.
  4. ایجاد یک موضوع عمومی/زیرموضوعی ابری به یکی از سه روش زیر:

  5. یک اشتراک در Cloud Pub/Sub ایجاد کنید تا به Cloud Pub/Sub بگویید چگونه اعلان‌های شما را ارسال کند.

  6. در نهایت، قبل از ایجاد watchهایی که موضوع شما را هدف قرار می‌دهند، باید به حساب سرویس اعلان‌های فرم‌ها (forms-notifications@system.gserviceaccount.com) اجازه انتشار در موضوع خود را بدهید .

یک ساعت مچی ایجاد کنید

وقتی موضوعی دارید که حساب سرویس اعلان‌های فشاری Forms API می‌تواند در آن منتشر شود، می‌توانید با استفاده از متد watch.create() اعلان‌ها را ایجاد کنید. این متد تأیید می‌کند که حساب سرویس اعلان‌های فشاری می‌تواند به موضوع Cloud Pub/Sub ارائه شده دسترسی داشته باشد و اگر نتواند به موضوع دسترسی پیدا کند، ناموفق می‌شود؛ برای مثال، اگر موضوع وجود نداشته باشد یا شما مجوز انتشار در آن موضوع را به آن نداده باشید.

پایتون

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)

نود جی اس

فرم‌ها/قطعه کدها/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;
}

حذف یک ساعت

پایتون

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)

نود جی اس

فرم‌ها/قطعه کدها/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 را از کاربر مجاز با محدوده‌های مورد نیاز حفظ کند. اگر کاربر اتصال برنامه را قطع کند، اعلان‌ها متوقف می‌شوند و ممکن است watch با خطا به حالت تعلیق درآید. برای از سرگیری اعلان‌ها پس از بازیابی مجوز، به Renew a watch مراجعه کنید.

فهرست کردن watch های یک فرم

پایتون

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)

نود جی اس

فرم‌ها/قطعه کدها/لیست_واچ‌ها.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;
}

تمدید ساعت

پایتون

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)

نود جی اس

فرم‌ها/قطعه کدها/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;
}

تنظیم سرعت

اعلان‌ها محدود شده‌اند—هر ساعت می‌تواند حداکثر هر سی ثانیه یک اعلان دریافت کند. این آستانه فرکانس قابل تغییر است.

به دلیل محدود کردن سرعت، یک اعلان واحد ممکن است با چندین رویداد مطابقت داشته باشد. به عبارت دیگر، یک اعلان نشان می‌دهد که یک یا چند رویداد از آخرین اعلان رخ داده است.

محدودیت‌ها

در هر زمان، برای یک فرم و نوع رویداد مشخص، هر پروژه Cloud Console می‌تواند موارد زیر را داشته باشد:

  • در مجموع تا 20 ساعت
  • حداکثر یک ساعت برای هر کاربر نهایی

علاوه بر این، در هر زمان، هر فرم در کل پروژه‌های Cloud Console به ۵۰ بازدید برای هر نوع رویداد محدود است.

یک watch زمانی با یک کاربر نهایی مرتبط می‌شود که با اعتبارنامه‌های آن کاربر ایجاد یا تمدید شود. اگر کاربر نهایی مرتبط دسترسی به فرم را از دست بدهد یا دسترسی برنامه به فرم را لغو کند، watch به حالت تعلیق در می‌آید.

قابلیت اطمینان

به هر دیده‌بان، حداقل یک بار پس از هر رویداد، در تمام شرایط به جز شرایط فوق‌العاده، اطلاع داده می‌شود. در اکثر موارد، ظرف چند دقیقه پس از وقوع رویداد، اطلاع‌رسانی انجام می‌شود.

خطاها

اگر اعلان‌های مربوط به یک watch به طور مداوم تحویل داده نشوند، وضعیت watch به SUSPENDED تبدیل می‌شود و فیلد errorType آن تنظیم می‌شود. برای تنظیم مجدد وضعیت watch معلق به ACTIVE و از سرگیری اعلان‌ها، به Renew a watch مراجعه کنید.

کاربرد پیشنهادی

  • از یک موضوع Cloud Pub/Sub به عنوان هدف چندین Watch استفاده کنید.
  • هنگام دریافت اعلان در مورد یک موضوع، شناسه فرم در بار داده اعلان گنجانده شده است. از آن به همراه نوع رویداد استفاده کنید تا بدانید چه داده‌هایی را باید واکشی کنید و از کدام فرم آن را دریافت کنید.
  • برای دریافت داده‌های به‌روزرسانی‌شده پس از اعلان با EventType.RESPONSES ، تابع forms.responses.list() را فراخوانی کنید.
    • فیلتر روی درخواست را روی timestamp > timestamp_of_the_last_response_you_fetched تنظیم کنید.
  • برای دریافت داده‌های به‌روزرسانی‌شده پس از اعلان با EventType.SCHEMA ، تابع forms.get() را فراخوانی کنید.