Konfigurowanie i odbieranie powiadomień push

Możesz korzystać z metod z kolekcji Zegarki, aby otrzymywać powiadomienia o zmianie danych w formularzach. Ta strona zawiera ogólny opis oraz instrukcje konfigurowania i odbierania powiadomień push.

Opis

Funkcja powiadomień push interfejsu API Formularzy Google pozwala aplikacjom na subskrybowanie powiadomień o zmianie danych w formularzach. Powiadomienia są dostarczane do tematu Cloud Pub/Sub, zwykle w ciągu kilku minut od wprowadzenia zmiany.

Aby otrzymywać powiadomienia push, musisz skonfigurować temat Cloud Pub/Sub i podać jego nazwę podczas tworzenia zegarka dla odpowiedniego typu zdarzenia.

Poniżej znajdziesz definicje kluczowych pojęć wykorzystywanych w tej dokumentacji:

  • Cel to miejsce, do którego wysyłane są powiadomienia. Jedynym obsługiwanym miejscem docelowym jest temat Cloud Pub/Sub.
  • Typ zdarzenia to kategoria powiadomień, które mogą subskrybować aplikacja innej firmy.
  • Zegarek to instrukcja do interfejsu API Formularzy, która służy do wysyłania powiadomień do elementów docelowych określonego typu zdarzenia w konkretnym formularzu.

Gdy utworzysz obserwację dla danego typu zdarzenia w konkretnym formularzu, do jego celu (czyli tematu Cloud Pub/Sub) będziesz otrzymywać powiadomienia o tych zdarzeniach w tym formularzu, dopóki nie wygaśnie. Zegarek działa przez tydzień, ale w dowolnym momencie przed wygaśnięciem możesz go przedłużyć, wysyłając żądanie do watches.renew().

Temat Cloud Pub/Sub otrzymuje powiadomienia tylko o formularzach, które możesz wyświetlić za pomocą podanych przez Ciebie danych logowania. Jeśli na przykład użytkownik wycofa uprawnienia aplikacji lub utraci uprawnienia do edycji obserwowanego formularza, powiadomienia nie będą już dostarczane.

Dostępne typy zdarzeń

Interfejs API Formularzy Google udostępnia obecnie 2 kategorie wydarzeń:

  • EventType.SCHEMA, który powiadamia o zmianach w treści i ustawieniach formularza.
  • EventType.RESPONSES, który powiadamia o przesłaniu odpowiedzi (nowych i zaktualizowanych).

Odpowiedzi na powiadomienia

Powiadomienia są zakodowane w formacie JSON i zawierają:

  • Identyfikator formularza aktywującego
  • Identyfikator zegarka wyzwalającego
  • Typ zdarzenia, które wywołało powiadomienie
  • Inne pola ustawione przez Cloud Pub/Sub, takie jak messageId i publishTime

Powiadomienia nie zawierają szczegółowych danych formularza ani odpowiedzi. Po otrzymaniu każdego powiadomienia do pobrania aktualnych danych wymagane jest osobne wywołanie interfejsu API. Aby dowiedzieć się, jak to zrobić, zapoznaj się z sekcją Polecane zastosowania.

Ten fragment kodu pokazuje przykładowe powiadomienie o zmianie schematu:

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

Ten fragment kodu ilustruje przykładowe powiadomienie o nowej odpowiedzi:

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

Skonfiguruj temat Cloud Pub/Sub

Powiadomienia są dostarczane do tematów Cloud Pub/Sub. Powiadomienia z Cloud Pub/Sub możesz otrzymywać przez webhooka lub odpytywanie punktu końcowego subskrypcji.

Aby skonfigurować temat Cloud Pub/Sub, wykonaj te czynności:

  1. Spełnij wymagania wstępne Cloud Pub/Sub.
  2. skonfigurować klienta Cloud Pub/Sub;
  3. Sprawdź cennik Cloud Pub/Sub i włącz płatności za projekt w Konsoli programisty.
  4. Utwórz temat Cloud Pub/Sub na 1 z 3 sposobów:

  5. Utwórz subskrypcję w Cloud Pub/Sub, aby poinformować Cloud Pub/Sub o sposobie dostarczania powiadomień.

  6. Na koniec, zanim utworzysz zegarki kierowane na Twój temat, musisz przyznać uprawnienia kontu usługi powiadomień Formularzy (forms-notifications@system.gserviceaccount.com), aby móc publikować w tym temacie.

