ตั้งค่าและรับข้อความ Push

คุณสามารถใช้วิธีการใน Watches คอลเล็กชันเพื่อ รับการแจ้งเตือนเมื่อข้อมูลในแบบฟอร์มมีการเปลี่ยนแปลง หน้านี้ให้ภาพรวมเชิงแนวคิดและวิธีการตั้งค่าและรับการแจ้งเตือนแบบพุช

ภาพรวม

ฟีเจอร์การแจ้งเตือนแบบพุชของ Google Forms API ช่วยให้แอปพลิเคชันสมัครรับการแจ้งเตือนเมื่อข้อมูลในแบบฟอร์มมีการเปลี่ยนแปลง ระบบจะส่งการแจ้งเตือนไปยัง หัวข้อ Cloud Pub/Sub โดยปกติแล้วจะใช้เวลาไม่กี่ นาทีหลังจากมีการเปลี่ยนแปลง

หากต้องการรับการแจ้งเตือนแบบพุช คุณต้องตั้งค่าหัวข้อ Cloud Pub/Sub และระบุชื่อหัวข้อเมื่อสร้างการดูสำหรับประเภทเหตุการณ์ที่เหมาะสม

ด้านล่างนี้คือคำจำกัดความของแนวคิดหลักที่ใช้ในเอกสารนี้

  • เป้าหมาย คือสถานที่ที่ระบบจะส่งการแจ้งเตือน เป้าหมายเดียวที่รองรับคือหัวข้อ Cloud Pub/Sub
  • ประเภทเหตุการณ์ คือหมวดหมู่ของการแจ้งเตือนที่แอปพลิเคชันของบุคคลที่สามสามารถสมัครรับได้
  • การดู คือคำสั่งที่ส่งไปยัง Forms API เพื่อส่งการแจ้งเตือนสำหรับ ประเภทเหตุการณ์ ที่เฉพาะเจาะจงในแบบฟอร์มที่เฉพาะเจาะจงไปยัง เป้าหมาย

เมื่อสร้างการดูสำหรับประเภทเหตุการณ์ในแบบฟอร์มที่เฉพาะเจาะจงแล้ว เป้าหมายของการดูนั้น (ซึ่งเป็นหัวข้อ Cloud Pub/Sub) จะได้รับการแจ้งเตือนจากเหตุการณ์เหล่านั้นในแบบฟอร์มนั้นจนกว่าการดูจะหมดอายุ การดูจะมีอายุ 1 สัปดาห์ แต่คุณ สามารถขยายระยะเวลาได้ทุกเมื่อก่อนที่จะหมดอายุโดยส่งคำขอไปยัง watches.renew()

หัวข้อ Cloud Pub/Sub จะได้รับการแจ้งเตือนเกี่ยวกับแบบฟอร์มที่คุณดูได้ด้วยข้อมูลเข้าสู่ระบบที่คุณระบุไว้เท่านั้น ตัวอย่างเช่น หากผู้ใช้เพิกถอนสิทธิ์จากแอปพลิเคชันของคุณหรือสูญเสียสิทธิ์เข้าถึงแบบฟอร์มที่ดูอยู่ ระบบจะไม่ส่งการแจ้งเตือนอีกต่อไป

ประเภทเหตุการณ์ที่มี

ปัจจุบัน Google Forms API มีเหตุการณ์ 2 หมวดหมู่ ได้แก่

  • 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 คุณสามารถรับการแจ้งเตือนใน Webhook หรือโดยการโพลปลายทางการสมัครใช้บริการจาก Cloud Pub/Sub

หากต้องการตั้งค่าหัวข้อ Cloud Pub/Sub ให้ทำดังนี้

  1. ทำตามข้อกำหนดเบื้องต้นของ Cloud Pub/Sub
  2. ตั้งค่าไคลเอ็นต์ Cloud Pub/Sub
  3. ตรวจสอบราคาของ Cloud Pub/Sub และเปิดใช้การเรียกเก็บเงินสำหรับโปรเจ็กต์คอนโซล Google Cloud
  4. สร้างหัวข้อ Cloud Pub/Sub ได้ 3 วิธี ดังนี้

  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 using 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;
}

