Menyiapkan dan menerima notifikasi push

Anda dapat menggunakan metode dalam koleksi Watches untuk menerima notifikasi saat data berubah dalam formulir. Halaman ini memberikan ringkasan konseptual dan petunjuk untuk menyiapkan dan menerima notifikasi push.

Ringkasan

Fitur notifikasi push Google Form API memungkinkan aplikasi untuk berlangganan notifikasi saat data berubah dalam formulir. Notifikasi dikirimkan ke topik Cloud Pub/Sub, biasanya dalam beberapa menit setelah perubahan.

Untuk menerima notifikasi push, Anda perlu menyiapkan topik Cloud Pub/Sub dan memberikan nama topik tersebut saat membuat smartwatch untuk jenis peristiwa yang sesuai.

Berikut adalah definisi konsep utama yang digunakan dalam dokumentasi ini:

  • Target adalah tempat notifikasi dikirim. Satu-satunya target yang didukung adalah topik Cloud Pub/Sub.
  • Jenis peristiwa adalah kategori notifikasi yang dapat diikuti oleh aplikasi pihak ketiga.
  • Smartwatch adalah petunjuk ke Formulir API untuk mengirimkan notifikasi untuk jenis peristiwa tertentu dalam formulir tertentu ke target.

Setelah Anda membuat smartwatch untuk jenis peristiwa pada formulir tertentu, target smartwatch tersebut (yang merupakan topik Cloud Pub/Sub) akan menerima notifikasi dari peristiwa pada formulir tersebut hingga masa berlaku smartwatch berakhir. Smartwatch Anda dapat bertahan seminggu, tetapi Anda dapat memperpanjangnya kapan saja sebelum habis masa berlakunya dengan membuat permintaan ke watches.renew().

Topik Cloud Pub/Sub Anda hanya menerima notifikasi tentang formulir yang dapat Anda lihat dengan kredensial yang Anda berikan. Misalnya, jika pengguna mencabut izin dari aplikasi atau kehilangan akses edit ke formulir yang diawasi, notifikasi tidak akan dikirimkan lagi.

Jenis peristiwa yang tersedia

Google Formulir API saat ini menawarkan dua kategori acara:

  • EventType.SCHEMA, yang memberi notifikasi saat ada pengeditan konten dan setelan formulir.
  • EventType.RESPONSES, yang memberi tahu saat respons formulir (baik yang baru maupun diperbarui) dikirim.

Respons notifikasi

Notifikasi dienkode dengan JSON dan berisi:

  • ID formulir pemicu
  • ID smartwatch pemicu
  • Jenis peristiwa yang memicu notifikasi
  • Kolom lain yang ditetapkan oleh Cloud Pub/Sub, seperti messageId dan publishTime

Notifikasi tidak berisi data respons atau formulir yang mendetail. Setelah setiap notifikasi diterima, panggilan API terpisah diperlukan untuk mengambil data baru. Lihat Penggunaan yang disarankan untuk mengetahui cara melakukannya.

Cuplikan berikut menunjukkan contoh notifikasi untuk perubahan skema:

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

Cuplikan berikut menunjukkan contoh notifikasi untuk respons baru:

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

Menyiapkan topik Cloud Pub/Sub

Notifikasi dikirim ke topik Cloud Pub/Sub. Dari Cloud Pub/Sub, Anda dapat menerima notifikasi di hook web, atau dengan melakukan polling pada endpoint langganan.

Untuk menyiapkan topik Cloud Pub/Sub, lakukan langkah berikut:

  1. Selesaikan Prasyarat Cloud Pub/Sub.
  2. Menyiapkan klien Cloud Pub/Sub.
  3. Tinjau harga Cloud Pub/Sub, dan aktifkan penagihan untuk project Konsol Developer Anda.
  4. Buat topik Cloud Pub/Sub dengan salah satu dari tiga cara berikut:

  5. Buat Langganan di Cloud Pub/Sub untuk memberi tahu Cloud Pub/Sub cara mengirimkan notifikasi.

  6. Terakhir, sebelum membuat smartwatch yang menargetkan topik, Anda harus memberikan izin ke akun layanan notifikasi Formulir (forms-notifications@system.gserviceaccount.com) untuk memublikasikan ke topik Anda.