Utwórz zegarek

Jeśli masz temat, w którym konto usługi powiadomień push interfejsu Formularzy API może publikować, możesz tworzyć powiadomienia za pomocą metody watches.create(). Ta metoda sprawdza, czy konto usługi powiadomień push może dotrzeć do podanego tematu Cloud Pub/Sub, i kończy się niepowodzeniem, jeśli temat nie jest dostępny, na przykład jeśli temat nie istnieje lub nie masz uprawnień do publikowania w tym temacie.

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;

Usuwanie zegarka

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

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

Upoważnienie

Tak jak w przypadku wszystkich wywołań interfejsu Formularzy API, wywołania watches.create() muszą być autoryzowane za pomocą tokena autoryzacji. Token musi zawierać zakres dający dostęp do odczytu danych, o których wysyłane są powiadomienia.

Aby powiadomienia były dostarczane, aplikacja musi zachować uwierzytelnienie OAuth od autoryzowanego użytkownika z wymaganymi zakresami. Jeśli użytkownik odłączy aplikację, powiadomienia przestaną być wyświetlane, a zegarek może zostać zawieszony z powodu błędu. Jeśli chcesz wznowić powiadomienia po odzyskaniu autoryzacji, przeczytaj sekcję Odnawianie zegarka.

Wyświetlanie listy obserwowanych przez formularz

Python

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

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

Odnawianie zegarka

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

Ograniczenia

Powiadomienia są ograniczane – każdy zegarek może otrzymać maksymalnie jedno powiadomienie w ciągu 30 sekund. Ten próg częstotliwości może ulec zmianie.

Z powodu ograniczenia 1 powiadomienie może odpowiadać większej liczbie zdarzeń. Innymi słowy powiadomienie wskazuje, że od ostatniego powiadomienia wystąpiło co najmniej 1 zdarzenie.

Ograniczenia

W przypadku danego formularza i typu zdarzenia każdy projekt Cloud Console może mieć:

  • do 20 obejrzeń łącznie
  • 1 obejrzenie na użytkownika

Dodatkowo w dowolnym momencie we wszystkich projektach Cloud Console każdy formularz jest ograniczony do 50 obejrzeń na typ zdarzenia.

Zegarek jest powiązany z użytkownikiem w momencie jego utworzenia lub odnowienia za pomocą danych logowania dla tego użytkownika. Zegarek zostanie zawieszony, jeśli powiązany użytkownik utraci dostęp do formularza lub cofnie dostęp aplikacji.

Niezawodność

Każdy zegarek co najmniej 1 raz po każdym zdarzeniu otrzymuje powiadomienie we wszystkich, ale niezwykłych okolicznościach. W większości przypadków powiadomienie jest dostarczane w ciągu kilku minut od wystąpienia zdarzenia.

Błędy

Jeśli powiadomienia dotyczące zegarka stale nie są dostarczane, stan oglądania zmienia się na SUSPENDED, a jego pole errorType jest ustawione. Aby zresetować zawieszony zegarek do stanu ACTIVE i wznowić powiadomienia, przeczytaj sekcję Odnawianie zegarka.

Sugerowane użycie

  • Używanie jednego tematu Cloud Pub/Sub jako elementu docelowego dla wielu zegarków.
  • Gdy odbierasz powiadomienie na temat, identyfikator formularza jest dołączany do ładunku powiadomienia. Dzięki temu będziesz wiedzieć, jakie dane pobrać i z jakiego formularza pobrać dany typ zdarzenia.
  • Aby pobrać zaktualizowane dane po otrzymaniu powiadomienia z atrybutem EventType.RESPONSES, wywołaj funkcję forms.responses.list().
    • Ustaw filtr w żądaniu na timestamp > timestamp_of_the_last_response_you_fetched.
  • Aby pobrać zaktualizowane dane po powiadomieniu za pomocą funkcji EventType.SCHEMA, wywołaj funkcję forms.get().