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, 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ść oddychania
  • 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 są wysyłane w przypadku tych typów danych 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 o wadze:
    • 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: po dołączeniu do środowiska wykonawczego Google Cloud (takiego jak Compute Engine, Cloud Run lub Google Kubernetes Engine) konta usługi 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 personalne 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ę IAM i Administracja projektu, aby utworzyć nowe konto usługi zarządzane przez użytkownika.
  2. Przyznaj niezbędne role IAM: 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 tak, aby działało jako nowe konto usługi. Dzięki temu kod aplikacji (np. biblioteki klienta interfejsów API Google) może automatycznie wykrywać i używać krótkotrwałych danych logowania konta usługi podczas wywoływania interfejsu API REST projects.subscribers.

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ć te dane:

  • project-id: numer projektu, w którym utworzono konto usługi webhooka.
  • subscriberId: unikalny identyfikator subskrybenta podany przez Ciebie. Identyfikator musi 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, dla których chcesz otrzymywać powiadomienia, oraz zasady subskrypcji dla każdego z nich.
  • endpointAuthorization: Mechanizm autoryzacji punktu końcowego. Musi on zawierać podany przez Ciebie secret. Wartość secret jest wysyłana w nagłówku Authorization z każdą wiadomością z powiadomieniem. Za pomocą tego tokena możesz sprawdzać, czy żądania przychodzące pochodzą z interfejsu Google Health API. Możesz na przykład ustawić wartość secret na Bearer R4nd0m5tr1ng123 w przypadku uwierzytelniania przy użyciu tokena okaziciela lub na Basic dXNlcjpwYXNzd29yZA== w przypadku uwierzytelniania podstawowego.

W przypadku każdego typu danych musisz ustawić subscriptionCreatePolicysubscriberConfigs. Ustaw wartość AUTOMATIC, aby używać automatycznych subskrypcji, lub MANUAL, jeśli zamierzasz samodzielnie zarządzać subskrypcjami użytkowników. Więcej informacji o poszczególnych opcjach znajdziesz w sekcjach Subskrypcje automatyczneSubskrypcje ręczne.

Żą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 aktualizujesz, 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

Aby usunąć subskrybenta z projektu, użyj punktu końcowego delete. 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ązkowe uzgadnianie połączenia weryfikacji dwuetapowej za każdym razem, gdy tworzysz subskrybenta lub aktualizujesz konfigurację jego 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 nagłówka User-Agent 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 efektywnie 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 aplikacji, które odpowiadają typom danych objętym AUTOMATIC zasadami, 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 z automatycznej konfiguracji subskrybenta dla tego użytkownika, a także wysyła powiadomienia o tych typach danych. Powiadomienia są następnie wysyłane do punktu końcowego za każdym razem, gdy użytkownik generuje nowe dane tych typów. Dotyczy to użytkowników, którzy wyrażą zgodę przed utworzeniem subskrybenta lub po jego utworzeniu. Powiadomienia nie są uzupełniane 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 w przypadku określonych typów danych, musisz wyraźnie utworzyć subskrypcje dla każdego użytkownika i nimi zarządzać. Subskrypcja łączy konkretnego użytkownika z punktem końcowym subskrybenta w przypadku określonego zestawu typów danych. Deweloperzy mogą używać określonych interfejsów API do:

  • Create (manual) subscriptions per healthUserId - Creates a new subscription for a specific user. 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ń o tym użytkowniku 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ż ponowne próby mogą 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 za pomocą AUTOMATIC zasad interfejs Google Health API automatycznie generuje i przypisuje do tego pola unikalny identyfikator (losowy identyfikator UUID) 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 API Google Health użytkownika, którego dane uległy zmianie. Jeśli Twoja aplikacja obsługuje wielu użytkowników, możesz otrzymywać powiadomienia dotyczące każdego użytkownika, który wyraził zgodę na korzystanie z niej. Gdy otrzymasz powiadomienie, użyj healthUserId, aby określić, które dane użytkownika uległy zmianie. Dzięki temu 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, spróbuje ponownie wysłać powiadomienie później.

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 GOOGLE-HEALTH-API-SIGNATURE HTTP 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ą elementu pierwotnego PublicKeyVerify biblioteki Tink. Pobierz z trwałego adresu URL zestaw kluczy publicznych, utwórz instancję elementu pierwotnego 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 formacie 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 i odpowie kodem 204, interfejs API automatycznie dostarczy zaległe wiadomości. Powiadomienia starsze niż 7 dni są odrzucane i nie 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 używaj w adresie URL żądania 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 Ten rozmówca nie ma uprawnień Podczas tworzenia lub wyświetlania listy subskrybentów używaj w adresie URL żądania 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.