Configura e ricevi notifiche push

Puoi utilizzare i metodi della raccolta Watches per ricevere notifiche quando i dati cambiano nei moduli. Questa pagina fornisce una panoramica concettuale e istruzioni per configurare e ricevere notifiche push.

Panoramica

La funzionalità di notifiche push dell'API Google Forms consente alle applicazioni di iscriversi alle notifiche quando i dati cambiano nei moduli. Le notifiche vengono inviate a un argomento Cloud Pub/Sub, in genere entro pochi minuti dalla modifica.

Per ricevere notifiche push, devi configurare un argomento Cloud Pub/Sub e fornire il nome dell'argomento quando crei un monitoraggio per il tipo di evento appropriato.

Di seguito sono riportate le definizioni dei concetti chiave utilizzati in questa documentazione:

  • Una destinazione è un luogo in cui vengono inviate le notifiche. L'unica destinazione supportata è un argomento Cloud Pub/Sub.
  • Un tipo di evento è una categoria di notifiche a cui un'applicazione di terze parti può iscriversi.
  • Un watch è un'istruzione per l'API Forms per inviare notifiche per un particolare tipo di evento su un particolare modulo a un target.

Una volta creato un monitoraggio per un tipo di evento su un determinato modulo, la destinazione del monitoraggio (che è un argomento Cloud Pub/Sub) riceve notifiche da questi eventi sul modulo fino alla scadenza del monitoraggio. La tua estensione dura una settimana, ma puoi prolungarla in qualsiasi momento prima della scadenza inviando una richiesta a watches.renew().

L'argomento Cloud Pub/Sub riceve solo notifiche relative ai moduli che puoi visualizzare con le credenziali fornite. Ad esempio, se l'utente revoca l'autorizzazione dalla tua applicazione o perde l'accesso in modifica a un modulo monitorato, le notifiche non vengono più inviate.

Tipi di evento disponibili

L'API Google Forms attualmente offre due categorie di eventi:

  • EventType.SCHEMA, che invia notifiche relative alle modifiche ai contenuti e alle impostazioni di un modulo.
  • EventType.RESPONSES, che invia una notifica quando vengono inviate risposte al modulo (sia nuove che aggiornate).

Risposte alle notifiche

Le notifiche sono codificate in formato JSON e contengono:

  • L'ID del modulo di attivazione
  • L'ID dell'orologio che ha attivato l'azione
  • Il tipo di evento che ha attivato la notifica
  • Altri campi impostati da Cloud Pub/Sub, come messageId e publishTime

Le notifiche non contengono dati dettagliati del modulo o delle risposte. Dopo aver ricevuto ogni notifica, è necessaria una chiamata API separata per recuperare i dati aggiornati. Per scoprire come fare, consulta la sezione Utilizzo suggerito.

Il seguente snippet mostra una notifica di esempio per una modifica dello schema:

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

Il seguente snippet mostra una notifica di esempio per una nuova risposta:

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

Configurare un argomento Cloud Pub/Sub

Le notifiche vengono inviate agli argomenti Cloud Pub/Sub. Da Cloud Pub/Sub puoi ricevere notifiche su un webhook o eseguendo il polling di un endpoint di abbonamento.

Per configurare un argomento Cloud Pub/Sub:

  1. Completa i prerequisiti di Cloud Pub/Sub.
  2. Configura un client Cloud Pub/Sub.
  3. Esamina i prezzi di Cloud Pub/Sub e attiva la fatturazione per il tuo progetto Developer Console.
  4. Crea un argomento Cloud Pub/Sub in uno dei tre modi seguenti:

  5. Crea una sottoscrizione in Cloud Pub/Sub per indicare a Cloud Pub/Sub come inviare le notifiche.

  6. Infine, prima di creare le notifiche che hanno come target il tuo argomento, devi concedere l'autorizzazione all'account di servizio di Notifiche di moduli (forms-notifications@system.gserviceaccount.com) per pubblicare nel tuo argomento.

Crea un orologio

Una volta creato un argomento a cui l'account di servizio di notifica push dell'API Forms può pubblicare, puoi creare notifiche utilizzando il metodo watches.create(). Questo metodo verifica che l'argomento Cloud Pub/Sub fornito sia raggiungibile dall'account di servizio delle notifiche push e non riesce a raggiungere l'argomento, ad esempio se l'argomento non esiste o se non hai concesso l'autorizzazione di pubblicazione per quell'argomento.

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

Eliminare uno 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

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

Autorizzazione

Come tutte le chiamate all'API Forms, le chiamate a watches.create() devono essere autorizzate con un token di autorizzazione. Il token deve includere un ambito che conceda l'accesso in lettura ai dati relativi alle notifiche inviate.

Per la ricezione delle notifiche, l'applicazione deve conservare una concessione OAuth dell'utente autorizzato con gli ambiti richiesti. Se l'utente disconnette l'applicazione, le notifiche cessano e lo smartwatch potrebbe essere sospeso con un errore. Per riprendere a ricevere le notifiche dopo aver ottenuto di nuovo l'autorizzazione, vedi Rinnovare uno smartwatch.

Elencare gli orologi di un modulo

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

Rinnovare uno 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

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

Limitazione

Le notifiche vengono limitate: ogni orologio può ricevere al massimo una notifica ogni 30 secondi. Questa soglia di frequenza è soggetta a modifiche.

A causa della limitazione, una singola notifica può corrispondere a più eventi. In altre parole, una notifica indica che si sono verificati uno o più eventi dall'ultima notifica.

Limiti

In qualsiasi momento, per un determinato modulo e tipo di evento, ogni progetto della console Google Cloud può avere:

  • fino a 20 visualizzazioni totali
  • fino a uno smartwatch per utente finale

Inoltre, in qualsiasi momento, ogni modulo è limitato a 50 visualizzazioni per tipo di evento in totale in tutti i progetti della console Google Cloud.

Uno smartwatch viene associato a un utente finale quando viene creato o rinnovato con le credenziali di quell'utente. Un orologio viene sospeso se l'utente finale associato perde l'accesso al modulo o revoca l'accesso dell'app al modulo.

Affidabilità

Ogni orologio riceve una notifica almeno una volta dopo ogni evento, salvo circostanze straordinarie. Nella stragrande maggioranza dei casi, una notifica viene inviata entro pochi minuti da un evento.

Errori

Se le notifiche per uno smartwatch non vengono recapitate in modo persistente, lo stato dello smartwatch diventa SUSPENDED e viene impostato il campo errorType dello smartwatch. Per ripristinare lo stato di un orologio sospeso su ACTIVE e riprendere le notifiche, consulta Rinnovare un orologio.

Utilizzo suggerito

  • Utilizza un singolo argomento Cloud Pub/Sub come target di molti orologi.
  • Quando ricevi una notifica su un argomento, l'ID modulo è incluso nel payload della notifica. Utilizzalo con il tipo di evento per sapere quali dati recuperare e da quale modulo recuperarli.
  • Per recuperare i dati aggiornati dopo una notifica con EventType.RESPONSES, chiama forms.responses.list().
    • Imposta il filtro sulla richiesta su timestamp > timestamp_of_the_last_response_you_fetched.
  • Per recuperare i dati aggiornati dopo una notifica con EventType.SCHEMA, chiama forms.get().