Подписки на веб-хуки


API Google Health позволяет вашему приложению получать уведомления в режиме реального времени об изменениях в данных о здоровье пользователя. Вместо постоянного опроса, ваш сервер получает HTTPS POST-запрос ( веб-хук ), как только данные становятся доступны в API Google Health.

Поддерживаемые типы данных

Уведомления через веб-перехватчики поддерживаются для следующих типов данных:

  • Шаги
  • Высота
  • Расстояние
  • Полы
  • Масса
  • Спать

Уведомления для этих типов данных отправляются только в том случае, если пользователь дал согласие на использование данных в одной из соответствующих областей:

  • Данная специализация охватывает следующие типы данных: количество шагов, высота, расстояние и этажи:
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
  • Показатели здоровья , которые охватывают тип данных о весе:
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly
  • Сон , который охватывает тип данных о сне:
    • https://www.googleapis.com/auth/googlehealth.sleep
    • https://www.googleapis.com/auth/googlehealth.sleep.readonly

Управление подписчиками

Прежде чем получать уведомления, необходимо зарегистрировать подписчика (Subscriber), который представляет собой конечную точку уведомлений вашего приложения. Управлять подписчиками можно с помощью REST API, доступного по адресу projects.subscribers .

Ваша конечная точка для подписчиков должна использовать HTTPS (TLSv1.2+) и быть общедоступной. Во время создания и обновления подписчиков API Google Health выполняет проверку подлинности, чтобы убедиться, что вы являетесь владельцем URI конечной точки. Если проверка не удается, операции создания и обновления подписчиков завершаются с ошибкой FailedPreconditionException .

Создать подписчика

Для регистрации нового подписчика для вашего проекта используйте конечную точку create . Вам необходимо указать:

  • endpointUri : Целевой URL-адрес для уведомлений веб-перехватчика.
  • subscriberConfigs : Типы данных, для которых вы хотите получать уведомления, и политика подписки для каждого из них.
  • endpointAuthorization : Механизм авторизации для вашей конечной точки. Он должен содержать предоставленный вами authorization_token . Значение authorization_token отправляется в заголовке Authorization с каждым уведомлением. Вы можете использовать этот токен для проверки того, что входящие запросы поступают от Google Health API. Например, вы можете установить authorization_token равным Bearer R4nd0m5tr1ng123 для аутентификации Bearer или Basic dXNlcjpwYXNzd29yZA== для базовой аутентификации.
  • subscriberId : Уникальный идентификатор, который вы указываете для подписчика. Этот идентификатор должен содержать от 4 до 36 символов и соответствовать регулярному выражению ( [az]([a-z0-9-]{2,34}[a-z0-9]) ).

В subscriberConfigs необходимо задать subscriptionCreatePolicy для каждого типа данных. Установите значение AUTOMATIC для использования автоматических подписок или MANUAL , если вы планируете управлять подписками пользователей самостоятельно. Дополнительные сведения о каждом параметре см. в разделах «Автоматические подписки» и «Подписки вручную» .

Запрос

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": {
    "authorization_token": "Bearer example-secret-token"
  }
}

Ответ

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

Список подписчиков

Используйте конечную точку list для получения списка всех подписчиков, зарегистрированных в вашем проекте.

Запрос

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

Ответ

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

Обновить данные подписчика

Используйте конечную точку patch для обновления подписчика в вашем проекте. Можно обновить следующие поля: endpointUri , subscriberConfigs и endpointAuthorization .

Обновление полей осуществляется путем предоставления параметра запроса updateMask и тела запроса. Параметр updateMask должен содержать список имен полей, разделенных запятыми, с использованием верблюжьего регистра для имен полей (например, endpointUri ). Тело запроса должно содержать частичный объект Subscriber с новыми значениями для полей, которые вы хотите обновить. Обновляются только поля, указанные в updateMask . Если в теле запроса указаны поля, не указанные в updateMask , они игнорируются.

