Subskrypcje webhooków

Interfejs Google Health API umożliwia aplikacji otrzymywanie powiadomień w czasie rzeczywistym o zmianach w danych dotyczących zdrowia użytkownika. Zamiast odpytywać o zmiany, Twój serwer otrzymuje żądanie HTTPS POST (webhook){:target="_blank" class="external"} od razu, gdy dane są dostępne w interfejsie Google Health API.

Obsługiwane typy danych

Powiadomienia webhook są obsługiwane w przypadku tych typów danych:

  • Aktywne minuty w strefie
  • Poziom aktywności
  • Wysokość
  • Glukoza we krwi
  • Tkanka tłuszczowa
  • Kalorie w strefie tętna
  • Dzienna zmienność rytmu serca
  • Dzienne strefy tętna
  • Dzienne nasycenie tlenem
  • Dzienna częstość oddechów
  • Dzienne tętno spoczynkowe
  • Codzienne dane pochodne dotyczące temperatury podczas snu
  • Odległość
  • Ćwiczenia
  • Piętra
  • tętno
  • Zmienność rytmu serca
  • Wysokość
  • Zapis nawodnienia
  • Dziennik odżywiania
  • Podsumowanie snu dotyczące częstości oddychania
  • Pułap tlenowy podczas biegu
  • Okres braku aktywności
  • Sen
  • Kroki
  • Czas w strefie tętna
  • Wszystkie kalorie
  • Waga

Powiadomienia dotyczące tych typów danych są wysyłane tylko wtedy, gdy użytkownik wyrazi zgodę na jeden z odpowiednich zakresów:

  • Aktywność, która obejmuje typy danych dotyczące kroków, wysokości, dystansu i pięter:
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
  • Wskaźniki zdrowotne, które obejmują typ danych dotyczących wagi:
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.writeonly
  • Sen, który obejmuje typ danych o śnie:
    • https://www.googleapis.com/auth/googlehealth.sleep.readonly
    • https://www.googleapis.com/auth/googlehealth.sleep.writeonly

Konta usługi używane przez Uprawnienia

Podczas konfigurowania subskrybentów interfejsu Google Health API zalecamy używanie konta usługi IAM. Konta usługi zapewniają większe bezpieczeństwo obciążeń aplikacji niż standardowe konta użytkowników dzięki tym funkcjom:

  • Automatyczne, krótkotrwałe dane logowania: gdy konta usługi są dołączone do środowiska wykonawczego Google Cloud (np. Compute Engine, Cloud Run lub Google Kubernetes Engine), automatycznie uzyskują i rotują bezpieczne, krótkotrwałe dane logowania. Eliminuje to ryzyko związane z zarządzaniem trwałymi kluczami statycznymi i ich przechowywaniem.
  • Zasada jak najmniejszych uprawnień: konta usługi zapewniają dedykowane tożsamości dla zadań. Możesz przyznać im tylko konkretne uprawnienia potrzebne do zarządzania punktami końcowymi subskrybentów, unikając szerszego dostępu do zasobów Google Cloud.
  • Niezależność cyklu życia: konta usługi działają niezależnie od kont poszczególnych użytkowników, dzięki czemu zmiany personelu nie wpływają na długoterminową stabilność uwierzytelniania.

skonfigurować konto usługi,

Aby skonfigurować aplikację subskrybenta do uwierzytelniania za pomocą konta usługi:

  1. Utwórz konto usługi: w konsoli Google Cloud otwórz stronę Administracja w projekcie, aby utworzyć nowe konto usługi zarządzane przez użytkownika.
  2. Przypisz niezbędne role uprawnień: przypisz do konta usługi odpowiednie role wymagane do zarządzania subskrybentami w projekcie Google Cloud.
  3. Dołącz konto usługi do zadania: skonfiguruj środowisko hostujące logikę subskrybenta, aby działało jako nowe konto usługi. Dzięki temu kod aplikacji (np. biblioteki klienta interfejsów API Google) będzie automatycznie wykrywać i używać krótkotrwałych danych logowania konta usługi podczas wywoływania interfejsu projects.subscribers REST API.

