Push bildirimlerini ayarlama ve alma

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

Genel Bakış

Google Forms API push bildirimleri özelliği, uygulamalara formlardaki veriler değiştiğinde bildirimlere abone olma olanağı tanır. Bildirimler, genellikle değişiklikten birkaç dakika sonra 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. Yalnızca Cloud Pub/Sub konusu desteklenir.
  • Etkinlik türü, üçüncü taraf uygulamalarının abone olabileceği bir bildirim kategorisidir.
  • İzleme, belirli bir formdaki belirli bir etkinlik türü için bildirimleri bir hedefe yayınlaması amacıyla Forms API'ye verilen bir talimattır.

Belirli bir formda bir etkinlik türü için izleme oluşturduktan sonra, izlemenin hedefi (bir Cloud Pub/Sub konusudur) izlemenin süresi dolana kadar söz konusu formdaki etkinliklerden bildirim alır. İzlemeniz bir hafta sürer ancak watches.renew() isteği göndererek süresi dolmadan dilediğiniz zaman uzatabilirsiniz.

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

Kullanılabilir etkinlik türleri

Google Forms API şu anda iki etkinlik kategorisi sunar:

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

Bildirim yanıtları

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

  • Tetikleyici formun kimliği
  • Tetikleyici kol saatinin 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 veriler almak için ayrı bir API çağrısı gerekir. Bunu nasıl yapacağınızla ilgili bilgi için Önerilen kullanım bölümüne bakın.

Aşağıdaki snippet'te, şema değişikliğiyle ilgili örnek bir bildirim gösterilmektedir:

{
  "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ıt için ö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 gönderilir. Cloud Pub/Sub'dan web kancası üzerinden veya abonelik uç noktasını sorgulayarak 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 oluşturun.
  3. Cloud Pub/Sub fiyatlandırmasını inceleyin ve Developer Console projeniz için faturalandırmayı etkinleştirin.
  4. Aşağıdaki üç yöntemden biriyle Cloud Pub/Sub konusu oluşturun:

  5. Cloud Pub/Sub'a bildirimlerinizi nasıl yayınlayacağını bildirmek için Cloud Pub/Sub'da abonelik oluşturun.

  6. Son olarak, konunuzu hedefleyen izlemeler oluşturmadan önce, Forms bildirimleri hizmet hesabına (forms-notifications@system.gserviceaccount.com) konunuzda yayın yapması için izin vermeniz gerekir.

Kol saati oluşturma

Forms API push bildirimleri hizmet hesabının yayınlayabileceği bir konunuz olduğunda watches.create() yöntemini kullanarak bildirim oluşturabilirsiniz. Bu yöntem, sağlanan Cloud Pub/Sub konusuna push bildirimleri hizmet hesabı tarafından ulaşılıp ulaşılamayacağını doğrular ve konuya ulaşılamazsa (ör. konu mevcut değilse veya konuyla ilgili 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
'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;

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

Yetkilendirme

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

Bildirimlerin gönderilebilmesi için uygulamanın, yetkili kullanıcıdan gerekli kapsamları içeren bir OAuth izni alması gerekir. Kullanıcı uygulamanın bağlantısını keserse bildirimler kesilir ve saat bir hatayla askıya alınabilir. Yetkilendirmeyi yeniden aldıktan sonra bildirimleri devam ettirmek için Bir saati yenileme başlıklı makaleyi inceleyin.

Formdaki kol saatlerini listeleme

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

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

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.

Tek bir bildirim, akış kontrolü nedeniyle birden fazla etkinliğe karşılık gelebilir. Diğer bir deyişle, bir bildirim, son bildirimden bu yana bir veya daha fazla etkinlik gerçekleştiğini gösterir.

Sınırlar

Her Cloud Console projesinde, belirli bir form ve etkinlik türü için herhangi bir zamanda şunlar bulunabilir:

  • Toplamda en fazla 20 saat
  • Son kullanıcı başına en fazla bir kol saati

Ayrıca, her form herhangi bir zamanda tüm Cloud Console projelerinde toplam 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ı forma erişimini kaybederse veya uygulamanın forma 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 bilgilendirilir. Çoğu durumda, bildirim bir etkinlikten sonraki dakikalar içinde gönderilir.

Hatalar

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

Önerilen kullanım

  • Birçok izlemenin hedefi olarak tek bir Cloud Pub/Sub konusu kullanın.
  • Bir konuyla ilgili bildirim aldığınızda form kimliği, bildirim yüküne eklenir. Hangi verilerin getirileceğini ve hangi formdan getirileceğini öğrenmek için etkinlik türüyle birlikte kullanın.
  • EventType.RESPONSES içeren bir bildirimden sonra güncellenmiş verileri almak için forms.responses.list() işlevini çağırın.
    • İstekte filtreyi timestamp > timestamp_of_the_last_response_you_fetched olarak ayarlayın.
  • EventType.SCHEMA içeren bir bildirimden sonra güncel verileri almak için forms.get() işlevini çağırın.