Configura e ricevi notifiche push

Puoi utilizzare i metodi nella raccolta Smartwatch per ricevere notifiche quando i dati cambiano nei moduli. Questa pagina fornisce una panoramica concettuale e le istruzioni per impostare e ricevere notifiche push.

Panoramica

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

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

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

  • Un target è il luogo a cui vengono inviate le notifiche. L'unico target supportato è un argomento Cloud Pub/Sub.
  • Un tipo di evento è una categoria di notifiche a cui un'applicazione di terze parti può iscriversi.
  • Uno smartwatch è un'istruzione all'API Moduli per inviare notifiche per un particolare tipo di evento su un determinato modulo a un target.

Dopo aver creato uno smartwatch per un tipo di evento in un determinato modulo, il target dello smartwatch (ovvero un argomento Cloud Pub/Sub) riceve le notifiche da questi eventi su quel modulo fino alla scadenza dello smartwatch. Il tuo smartwatch dura una settimana, ma puoi estenderlo in qualsiasi momento prima che scada 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 all'applicazione o perde l'accesso in modifica a un modulo guardato, le notifiche non vengono più consegnate.

Tipi di evento disponibili

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

  • EventType.SCHEMA, che notifica le modifiche ai contenuti e alle impostazioni di un modulo.
  • EventType.RESPONSES, che avvisa quando vengono inviate risposte del modulo (nuove e aggiornate).

Risposte alle notifiche

Le notifiche sono codificate con JSON e contengono:

  • ID del modulo di attivazione
  • L'ID dello smartwatch che attiva
  • 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 dei moduli o delle risposte. Dopo aver ricevuto ogni notifica, è necessaria una chiamata API separata per recuperare i dati aggiornati. Per scoprire come eseguire questa operazione, consulta Utilizzo suggerito.

Lo snippet seguente mostra una notifica di esempio per una modifica allo schema:

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

Lo snippet seguente 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"
}

Configura un argomento Cloud Pub/Sub

Le notifiche vengono recapitate agli argomenti di Cloud Pub/Sub. Da Cloud Pub/Sub, puoi ricevere notifiche su un webhook 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. Consulta i prezzi di Cloud Pub/Sub e abilita la fatturazione per il tuo progetto della Developer Console.
  4. Puoi creare 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 smartwatch che hanno come target l'argomento, devi concedere l'autorizzazione all'account di servizio notifiche di Moduli (forms-notifications@system.gserviceaccount.com) per pubblicare nell'argomento.

Crea uno smartwatch

Una volta disponibile un argomento in cui l'account di servizio per le notifiche push dell'API Moduli 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 è in grado di raggiungere l'argomento, ad esempio se l'argomento non esiste o se non gli hai concesso l'autorizzazione di pubblicazione su 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
'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;

Elimina 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

moduli/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 tutte le chiamate all'API Moduli, le chiamate a watches.create() devono essere autorizzate con un token di autorizzazione. Il token deve includere un ambito che concede l'accesso in lettura ai dati relativi ai tipi di notifiche che vengono inviate.

Affinché le notifiche vengano recapitate, l'applicazione deve conservare una concessione OAuth dell'utente autorizzato con gli ambiti richiesti. Se l'utente disconnette l'applicazione, le notifiche vengono interrotte e lo smartwatch potrebbe essere sospeso con un errore. Per riprendere le notifiche dopo aver recuperato l'autorizzazione, consulta Rinnovare un orologio.

Elenco degli smartwatch di un modulo

Python

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

moduli/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 un orologio

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

moduli/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 sono limitate: ogni smartwatch 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 Cloud può avere:

  • Fino a 20 visualizzazioni in totale
  • fino a uno smartwatch per utente finale

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

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

Affidabilità

Ogni smartwatch riceve una notifica almeno una volta dopo ogni evento in tutte le circostanze tranne quelle straordinarie. Nella stragrande maggioranza dei casi, una notifica viene consegnata entro pochi minuti da un evento.

Errori

Se le notifiche per uno smartwatch continuano a non essere consegnate, lo stato dell'orologio diventa SUSPENDED e il campo errorType dello smartwatch viene impostato. Per reimpostare 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 più smartwatch.
  • Quando ricevi una notifica su un argomento, l'ID modulo viene incluso nel payload della notifica. Utilizzalo con il tipo di evento per sapere quali dati recuperare e da quale modulo.
  • Per recuperare i dati aggiornati dopo una notifica con EventType.RESPONSES, chiama forms.responses.list().
    • Imposta il filtro nella richiesta su timestamp > timestamp_of_the_last_response_you_fetched.
  • Per recuperare i dati aggiornati dopo una notifica con EventType.SCHEMA, chiama forms.get().