Role CPE

Aby zarządzać subskrybentami lub subskrypcjami interfejsu Google Health API, musisz przyznać odpowiednią rolę kontu usługi, które jest używane do wywoływania interfejsu API. W zależności od potrzebnego poziomu dostępu przypisz jedną z tych ról:

  • Google Health API Read
  • Edytujący interfejs Google Health API
  • Administrator interfejsu Google Health API

Więcej informacji o rolach i uprawnieniach interfejsu Google Health API

Zarządzanie subskrybentami

Aby otrzymywać powiadomienia, musisz zarejestrować subskrybenta, który reprezentuje punkt końcowy powiadomień aplikacji. Subskrybentami możesz zarządzać za pomocą interfejsu API REST dostępnego pod adresem projects.subscribers.

Punkt końcowy subskrybenta musi używać protokołu HTTPS (TLSv1.2+) i być publicznie dostępny. Podczas tworzenia i aktualizowania subskrybentów interfejs API Google Health przeprowadza weryfikację, aby upewnić się, że jesteś właścicielem identyfikatora URI punktu końcowego. Jeśli weryfikacja się nie powiedzie, operacje tworzenia i aktualizowania subskrybentów zakończą się niepowodzeniem z błędem FailedPreconditionException.

Tworzenie subskrybenta

Aby zarejestrować nowego subskrybenta w projekcie, użyj punktu końcowego create. Musisz podać:

  • project-id: numer projektu, w którym utworzono konto usługi webhooka.
  • subscriberId: unikalny identyfikator, który podajesz dla subskrybenta. Musi on mieć od 4 do 36 znaków i pasować do wyrażenia regularnego ([a-z]([a-z0-9-]{2,34}[a-z0-9])).
  • endpointUri: docelowy adres URL powiadomień webhooka.
  • subscriberConfigs: typy danych, w przypadku których chcesz otrzymywać powiadomienia, oraz zasady subskrypcji dla każdego z nich.
  • endpointAuthorization: mechanizm autoryzacji punktu końcowego. Musi zawierać podany przez Ciebie element secret. Wartość elementu secret jest wysyłana w nagłówku Authorization z każdym komunikatem z powiadomieniem. Możesz użyć tego tokena, aby sprawdzić, czy przychodzące żądania pochodzą z interfejsu Google Health API. Możesz na przykład ustawić secret na Bearer R4nd0m5tr1ng123 w przypadku uwierzytelniania za pomocą tokena lub na Basic dXNlcjpwYXNzd29yZA== w przypadku uwierzytelniania podstawowego.

subscriberConfigs musisz ustawić subscriptionCreatePolicy dla każdego typu danych. Aby używać automatycznych subskrypcji, ustaw wartość AUTOMATIC, a jeśli chcesz samodzielnie zarządzać subskrypcjami użytkowników, ustaw wartość MANUAL. Więcej informacji o poszczególnych opcjach znajdziesz w sekcjach Automatyczne subskrypcjeRęczne subskrypcje.

Żądanie

POST https://health.googleapis.com/v4/projects/project-id/subscribers?subscriberId=subscriber-id
{
  "endpointUri": "https://myapp.com/webhooks/health",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ],
  "endpointAuthorization": {
    "secret": "Bearer example-secret-token"
  }
}

Odpowiedź

{
  "name": "projects/project-id/subscribers/subscriber-id",
  "endpointUri": "https://myapp.com/webhooks/health",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ]
}

Wyświetlanie listy subskrybentów

Użyj punktu końcowego list, aby pobrać wszystkich subskrybentów zarejestrowanych w Twoim projekcie.

Żądanie

GET https://health.googleapis.com/v4/projects/project-id/subscribers

Odpowiedź

{
  "subscribers": [
    {
      "name": "projects/project-id/subscribers/subscriber-id",
      "endpointUri": "https://myapp.com/webhooks/health",
      "subscriberConfigs": [
        {
          "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
          "subscriptionCreatePolicy": "AUTOMATIC"
        },
        {
          "dataTypes": ["sleep"],
          "subscriptionCreatePolicy": "MANUAL"
        }
      ],
      "endpointAuthorization": {
        "authorizationTokenSet": true
      }
    }
  ],
  "totalSize": 1
}