При изменении endpointUri или endpointAuthorization выполняется проверка конечной точки. Подробнее см. в разделе «Проверка конечной точки» .

При обновлении subscriberConfigs обратите внимание, что это полная замена , а не слияние. Если subscriberConfigs включен в updateMask , все сохраненные конфигурации для этого подписчика будут перезаписаны списком, предоставленным в теле запроса. Чтобы добавить или удалить конфигурацию, необходимо предоставить полный набор конфигураций. Если вы обновляете другие поля и хотите сохранить текущие конфигурации, опустите subscriberConfigs из updateMask .

Запрос

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

Ответ

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

Проверка конечной точки

Для обеспечения безопасности и надежности доставки уведомлений API Google Health выполняет обязательную двухэтапную проверку подлинности при каждом создании подписчика или обновлении конфигурации его конечной точки ( endpointUri или endpointAuthorization ). Этот процесс выполняется синхронно во время вызова API. Сервис отправляет два автоматических POST-запроса на ваш URI конечной точки, используя User-Agent Google-Health-API-Webhooks-Verifier , с телом JSON {"type": "verification"} .

  • Авторизованное рукопожатие : Первый запрос отправляется с настроенным вами заголовком Authorization . Ваш сервер должен ответить статусом 200 OK или 201 Created .
  • Несанкционированный запрос : второй запрос отправляется без учетных данных. Ваш сервер должен ответить кодом 401 Unauthorized или 403 Forbidden .

Этот процесс подтверждения подтверждает активность вашей конечной точки и корректное применение мер безопасности. Если какой-либо из шагов завершится неудачей, запрос к API завершится с ошибкой FAILED_PRECONDITION . Только после успешного завершения этого процесса подтверждения ваш подписчик будет сохранен и активирован для получения уведомлений о состоянии здоровья.

Вращение ключа

Если вам необходимо сменить ключи для endpointAuthorization , выполните следующие действия:

  1. Настройте конечную точку таким образом, чтобы она принимала как старые, так и новые значения endpointAuthorization .
  2. Обновите конфигурацию абонента, указав новое значение endpointAuthorization , используя запрос на обновление с patch ?updateMask=endpointAuthorization .
  3. Настройте конечную точку таким образом, чтобы она принимала только новое значение endpointAuthorization после подтверждения успешного выполнения шага 2.

Удалить подписчика

Используйте конечную точку delete , чтобы удалить подписчика из вашего проекта. После удаления подписчик больше не будет получать уведомления.

Запрос

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

Ответ

В случае успешного удаления возвращается пустое тело ответа со статусом HTTP `200 OK`.
{}

Подписки пользователей

API Google Health помогает эффективно управлять подписками пользователей, сокращая необходимость ручной регистрации при первом подключении пользователей.

Автоматические подписки

Мы рекомендуем использовать автоматические подписки. Чтобы включить эту функцию, установите subscriptionCreatePolicy в значение AUTOMATIC в ваших subscriberConfigs для конкретных типов данных. dataTypes указанные в политике AUTOMATIC — это те же типы данных, для которых API Google Health отправляет уведомления, при условии, что для этих типов данных также получено согласие пользователя.

Когда пользователь предоставляет приложению согласие на использование данных, соответствующих типам данных с политикой AUTOMATIC , API Google Health автоматически отслеживает и отправляет уведомления для типов данных, возникающих в результате пересечения типов данных, на которые пользователь дал согласие, и типов данных автоматической конфигурации подписчика для этого пользователя. Затем уведомления отправляются на вашу конечную точку всякий раз, когда этот пользователь генерирует новые данные для этих типов. Это работает для пользователей, которые предоставляют согласие до или после создания подписчика. Уведомления не заполняются данными, сгенерированными до создания подписчика.

Если пользователь отзывает согласие, уведомления для соответствующих типов данных прекращаются. Автоматические подписки управляются Google и не могут быть перечислены или удалены по отдельности; они удаляются только при удалении основного подписчика.

Ручная подписка

