Push bildirimlerini ayarlama ve alma

Formlardaki veriler değiştiğinde bildirim almak için Watches koleksiyonundaki yöntemleri kullanabilirsiniz. Bu sayfada, push bildirimlerini ayarlama ve alma ile ilgili kavramsal bir genel bakış ve talimatlar sağlanmaktadır.

Genel Bakış

Google Forms API'nin push bildirimleri özelliği, uygulamaların formlardaki veriler değiştiğinde bildirimlere abone olmasına olanak tanır. Bildirimler, genellikle değişiklikten sonraki birkaç dakika içinde bir Cloud Pub/Sub konusuna gönderilir.

Push bildirimi almak için bir Cloud Pub/Sub konusu oluşturmanız ve uygun etkinlik türü için izleme oluştururken bu konunun adını sağlamanız gerekir.

Bu dokümanda kullanılan temel kavramların tanımları aşağıda verilmiştir:

  • Hedef, bildirimlerin gönderildiği yerdir. Desteklenen tek hedef bir Cloud Pub/Sub konusudur.
  • Etkinlik türü, üçüncü taraf bir uygulamanın abone olabileceği bildirim kategorisidir.
  • İzleme, Forms API'ye belirli bir formdaki belirli bir etkinlik türü için bildirimleri bir hedefe gönderme talimatıdır.

Belirli bir formda bir etkinlik türü için izleme oluşturduğunuzda, bu izlemenin hedefi (Cloud Pub/Sub konusu) izleme süresi dolana kadar söz konusu formdaki etkinliklerden bildirim alır. İzleme isteğiniz bir hafta sürer ancak süresi dolmadan önce watches.renew() isteğinde bulunarak süreyi uzatabilirsiniz.

Cloud Pub/Sub konunuz yalnızca sağladığınız kimlik bilgileriyle görüntüleyebileceğiniz formlarla ilgili bildirimleri alır. Örneğin, kullanıcı uygulamanızdan izni iptal ederse veya izlenen bir forma düzenleme erişimini kaybederse bildirimler artık gönderilmez.

Kullanılabilir etkinlik türleri

Google Forms API şu anda iki etkinlik kategorisi sunmaktadır:

  • EventType.SCHEMA: Formun içeriğinde ve ayarlarında yapılan düzenlemeler hakkında bildirim gönderir.
  • EventType.RESPONSES: Form yanıtları (hem yeni hem de güncellenmiş) gönderildiğinde bildirim gönderir.

Bildirim yanıtları

Bildirimler JSON ile kodlanır ve şunları içerir:

  • Tetikleyici formun kimliği
  • Tetikleyici izlemenin kimliği
  • Bildirimi tetikleyen etkinlik türü
  • Cloud Pub/Sub tarafından ayarlanan diğer alanlar (ör. messageId ve publishTime)

Bildirimler, ayrıntılı form veya yanıt verileri içermez. Her bildirim alındıktan sonra yeni verileri getirmek için ayrı bir API çağrısı yapılması gerekir. Bunu nasıl yapacağınızı öğrenmek için Önerilen kullanım bölümüne bakın.

Aşağıdaki snippet, şema değişikliğiyle ilgili örnek bir bildirimi gösterir:

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

Aşağıdaki snippet'te yeni bir yanıtla ilgili örnek bir bildirim gösterilmektedir:

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

Cloud Pub/Sub konusu oluşturma

Bildirimler Cloud Pub/Sub konularına iletilir. Cloud Pub/Sub'dan web kancası üzerinden veya bir abonelik uç noktası yoklanarak bildirim alabilirsiniz.

Cloud Pub/Sub konusu oluşturmak için aşağıdakileri yapın:

  1. Cloud Pub/Sub Ön Koşulları'nı tamamlayın.
  2. Cloud Pub/Sub istemcisi ayarlayın.
  3. Cloud Pub/Sub fiyatlandırmasını inceleyin ve Developer Console projeniz için faturalandırmayı etkinleştirin.
  4. Üç yöntemden birini kullanarak Cloud Pub/Sub konusu oluşturun:

  5. Cloud Pub/Sub'a bildirimlerinizi nasıl ileteceğini söylemek için Cloud Pub/Sub'da bir abonelik oluşturun.

  6. Son olarak, konunuzu hedefleyen izlemeler oluşturmadan önce Formlar bildirimleri hizmet hesabına (forms-notifications@system.gserviceaccount.com) konunuza yayınlama izni vermeniz gerekir.