Aktualizowanie subskrybenta

Użyj punktu końcowego patch, aby zaktualizować subskrybenta w projekcie. Pola, które można zaktualizować, to endpointUri, subscriberConfigs i endpointAuthorization.

Pola aktualizuje się, podając parametr zapytania updateMask i treść żądania. Parametr updateMask musi zawierać rozdzieloną przecinkami listę nazw pól, które chcesz zaktualizować. Nazwy pól muszą być zapisane w formacie camel case (np. endpointUri). Treść żądania musi zawierać częściowy obiekt Subscriber z nowymi wartościami pól, które chcesz zaktualizować. Aktualizowane są tylko pola określone w updateMask. Jeśli w treści żądania podasz pola, których nie ma w updateMask, zostaną one zignorowane.

Jeśli zaktualizujesz endpointUri lub endpointAuthorization, zostanie przeprowadzona weryfikacja punktów końcowych. Więcej informacji znajdziesz w artykule Weryfikacja punktów końcowych.

Podczas aktualizowania subscriberConfigs pamiętaj, że jest to pełna zamiana, a nie scalanie. Jeśli subscriberConfigs znajduje się w updateMask, wszystkie zapisane konfiguracje subskrybenta zostaną zastąpione listą podaną w treści żądania. Aby dodać lub usunąć konfigurację, musisz podać pełny zestaw konfiguracji. Jeśli aktualizujesz inne pola i chcesz zachować obecne konfiguracje, pomiń subscriberConfigs w updateMask.

Żądanie

PATCH https://health.googleapis.com/v4/projects/project-id/subscribers/subscriber-id?updateMask=endpointUri
{
  "endpointUri": "https://myapp.com/new-webhooks/health"
}

Odpowiedź

{
  "name": "projects/project-id/subscribers/subscriber-id",
  "endpointUri": "https://myapp.com/new-webhooks/health",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ]
}

Usuwanie subskrybenta

Użyj punktu końcowego delete, aby usunąć subskrybenta z projektu. Po usunięciu subskrybent nie będzie już otrzymywać powiadomień.

Żądanie

DELETE https://health.googleapis.com/v4/projects/project-id/subscribers/subscriber-id

Odpowiedź

Jeśli usunięcie się powiedzie, zwracana jest pusta treść odpowiedzi z kodem stanu HTTP „200 OK”.
{}

Weryfikacja punktów końcowych

Aby zapewnić bezpieczeństwo i niezawodność dostarczania powiadomień, interfejs Google Health API przeprowadza obowiązkową weryfikację dwuetapową za każdym razem, gdy tworzysz subskrybenta lub aktualizujesz jego konfigurację punktu końcowego (endpointUri lub endpointAuthorization). Ten proces jest wykonywany synchronicznie podczas wywołania interfejsu API. Usługa wysyła 2 automatyczne żądania POST do adresu URI punktu końcowego, używając User-Agenta Google-Health-API-Webhooks-Verifier i treści JSON {"type": "verification"}.

  • Autoryzowane uzgadnianie: pierwsze żądanie jest wysyłane z nagłówkiem Authorization skonfigurowanym przez Ciebie. Serwer musi odpowiadać stanem 200 OK lub 201 Created.
  • Nieautoryzowane wyzwanie: drugie żądanie jest wysyłane bez danych logowania. Serwer musi odpowiadać stanem 401 Unauthorized lub 403 Forbidden.

Ten proces potwierdza, że punkt końcowy jest aktywny i prawidłowo egzekwuje zabezpieczenia. Jeśli którykolwiek z tych kroków się nie powiedzie, żądanie do interfejsu API zakończy się błędem FAILED_PRECONDITION. Dopiero po pomyślnym nawiązaniu połączenia subskrybent zostanie zapisany i aktywny, aby otrzymywać powiadomienia o danych dotyczących zdrowia.

Rotacja kluczy

