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 le istruzioni per configurare e ricevere le 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'osservazione per il tipo di evento appropriato.

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

  • Un target è un luogo in cui vengono inviate le notifiche. L'unico 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 monitoraggio è un'istruzione all'API Forms per inviare notifiche per un determinato tipo di evento in un determinato modulo a un target.

Una volta creato un monitoraggio per un tipo di evento in un determinato modulo, il suo target (un argomento Cloud Pub/Sub) riceve notifiche da questi eventi nel modulo fino alla scadenza del monitoraggio. Lo smartwatch dura una settimana, ma puoi estendere la sua durata in qualsiasi momento prima della scadenza inviando una richiesta a watches.renew().

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

Tipi di eventi disponibili

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

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

Risposte alle notifiche

Le notifiche sono codificate in JSON e contengono:

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

Le notifiche non contengono dati dettagliati su moduli o risposte. Dopo ogni notifica ricevuta, è necessaria una chiamata API separata per recuperare i dati aggiornati. Per scoprire come, 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 web hook o eseguendo il polling di un endpoint di sottoscrizione.

Per configurare un argomento Cloud Pub/Sub, segui questi passaggi:

  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 della Console per gli sviluppatori.
  4. Crea un argomento Cloud Pub/Sub in tre modi:

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

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

Creare uno smartwatch

Una volta creato un argomento su cui l'account di servizio per le notifiche push dell'API Forms può pubblicare, puoi creare notifiche utilizzando il metodo watches.create(). Questo metodo convalida che l'argomento Cloud Pub/Sub fornito possa essere raggiunto dall'account di servizio delle notifiche push e non va a buon fine se non riesce a raggiungere l'argomento, ad esempio se l'argomento non esiste o non gli è stata concessa l'autorizzazione di pubblicazione per quell'argomento.

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

Eliminare uno smartwatch

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

Autorizzazione

Come per 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 consenta l'accesso in lettura ai dati relativi alle notifiche inviate.

Affinché le notifiche vengano inviate, l'applicazione deve conservare una concessione OAuth dall'utente autorizzato con gli ambiti richiesti. Se l'utente scollega l'applicazione, le notifiche vengono interrotte e lo smartwatch potrebbe essere sospeso con un errore. Per riprendere le notifiche dopo aver ottenuto nuovamente l'autorizzazione, consulta Rinnovare uno smartwatch.

Elencare gli orologi di un modulo

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

Rinnovare uno smartwatch

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

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 tipo di modulo e di evento, ogni progetto della console Cloud può avere:

  • fino a 20 visualizzazioni totali
  • fino a un orologio per utente finale

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

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

Affidabilità

A ogni orologio viene inviata una notifica almeno una volta dopo ogni evento, tranne in circostanze eccezionali. Nella maggior parte 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 il campo errorType dello smartwatch viene impostato. Per reimpostare lo stato di un smartwatch sospeso su ACTIVE e riprendere le notifiche, consulta Rinnovare uno smartwatch.

Utilizzo suggerito

  • Utilizza un singolo argomento Cloud Pub/Sub come target di molti monitor.
  • 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 della richiesta su timestamp > timestamp_of_the_last_response_you_fetched.
  • Per recuperare i dati aggiornati dopo una notifica con EventType.SCHEMA, chiama forms.get().