Kol saati oluşturma

Forms API push bildirimleri hizmet hesabının yayınlayabileceği bir konu belirledikten sonra watches.create() yöntemini kullanarak bildirim oluşturabilirsiniz. Bu yöntem, sağlanan Cloud Pub/Sub konusuna push bildirimleri hizmet hesabıyla erişilebildiğini doğrular ve konuya erişilemezse (ör. konu mevcut değilse veya bu konuda yayınlama izni vermediyseniz) başarısız olur.

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

Kol saati silme

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

Yetkilendirme

Forms API'ye yapılan tüm çağrılar gibi, watches.create() çağrıları da bir yetkilendirme jetonuyla yetkilendirilmelidir. Jeton, hangi bildirimlerin gönderildiğiyle ilgili verilere okuma erişimi veren bir kapsam içermelidir.

Bildirimlerin gönderilebilmesi için uygulamanın, yetkili kullanıcıdan gerekli kapsamlarla bir OAuth izni alması gerekir. Kullanıcı uygulamanın bağlantısını keserse bildirimler durdurulur ve saat, hata nedeniyle askıya alınabilir. Yetkiyi yeniden kazandıktan sonra bildirimleri devam ettirmek için Saati yenileme başlıklı makaleyi inceleyin.

Bir formun izleme listesini görüntüleme

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

Kol saatini yenileme

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

Kısıtlama

Bildirimler sınırlandırılır. Her kol saati, otuz saniyede en fazla bir bildirim alabilir. Bu sıklık eşiği değişebilir.

Sınırlama nedeniyle, tek bir bildirim birden fazla etkinliğe karşılık gelebilir. Başka bir deyişle, bir bildirim, son bildirimden bu yana bir veya daha fazla etkinliğin gerçekleştiğini gösterir.

Sınırlar

Herhangi bir zamanda, belirli bir form ve etkinlik türü için her Cloud Console projesi şunlara sahip olabilir:

  • toplamda 20 izleme
  • Son kullanıcı başına bir izleme

Ayrıca, her form herhangi bir zamanda tüm Cloud Console projelerinde toplamda etkinlik türü başına 50 izlemeyle sınırlıdır.

Bir kol saati, ilgili kullanıcının kimlik bilgileriyle oluşturulduğunda veya yenilendiğinde son kullanıcıyla ilişkilendirilir. İlişkili son kullanıcı form erişimini kaybederse veya uygulamanın form erişimini iptal ederse izleme askıya alınır.

Güvenilirlik

Her kol saati, olağanüstü durumlar dışında her etkinlikten sonra en az bir kez bildirim alır. Çok büyük bir çoğunlukta, etkinlikten sonraki birkaç dakika içinde bildirim gönderilir.

Hatalar

Bir kol saatiyle ilgili bildirimler sürekli olarak teslim edilemezse kol saatinin durumu SUSPENDED olur ve kol saatinin errorType alanı ayarlanır. Askıya alınmış bir saatin durumunu ACTIVE olarak sıfırlamak ve bildirimleri devam ettirmek için Saati yenileme başlıklı makaleyi inceleyin.

Önerilen kullanım

  • Tek bir Cloud Pub/Sub konusunu birçok izlemenin hedefi olarak kullanma.
  • Bir konuyla ilgili bildirim alırken form kimliği, bildirim yüküne dahil edilir. Hangi verilerin ve hangi formdan getirileceğini öğrenmek için etkinlik türüyle birlikte kullanın.
  • EventType.RESPONSES içeren bir bildirimden sonra güncellenen verileri getirmek için forms.responses.list() işlevini çağırın.
    • İstekle ilgili filtreyi timestamp > timestamp_of_the_last_response_you_fetched olarak ayarlayın.
  • EventType.SCHEMA içeren bir bildirimden sonra güncellenen verileri getirmek için forms.get() işlevini çağırın.