Jeśli musisz dokonać rotacji kluczy w przypadku endpointAuthorization, wykonaj te czynności:

  1. Skonfiguruj punkt końcowy tak, aby akceptował zarówno stare, jak i nowe wartości.endpointAuthorization
  2. Zaktualizuj konfigurację subskrybenta, podając nową wartość endpointAuthorization, za pomocą żądania patch z parametrem ?updateMask=endpointAuthorization.
  3. Skonfiguruj punkt końcowy tak, aby akceptował tylko nową wartość endpointAuthorization po potwierdzeniu, że krok 2 został wykonany prawidłowo.

Subskrypcje użytkownika

Interfejs Google Health API pomaga skutecznie zarządzać subskrypcjami użytkowników, co zmniejsza potrzebę ręcznej rejestracji podczas wprowadzania użytkowników.

Automatyczne subskrypcje

Zalecamy korzystanie z automatycznych subskrypcji. Aby włączyć tę funkcję, ustaw wartość subscriptionCreatePolicy na AUTOMATICsubscriberConfigs dla konkretnych typów danych. dataTypes określone w zasadach AUTOMATIC to te same typy danych, w przypadku których interfejs Google Health API wysyła powiadomienia, pod warunkiem że użytkownik wyraził zgodę na te typy danych.

Gdy użytkownik wyrazi zgodę na zakresy odpowiadające typom danych z zasadami AUTOMATIC, interfejs Google Health API automatycznie śledzi typy danych wynikające z części wspólnej typów danych, na które użytkownik wyraził zgodę, i typów danych konfiguracji automatycznego subskrybenta dla tego użytkownika, a następnie wysyła powiadomienia o tych typach danych. Powiadomienia są wysyłane do Twojego punktu końcowego za każdym razem, gdy użytkownik wygeneruje nowe dane dla tych typów. Działa to w przypadku użytkowników, którzy wyrażą zgodę przed utworzeniem subskrybenta lub po jego utworzeniu. Powiadomienia nie są wysyłane wstecznie w przypadku danych wygenerowanych przed utworzeniem subskrybenta.

Jeśli użytkownik wycofa zgodę, powiadomienia dotyczące odpowiednich typów danych przestaną być wysyłane. Subskrypcjami automatycznymi zarządza Google i nie można ich wyświetlać ani usuwać pojedynczo. Są one usuwane tylko wtedy, gdy usunięty zostanie subskrybent nadrzędny.

Subskrypcje ręczne

Jeśli subskrybent jest skonfigurowany z wartością MANUAL subscription_create_policy dla określonych typów danych, musisz wyraźnie tworzyć subskrypcje i nimi zarządzać dla każdego użytkownika. Subskrypcja łączy określonego użytkownika z punktem końcowym subskrybenta dla zdefiniowanego zestawu typów danych. Deweloperzy mogą używać określonych interfejsów API do:

  • Tworzenie (ręczne) subskrypcji dla healthUserId – tworzy nową subskrypcję dla konkretnego użytkownika. Ta metoda wymaga, aby subskrybent miał ustawioną wartość SubscriptionCreatePolicy na MANUAL w przypadku żądanych typów danych.
  • Aktualizacja subskrypcji (ręczna) – aktualizuje typy danych w przypadku istniejącej subskrypcji użytkownika.
  • Usuń subskrypcję (ręcznie) – usuwa subskrypcję konkretnego użytkownika. Po usunięciu punkt końcowy subskrybenta nie będzie już otrzymywać powiadomień dotyczących tego użytkownika w przypadku powiązanych typów danych.
  • Wyświetlanie listy subskrypcji (ręcznych) – wyświetla wszystkie aktywne subskrypcje danego subskrybenta. Wyniki możesz filtrować według użytkownika lub typu danych.

Powiadomienia

Gdy dane użytkownika zmienią się w przypadku subskrybowanego typu danych, interfejs Google Health API wyśle żądanie HTTPS POST na adres URL punktu końcowego subskrybenta.

Format powiadomienia

Ładunek powiadomienia to obiekt JSON zawierający szczegóły zmiany danych. Obejmuje to identyfikator użytkownika, typ danych i przedziały czasowe, których możesz używać do wysyłania zapytań dotyczących zaktualizowanych danych.