Buat smartwatch

Setelah memiliki topik yang dapat dipublikasikan oleh akun layanan notifikasi push Formulir API, Anda dapat membuat notifikasi menggunakan metode watches.create(). Metode ini memvalidasi bahwa topik Cloud Pub/Sub yang disediakan dapat diakses oleh akun layanan notifikasi push, dan akan gagal jika tidak dapat menjangkau topik tersebut. Misalnya, jika topik tidak ada atau Anda belum memberikan izin publikasi pada topik tersebut.

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

Menghapus smartwatch

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

form/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;

Otorisasi

Seperti semua panggilan ke Formulir API, panggilan ke watches.create() harus diotorisasi dengan token otorisasi. Token tersebut harus menyertakan cakupan yang memberikan akses baca ke data tentang notifikasi mana yang dikirim.

Agar notifikasi dikirimkan, aplikasi harus mempertahankan pemberian izin OAuth dari pengguna yang diberi otorisasi dengan cakupan yang diperlukan. Jika pengguna memutuskan koneksi aplikasi, notifikasi akan berhenti dan smartwatch dapat ditangguhkan saat terjadi error. Untuk melanjutkan notifikasi setelah mendapatkan otorisasi kembali, lihat Memperpanjang smartwatch.

Menampilkan daftar smartwatch formulir

Python

form/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

form/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;

Perpanjang smartwatch

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

form/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

Notifikasi dibatasi—setiap smartwatch dapat menerima maksimal satu notifikasi setiap tiga puluh detik. Batas frekuensi ini dapat berubah.

Karena throttling, satu notifikasi mungkin berkaitan dengan beberapa peristiwa. Dengan kata lain, notifikasi menunjukkan bahwa satu atau beberapa peristiwa telah terjadi sejak notifikasi terakhir.

Batas

Kapan pun, untuk formulir dan jenis peristiwa tertentu, setiap project Konsol Cloud dapat memiliki:

  • total hingga 20 tontonan
  • hingga satu smartwatch per pengguna akhir

Selain itu, setiap saat dibatasi hingga total 50 smartwatch per jenis peristiwa di seluruh project Konsol Cloud.

Smartwatch dikaitkan dengan pengguna akhir saat dibuat atau diperpanjang dengan kredensial untuk pengguna tersebut. Smartwatch ditangguhkan jika pengguna akhir yang terkait kehilangan akses ke formulir atau mencabut akses aplikasi ke formulir tersebut.

Keandalan

Setiap smartwatch akan diberi tahu setidaknya sekali setelah setiap peristiwa dalam segala hal kecuali keadaan yang luar biasa. Pada umumnya, notifikasi dikirimkan dalam hitungan menit setelah peristiwa.

Error

Jika notifikasi untuk smartwatch terus gagal dikirimkan, status smartwatch menjadi SUSPENDED dan kolom errorType smartwatch akan disetel. Untuk mereset status smartwatch yang ditangguhkan ke ACTIVE dan melanjutkan notifikasi, lihat Memperpanjang smartwatch.

Penggunaan yang disarankan

  • Menggunakan satu topik Cloud Pub/Sub sebagai target dari banyak smartwatch.
  • Saat menerima notifikasi tentang topik, ID formulir akan disertakan dalam payload notifikasi. Gunakan peristiwa ini bersama jenis peristiwa untuk mengetahui data yang akan diambil dan bentuk untuk diambil.
  • Untuk mengambil data yang diperbarui setelah notifikasi dengan EventType.RESPONSES, panggil forms.responses.list().
    • Tetapkan filter pada permintaan ke timestamp > timestamp_of_the_last_response_you_fetched.
  • Untuk mengambil data yang diperbarui setelah notifikasi dengan EventType.SCHEMA, panggil forms.get().