Если вы предпочитаете управлять подписками для каждого пользователя вручную, установите subscriptionCreatePolicy в MANUAL в subscriberConfigs . При использовании этой политики подписки пользователей не создаются автоматически. Эта функция будет использоваться в будущем, когда станут доступны API для управления подписками вручную. До тех пор, пока эти API не станут доступны, мы рекомендуем использовать подписки AUTOMATIC .

Уведомления

Когда данные пользователя изменяются для указанного типа данных, API Google Health отправляет HTTPS POST-запрос на URL-адрес конечной точки подписчика.

Формат уведомления

Уведомление представляет собой JSON-объект, содержащий подробную информацию об изменении данных. Сюда входят идентификатор пользователя, тип данных и временные интервалы, которые можно использовать для запроса обновленных данных.

{
  "data": {
    "version": "1",
    "clientProvidedSubscriptionName": "subscription-name",
    "healthUserId": "health-user-id",
    "operation": "UPSERT",
    "dataType": "steps",
    "intervals": [
      {
        "physicalTimeInterval": {
          "startTime": "2026-03-0B01: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"
        }
      }
    ]
  }
}

В поле operation указывается тип изменения, вызвавшего уведомление:

  • UPSERT : Отправляется для добавления или изменения любых данных.
  • DELETE : Отправляется, когда пользователь удаляет данные, или когда данные удаляются в результате системного события, например, когда пользователь отзывает разрешение или удаляет свою учетную запись.

Мы рекомендуем сделать логику обработки уведомлений идемпотентной, особенно для операций UPSERT , поскольку повторные попытки могут привести к отправке дублирующих уведомлений.

Поле clientProvidedSubscriptionName представляет собой уникальный идентификатор. Для подписок с политикой MANUAL это поле содержит постоянное имя подписки, предоставленное разработчиком и указанное при создании подписки. Это обеспечивает стабильный идентификатор для управления подписками, созданными вручную. Для подписок, созданных с политикой AUTOMATIC , API Google Health автоматически генерирует и присваивает этому полю уникальный идентификатор (случайный UUID) для каждого уведомления. Включение поля clientProvidedSubscriptionName как для ручных, так и для автоматических политик обеспечивает согласованный формат полезной нагрузки уведомлений для всех типов подписок.

healthUserId — это идентификатор пользователя в Google Health API, данные которого изменились. Если ваше приложение поддерживает несколько пользователей, вы можете получать уведомления для любого пользователя, предоставившего вашему приложению согласие на обработку данных. При получении уведомления используйте healthUserId , чтобы определить, данные какого пользователя изменились, и использовать его учетные данные OAuth для запроса этих данных.

Чтобы сопоставить учетные данные OAuth пользователя с его healthUserId , используйте конечную точку getIdentity . Вызовите эту конечную точку с учетными данными пользователя во время регистрации, чтобы получить его healthUserId , и сохраните это сопоставление. Это сопоставление не меняется со временем, поэтому его можно кэшировать неограниченно долго. Пример см. в разделе «Получение идентификатора пользователя» . Это позволяет выбирать правильные учетные данные пользователя при запросе данных на основе healthUserId в уведомлении.

Ответить на уведомление

Ваш сервер должен немедленно отвечать на уведомления кодом состояния HTTP 204 No Content . Во избежание таймаутов обрабатывайте полезную нагрузку уведомления асинхронно после отправки ответа. Если API Google Health получает какой-либо другой код состояния или запрос истекает по таймауту, он повторяет попытку отправки уведомления позже.

Пример использования 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
    });
});

Статус подписчика и восстановление

Если конечная точка для ваших подписчиков становится недоступной или возвращает код ошибки (любой, кроме 204 ), API Google Health сохраняет ожидающие уведомления на срок до 7 дней и повторяет попытку доставки с экспоненциальной задержкой.

Как только ваша конечная точка снова станет доступной и ответит кодом 204 , API автоматически доставит вам список сохраненных сообщений. Уведомления старше 7 дней будут удалены и не подлежат восстановлению.