{
  "data": {
    "version": "1",
    "clientProvidedSubscriptionName": "subscription-name",
    "healthUserId": "health-user-id",
    "operation": "UPSERT",
    "dataType": "steps",
    "intervals": [
      {
        "physicalTimeInterval": {
          "startTime": "2026-03-08T01:29:00Z",
          "endTime": "2026-03-08T01:34:00Z"
        },
        "civilDateTimeInterval": {
          "startDateTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 7
            },
            "time": {
              "hours": 17,
              "minutes": 29
            }
          },
          "endDateTime": {
            "date": {
              "year": 2026,
              "month": 3,
              "day": 7
            },
            "time": {
              "hours": 17,
              "minutes": 34
            }
          }
        },
        "civilIso8601TimeInterval": {
          "startTime": "2026-03-07T17:29:00",
          "endTime": "2026-03-07T17:34:00"
        }
      }
    ]
  }
}

Pole operation wskazuje typ zmiany, która wywołała powiadomienie:

  • UPSERT: wysyłany w przypadku dodania lub zmodyfikowania danych.
  • DELETE: wysyłany, gdy użytkownik usuwa dane.

Zalecamy, aby logika obsługi powiadomień była idempotentna, zwłaszcza w przypadku operacji UPSERT, ponieważ ponawianie prób może powodować wysyłanie zduplikowanych powiadomień.

Pole clientProvidedSubscriptionName to unikalny identyfikator. W przypadku subskrypcji objętych MANUAL zasadami to pole zawiera trwałą nazwę subskrypcji podaną przez dewelopera podczas tworzenia subskrypcji. Zapewnia to stabilny identyfikator do zarządzania subskrypcjami ustawianymi samodzielnie. W przypadku subskrypcji utworzonych zgodnie z zasadami AUTOMATIC interfejs Google Health API automatycznie generuje i przypisuje unikalny identyfikator (losowy identyfikator UUID) do tego pola dla każdego powiadomienia. Uwzględnienie clientProvidedSubscriptionName w przypadku zasad ręcznych i automatycznych zapewnia spójny format ładunku powiadomienia we wszystkich typach subskrypcji.

healthUserId to identyfikator interfejsu Google Health API użytkownika, którego dane uległy zmianie. Jeśli Twoja aplikacja obsługuje wielu użytkowników, możesz otrzymywać powiadomienia o zmianach danych każdego użytkownika, który wyraził zgodę na dostęp do nich. Gdy otrzymasz powiadomienie, użyj parametru healthUserId, aby określić, którego użytkownika dane uległy zmianie. Następnie możesz użyć jego danych logowania OAuth do wysłania zapytania o jego dane.

Aby zmapować dane logowania OAuth użytkownika na jego healthUserId, użyj punktu końcowego getIdentity. Wywołaj ten punkt końcowy za pomocą danych logowania użytkownika podczas wprowadzania użytkownika, aby pobrać jego healthUserId i zapisać to mapowanie. To mapowanie nie zmienia się z czasem, więc można je przechowywać w pamięci podręcznej bez ograniczeń. Przykład znajdziesz w sekcji Pobieranie identyfikatora użytkownika. Dzięki temu możesz wybrać prawidłowe dane logowania użytkownika podczas wysyłania zapytań o dane na podstawie ikony healthUserId w powiadomieniu.

Podejmowanie działania w związku z powiadomieniem

Serwer musi natychmiast odpowiadać na powiadomienia kodem stanu HTTP 204 No Content. Aby uniknąć przekroczenia limitu czasu, przetwórz ładunek powiadomienia asynchronicznie po wysłaniu odpowiedzi. Jeśli interfejs Google Health API otrzyma inny kod stanu lub żądanie przekroczy limit czasu, ponowi wysyłanie powiadomienia w późniejszym terminie.

Przykład w Node.js (Express):

