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

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

بررسی اجمالی

ویژگی اعلان‌های فشاری API Google Forms به برنامه‌ها اجازه می‌دهد تا زمانی که داده‌ها در فرم‌ها تغییر می‌کنند، در اعلان‌ها مشترک شوند. اعلان‌ها معمولاً در عرض چند دقیقه پس از تغییر به یک موضوع 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

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

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

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

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

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

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

هنگامی که موضوعی دارید که حساب سرویس فشار اعلان‌های API Forms می‌تواند در آن منتشر کند، می‌توانید با استفاده از متد watches.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)

Node.js

forms/snippets/create_watch.js
'use strict';

const path = require('path');
const google = require('@googleapis/forms');
const {authenticate} = require('@google-cloud/local-auth');

const formID = '<YOUR_FORM_ID>';

async function runSample(query) {
  const authClient = await authenticate({
    keyfilePath: path.join(__dirname, 'credentials.json'),
    scopes: 'https://www.googleapis.com/auth/drive',
  });
  const forms = google.forms({
    version: 'v1',
    auth: authClient,
  });
  const watchRequest = {
    watch: {
      target: {
        topic: {
          topicName: 'projects/<YOUR_TOPIC_PATH>',
        },
      },
      eventType: 'RESPONSES',
    },
  };
  const res = await forms.forms.watches.create({
    formId: formID,
    requestBody: watchRequest,
  });
  console.log(res.data);
  return res.data;
}

if (module === require.main) {
  runSample().catch(console.error);
}
module.exports = runSample;

یک ساعت را حذف کنید

پایتون

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
'use strict';

const path = require('path');
const google = require('@googleapis/forms');
const {authenticate} = require('@google-cloud/local-auth');

const formID = '<YOUR_FORM_ID>';
const watchID = '<YOUR_FORMS_WATCH_ID>';

async function runSample(query) {
  const authClient = await authenticate({
    keyfilePath: path.join(__dirname, 'credentials.json'),
    scopes: 'https://www.googleapis.com/auth/drive',
  });
  const forms = google.forms({
    version: 'v1',
    auth: authClient,
  });
  const res = await forms.forms.watches.delete({
    formId: formID,
    watchId: watchID,
  });
  console.log(res.data);
  return res.data;
}

if (module === require.main) {
  runSample().catch(console.error);
}
module.exports = runSample;

مجوز

مانند همه تماس‌های Forms API، تماس‌های watches.create() باید با یک نشانه مجوز مجاز باشد. توکن باید شامل محدوده‌ای باشد که به داده‌هایی که اعلان‌ها درباره آن‌ها ارسال می‌شوند، دسترسی خواندن می‌دهد.

  • برای تغییرات طرحواره، این به معنای هر محدوده ای است که از طریق forms.get() به فرم ها دسترسی خواندن می دهد.
  • برای پاسخ‌ها، این به معنای هر محدوده‌ای است که به پاسخ‌های فرم دسترسی خواندن می‌دهد، برای مثال از طریق forms.responses.list() .

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

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

پایتون

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
'use strict';

const path = require('path');
const google = require('@googleapis/forms');
const {authenticate} = require('@google-cloud/local-auth');

const formID = '<YOUR_FORM_ID>';

async function runSample(query) {
  const auth = await authenticate({
    keyfilePath: path.join(__dirname, 'credentials.json'),
    scopes: 'https://www.googleapis.com/auth/forms.responses.readonly',
  });
  const forms = google.forms({
    version: 'v1',
    auth: auth,
  });
  const res = await forms.forms.watches.list({formId: formID});
  console.log(res.data);
  return res.data;
}

if (module === require.main) {
  runSample().catch(console.error);
}
module.exports = runSample;

یک ساعت را تمدید کنید

پایتون

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
'use strict';

const path = require('path');
const google = require('@googleapis/forms');
const {authenticate} = require('@google-cloud/local-auth');

const formID = '<YOUR_FORM_ID>';
const watchID = '<YOUR_FORMS_WATCH_ID>';

async function runSample(query) {
  const authClient = await authenticate({
    keyfilePath: path.join(__dirname, 'credentials.json'),
    scopes: 'https://www.googleapis.com/auth/drive',
  });
  const forms = google.forms({
    version: 'v1',
    auth: authClient,
  });
  const res = await forms.forms.watches.renew({
    formId: formID,
    watchId: watchID,
  });
  console.log(res.data);
  return res.data;
}

if (module === require.main) {
  runSample().catch(console.error);
}
module.exports = runSample;

گاز دادن

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

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

محدودیت ها

در هر زمان، برای یک فرم و نوع رویداد معین، هر پروژه 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() تماس بگیرید.