การควบคุม

ระบบจะควบคุมการแจ้งเตือน โดยการดูแต่ละรายการจะได้รับการแจ้งเตือนอย่างน้อย 1 ครั้งทุกๆ 30 วินาที เกณฑ์ความถี่นี้อาจมีการเปลี่ยนแปลง

เนื่องจากการควบคุม การแจ้งเตือนเดียวอาจสอดคล้องกับเหตุการณ์หลายรายการ กล่าวอีกนัยหนึ่งคือ การแจ้งเตือนจะระบุว่ามีเหตุการณ์อย่างน้อย 1 รายการเกิดขึ้นนับตั้งแต่การแจ้งเตือนครั้งล่าสุด

จำกัดสูงสุด

โปรเจ็กต์คอนโซล Google Cloud แต่ละโปรเจ็กต์สามารถมีรายการต่อไปนี้สำหรับแบบฟอร์มและประเภทเหตุการณ์ที่กำหนด

  • การดูทั้งหมดสูงสุด 20 รายการ
  • การดูสูงสุด 1 รายการต่อผู้ใช้ปลายทาง 1 คน

นอกจากนี้ แบบฟอร์มแต่ละรายการยังจำกัดการดูสูงสุด 50 รายการต่อประเภทเหตุการณ์ทั้งหมดในโปรเจ็กต์คอนโซล Google Cloud ทั้งหมด

ระบบจะเชื่อมโยงการดูกับผู้ใช้ปลายทางเมื่อสร้างหรือต่ออายุด้วยข้อมูลเข้าสู่ระบบของผู้ใช้รายนั้น ระบบจะระงับการดูหากผู้ใช้ปลายทางที่เชื่อมโยงสูญเสียสิทธิ์เข้าถึงแบบฟอร์มหรือเพิกถอนสิทธิ์เข้าถึงแบบฟอร์มของแอป

ความน่าเชื่อถือ

ระบบจะแจ้งเตือนการดูแต่ละรายการอย่างน้อย 1 ครั้งหลังจากเกิดเหตุการณ์แต่ละรายการ ยกเว้นในสถานการณ์พิเศษ ในกรณีส่วนใหญ่ ระบบจะส่งการแจ้งเตือนภายในไม่กี่นาทีหลังจากเกิดเหตุการณ์

ข้อผิดพลาด

หากระบบส่งการแจ้งเตือนสำหรับการดูรายการหนึ่งๆ ไม่สำเร็จอย่างต่อเนื่อง สถานะการดูจะเปลี่ยนเป็น SUSPENDED และระบบจะตั้งค่าฟิลด์ errorType ของการดู หากต้องการรีเซ็ตสถานะการดูที่ถูกระงับเป็น ACTIVE และรับการแจ้งเตือนต่อ โปรดดูต่ออายุการดู

การใช้งานที่แนะนำ

  • ใช้หัวข้อ Cloud Pub/Sub เดียวเป็นเป้าหมายของการดูหลายรายการ
  • เมื่อรับการแจ้งเตือนในหัวข้อ รหัสแบบฟอร์มจะรวมอยู่ในเพย์โหลดการแจ้งเตือน ใช้รหัสนี้กับประเภทเหตุการณ์เพื่อดูว่าต้องดึงข้อมูลใดและดึงจากแบบฟอร์มใด
  • หากต้องการดึงข้อมูลที่อัปเดตแล้วหลังจากได้รับการแจ้งเตือนที่มี EventType.RESPONSES ให้เรียกใช้ forms.responses.list()
    • ตั้งค่าตัวกรองในคำขอเป็น timestamp > timestamp_of_the_last_response_you_fetched
  • หากต้องการดึงข้อมูลที่อัปเดตแล้วหลังจากได้รับการแจ้งเตือนที่มี EventType.SCHEMA ให้เรียกใช้ forms.get()