app.post('/webhook-receiver', (req, res) => {
    // 1. Immediately acknowledge the notification
    res.status(204).send();

    // 2. Process the data asynchronously in the background
    const notification = req.body;
    setImmediate(() => {
        console.log(`Update for user ${notification.data.healthUserId} of type ${notification.data.dataType}`);
        // Trigger your data retrieval logic here
    });
});

weryfikowaniem podpisu,

Aby zapewnić autentyczność powiadomień Webhooks, surowy ładunek JSON każdego wychodzącego powiadomienia Webhooks jest podpisywany kluczem prywatnym za pomocą Tink's PublicKeySign. Podpis zakodowany w Base64 jest umieszczany w nagłówku HTTP GOOGLE-HEALTH-API-SIGNATURE w żądaniu. Klucze podpisywania są automatycznie zmieniane co 30 dni, a odpowiedni oficjalny zestaw kluczy publicznych jest rozpowszechniany jako plik JSON pod stałym adresem URL https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json.

Jak zweryfikować podpis

Korzystanie z Tink (zalecane): deweloperzy mogą weryfikować podpis za pomocą prymitywu PublicKeyVerify w Tink. Pobierz z trwałego adresu URL zestaw kluczy publicznych, utwórz instancję elementu PublicKeyVerify z zestawem kluczy i zweryfikuj zdekodowany nagłówek GOOGLE-HEALTH-API-SIGNATURE z nieprzetworzonym ładunkiem JSON webhooka.

Weryfikacja ręczna (bez Tink): jeśli deweloperzy nie chcą korzystać z Tink, mogą ręcznie zweryfikować podpis, wykonując te czynności:

  1. Dekoduje w base64 nagłówek GOOGLE-HEALTH-API-SIGNATURE, aby oddzielić 5-bajtowy prefiks Tink (zawierający 1-bajtowy prefiks wersji i 4-bajtowy identyfikator klucza) od rzeczywistego podpisu zakodowanego w formacie DER.
  2. Pobierz zestaw kluczy JSON z adresu https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json.
  3. Znajdź klucz pasujący do przeanalizowanego identyfikatora keyId i zdekoduj w formacie Base64 jego pole wartości, które zawiera zserializowany bufor protokołu EcdsaPublicKey.
  4. Wyodrębnij współrzędne x i y w formacie big-endian (tagi Protobuf 3 i 4) z tego binarnego ładunku.
  5. Utwórz instancję standardowego klucza publicznego ECDSA P-256 w bibliotece kryptograficznej za pomocą wyodrębnionych współrzędnych x i y.
  6. Sprawdź, czy nieprzetworzony ładunek JSON webhooka jest zgodny z wyodrębnionym podpisem DER za pomocą algorytmu SHA-256.

Stan subskrybenta i odzyskiwanie

Jeśli punkt końcowy subskrybenta stanie się niedostępny lub zwróci kod stanu błędu (inny niż 204), interfejs Google Health API będzie przechowywać oczekujące powiadomienia przez maksymalnie 7 dni i ponawiać ich dostarczanie z wzrastającym czasem do ponowienia.

Gdy punkt końcowy znów będzie dostępny online i odpowie kodem 204, interfejs API automatycznie dostarczy zaległe wiadomości. Powiadomienia starsze niż 7 dni zostaną odrzucone i nie będzie można ich odzyskać.

Typowe błędy

Kod błędu Wiadomość Opis Rekomendacja
400 Nieprawidłowe żądanie Nieprawidłowy numer projektu w nazwie zasobu Podczas usuwania lub aktualizowania subskrybenta w adresie URL żądania używasz identyfikatora projektu Google Cloud zamiast numeru projektu. Dotyczy to subskrypcji webhooków korzystających z punktu końcowego projects.subscribers. W adresie URL żądania użyj numeru projektu Google Cloud, a nie identyfikatora projektu.
403 Dostęp zabroniony Rozmówca nie ma uprawnień Podczas tworzenia lub wyświetlania subskrybentów używaj w adresie URL żądania identyfikatora projektu w chmurze Google zamiast numeru projektu. Dotyczy to subskrypcji webhooków korzystających z punktu końcowego projects.subscribers. W adresie URL żądania użyj numeru projektu Google Cloud, a nie identyfikatora projektu.