वेबबुक की सदस्यताएं

Google Health API की मदद से, आपके ऐप्लिकेशन को रीयल-टाइम में सूचनाएं मिल सकती हैं. ऐसा तब होता है, जब किसी उपयोगकर्ता की सेहत के डेटा में बदलाव होता है. Google Health API में डेटा उपलब्ध होते ही, आपके सर्वर को बदलावों के लिए पोलिंग करने के बजाय, एचटीटीपीएस पोस्ट अनुरोध वेबहुक मिलता है.

डेटा टाइप, जो इस्तेमाल किए जा सकते हैं

वेबहुक सूचनाएं, इस तरह के डेटा के लिए काम करती हैं:

टेबल: Google Health API के डेटा टाइप, जिनमें वेबहुक की सुविधा काम करती है
डेटा टाइप उपलब्ध
कार्रवाइयां
दायरा
ऐक्टिव मिनट
dataType: active-minutes
filter parameter: active_minutes
रिकॉर्ड टाइप: इंटरवल
स्टोरेज से जुड़ी समस्या हल होने में लगने वाला समय: एक मिनट

संगत डिवाइस

  • Fitbit Air
  • Fitbit Alta
  • Fitbit Alta HR
  • Fitbit Blaze
  • Fitbit Charge 2
  • Fitbit Charge 3
  • Fitbit Flex 2
  • Fitbit Inspire
  • Fitbit Inspire HR
  • Pixel Watch 4
list, reconcile, rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
ऐक्टिव ज़ोन मिनट
dataType: active-zone-minutes
filter parameter: active_zone_minutes
रिकॉर्ड टाइप: इंटरवल
स्टोरेज से जुड़ी समस्या हल होने में लगने वाला समय: एक मिनट

संगत डिवाइस

list, reconcile, rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
गतिविधि का लेवल
dataType: activity-level
filter parameter: activity_level
रिकॉर्ड टाइप: इंटरवल
सूची, मिलान करें .activity_and_fitness.readonly
.activity_and_fitness.writeonly
ऊंचाई
dataType: altitude
filter parameter: altitude
रिकॉर्ड टाइप: इंटरवल
स्टोरेज से जुड़ी समस्या हल होने में लगने वाला समय: एक मिनट
list, reconcile, rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
ब्लड ग्लूकोज़
dataType: blood-glucose
filter parameter: blood_glucose
रिकॉर्ड टाइप: सैंपल
list, get, reconcile, rollup, dailyRollup .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
बॉडी फ़ैट
dataType: body-fat
filter parameter: body_fat
रिकॉर्ड टाइप: सैंपल

संगत डिवाइस

list, get, reconcile, rollup, dailyRollup, create, update, batchDelete .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
धड़कन की दर वाले ज़ोन में बर्न की गई कैलोरी
dataType: calories-in-heart-rate-zone
filter parameter: calories_in_heart_rate_zone
रिकॉर्ड टाइप: इंटरवल
स्टोरेज से जुड़ी समस्या हल होने में लगने वाला समय: एक मिनट
rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
धड़कन की दर में रोज़ाना होने वाले उतार-चढ़ाव का डेटा
dataType: daily-heart-rate-variability
filter parameter: daily_heart_rate_variability
रिकॉर्ड टाइप: रोज़ाना

संगत डिवाइस

सूची, मिलान करें .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
धड़कन की दर वाले ज़ोन की रोज़ की जानकारी
dataType: daily-heart-rate-zones
filter parameter: daily_heart_rate_zones
रिकॉर्ड टाइप: रोज़ाना
सूची, मिलान करें .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
ऑक्सीजन की मात्रा का रोज़ का डेटा
dataType: daily-oxygen-saturation
filter parameter: daily_oxygen_saturation
रिकॉर्ड टाइप: रोज़ाना

संगत डिवाइस

सूची, मिलान करें .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
सांस की दर का रोज़ का डेटा
dataType: daily-respiratory-rate
filter parameter: daily_respiratory_rate
रिकॉर्ड टाइप: रोज़ाना

संगत डिवाइस

सूची, मिलान करें .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
आराम करते समय धड़कन की दर का रोज़ का डेटा
dataType: daily-resting-heart-rate
filter parameter: daily_resting_heart_rate
रिकॉर्ड टाइप: रोज़ाना

संगत डिवाइस

सूची, मिलान करें .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
सोने के समय के तापमान का रोज़ाना का डेटा
dataType: daily-sleep-temperature-derivations
filter parameter: daily_sleep_temperature_derivations
रिकॉर्ड टाइप: रोज़ाना

संगत डिवाइस

सूची, मिलान करें .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
दूरी
dataType: distance
filter parameter: distance
रिकॉर्ड टाइप: इंटरवल
स्टोरेज से जुड़ी समस्या हल होने में लगने वाला समय: एक मिनट

संगत डिवाइस

list, reconcile, rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
कसरत
dataType: exercise
filter parameter: exercise
रिकॉर्ड टाइप: सेशन

संगत डिवाइस

list, get, reconcile, create, update, batchDelete .activity_and_fitness.readonly
.activity_and_fitness.writeonly
फ़्लोर
dataType: floors
filter parameter: floors
रिकॉर्ड टाइप: इंटरवल
स्टोरेज से जुड़ी समस्या हल होने में लगने वाला समय: एक मिनट
reconcile, rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
धड़कन की दर
dataType: heart-rate
filter parameter: heart_rate
रिकॉर्ड टाइप: सैंपल
स्टोरेज से जुड़ी समस्या हल करने में लगने वाला समय: एक सेकंड

संगत डिवाइस

list, reconcile, rollup, dailyRollup .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
धड़कन की दर में उतार-चढ़ाव
dataType: heart-rate-variability
filter parameter: heart_rate_variability
रिकॉर्ड टाइप: सैंपल

संगत डिवाइस

सूची, मिलान करें .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
ऊंचाई
dataType: height
filter parameter: height
रिकॉर्ड टाइप: सैंपल
list, get, reconcile, create, update, batchDelete .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
हाइड्रेशन का लॉग
dataType: hydration-log
filter parameter: hydration_log
रिकॉर्ड टाइप: सेशन
list, get, reconcile, rollup, dailyRollup, create, update, batchDelete .nutrition.readonly
.nutrition.writeonly
पोषण से जुड़ा डेटा लॉग करें
dataType: nutrition-log
filter parameter: nutrition_log
रिकॉर्ड टाइप: सेशन

संगत डिवाइस

list, get, reconcile, rollup, dailyRollup, create, update, batchDelete .nutrition.readonly
.nutrition.writeonly
सोते समय सांस की दर की खास जानकारी
dataType: respiratory-rate-sleep-summary
filter parameter: respiratory_rate_sleep_summary
रिकॉर्ड टाइप: सैंपल

संगत डिवाइस

सूची, मिलान करें .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly
दौड़ते समय वीओ2 मैक्स
dataType: run-vo2-max
filter parameter: run_vo2_max
रिकॉर्ड टाइप: सैंपल

संगत डिवाइस

list, reconcile, rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
बैठे रहने की अवधि
dataType: sedentary-period
filter parameter: sedentary_period
रिकॉर्ड टाइप: इंटरवल

संगत डिवाइस

list, reconcile, rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
सोने के समय का तापमान
dataType: sleep
filter parameter: sleep
रिकॉर्ड टाइप: सेशन

संगत डिवाइस

list, get, reconcile, create, update, batchDelete .sleep.readonly
.sleep.writeonly
तरीका
dataType: steps
filter parameter: steps
रिकॉर्ड टाइप: इंटरवल
स्टोरेज से जुड़ी समस्या हल होने में लगने वाला समय: एक मिनट

संगत डिवाइस

list, reconcile, rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
धड़कन की दर वाले ज़ोन में बिताया गया समय
dataType: time-in-heart-rate-zone
filter parameter: time_in_heart_rate_zone
रिकॉर्ड टाइप: इंटरवल
स्टोरेज से जुड़ी समस्या हल होने में लगने वाला समय: एक मिनट
list, reconcile, rollup, dailyRollup .activity_and_fitness.readonly
.activity_and_fitness.writeonly
वज़न
dataType: weight
filter parameter: weight
रिकॉर्ड टाइप: सैंपल

संगत डिवाइस

list, get, reconcile, rollup, dailyRollup, create, update, batchDelete .health_metrics_and_measurements.readonly
.health_metrics_and_measurements.writeonly

सूचनाओं के स्कोप

इन डेटा टाइप के लिए सूचनाएं सिर्फ़ तब भेजी जाती हैं, जब उपयोगकर्ता ने इनमें से किसी एक स्कोप के लिए सहमति दी हो:

  • गतिविधि, जिसमें ऐक्टिव मिनट, कदमों की संख्या, ऊंचाई, दूरी, और मंज़िलों के डेटा टाइप शामिल हैं:
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.readonly
    • https://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
  • सेहत की मेट्रिक, जिसमें वज़न का डेटा टाइप शामिल है:
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonly
    • https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.writeonly
  • नींद, जिसमें नींद से जुड़ा डेटा टाइप शामिल है:
    • https://www.googleapis.com/auth/googlehealth.sleep.readonly
    • https://www.googleapis.com/auth/googlehealth.sleep.writeonly

IAM सेवा खाते

Google Health API के लिए, सदस्यता लेने वाले लोगों को कॉन्फ़िगर करते समय, IAM सेवा खाते का इस्तेमाल करने का सुझाव दिया जाता है. हालांकि, ऐसा करना ज़रूरी नहीं है. सेवा खाते, सामान्य उपयोगकर्ता खातों की तुलना में ऐप्लिकेशन के वर्कलोड को बेहतर सुरक्षा देते हैं. इसके लिए, वे इन सुविधाओं का इस्तेमाल करते हैं:

  • कम समय के लिए मान्य क्रेडेंशियल अपने-आप जनरेट होना: जब सेवा खातों को Google Cloud के एक्ज़ीक्यूशन एनवायरमेंट (जैसे, Compute Engine, Cloud Run या Google Kubernetes Engine) से अटैच किया जाता है, तब वे कम समय के लिए मान्य क्रेडेंशियल अपने-आप जनरेट करते हैं और उन्हें रोटेट करते हैं. इससे, स्टैटिक कुंजियों को मैनेज करने और उन्हें सेव करने से जुड़े जोखिम कम हो जाते हैं.
  • कम से कम अधिकारों का सिद्धांत: सेवा खाते, वर्कलोड के लिए खास आइडेंटिटी उपलब्ध कराते हैं. आपके पास उन्हें सिर्फ़ वे अनुमतियां देने का विकल्प होता है जो सब्सक्राइबर एंडपॉइंट को मैनेज करने के लिए ज़रूरी हैं. इससे उन्हें आपके Google Cloud संसाधनों का ज़्यादा ऐक्सेस नहीं मिलता.
  • लाइफ़साइकल की स्वतंत्रता: सेवा खाते, किसी उपयोगकर्ता के खाते से अलग काम करते हैं. इससे यह पक्का होता है कि कर्मचारियों में होने वाले बदलावों से, लंबे समय तक पुष्टि करने की प्रोसेस पर कोई असर न पड़े.

सेवा खाता सेट अप करना

सेवा खाते का इस्तेमाल करके पुष्टि करने के लिए, अपने सब्सक्राइबर ऐप्लिकेशन को कॉन्फ़िगर करने के लिए:

  1. सेवा खाता बनाएं: Google Cloud Console में, अपने प्रोजेक्ट के आईएएम और एडमिन पेज पर जाएं. इसके बाद, उपयोगकर्ता की ओर से मैनेज किया जाने वाला नया सेवा खाता बनाएं.
  2. ज़रूरी आईएएम भूमिकाएं दें: अपने Google Cloud प्रोजेक्ट पर सदस्यों को मैनेज करने के लिए, सेवा खाते को ज़रूरी भूमिकाएं असाइन करें.
  3. सेवा खाते को अपने वर्कलोड से अटैच करें: अपने सब्सक्राइबर लॉजिक को होस्ट करने वाले एनवायरमेंट को नए सेवा खाते के तौर पर चलाने के लिए कॉन्फ़िगर करें. इससे आपके ऐप्लिकेशन कोड (जैसे, Google API क्लाइंट लाइब्रेरी) को projects.subscribers REST API को कॉल करते समय, सेवा खाते के कुछ समय के लिए मान्य क्रेडेंशियल का अपने-आप पता लगाने और उनका इस्तेमाल करने की अनुमति मिलती है.

सीपीई की भूमिकाएं

Google Health API के सदस्यों या सदस्यताओं को मैनेज करने के लिए, आपको एपीआई कॉल करने वाले सेवा खाते को सही भूमिका देनी होगी. ज़रूरत के हिसाब से, इनमें से कोई एक भूमिका असाइन करें:

  • Google Health API Read
  • Google Health API Editor
  • Google Health API Admin

Google Health API के आईएएम की भूमिकाओं और अनुमतियों के बारे में ज़्यादा जानें.

सदस्यों को मैनेज करना

सूचनाएं पाने के लिए, आपको एक सब्सक्राइबर रजिस्टर करना होगा. यह सब्सक्राइबर, आपके ऐप्लिकेशन के सूचना एंडपॉइंट को दिखाता है. projects.subscribers पर उपलब्ध REST API का इस्तेमाल करके, सदस्यों को मैनेज किया जा सकता है.

यह ज़रूरी है कि आपका सब्सक्राइबर एंडपॉइंट, एचटीटीपीएस (TLSv1.2+) का इस्तेमाल करता हो और सार्वजनिक तौर पर ऐक्सेस किया जा सके. सदस्यता बनाने और उसे अपडेट करने के दौरान, Google Health API पुष्टि करने की प्रोसेस पूरी करता है. इससे यह पक्का किया जाता है कि एंडपॉइंट यूआरआई का मालिकाना हक आपके पास है. अगर पुष्टि नहीं हो पाती है, तो सदस्य बनाने और अपडेट करने की प्रोसेस पूरी नहीं हो पाती है. साथ ही, FailedPreconditionException गड़बड़ी दिखती है.

सदस्यता बनाएं

अपने प्रोजेक्ट के लिए नया सब्सक्राइबर रजिस्टर करने के लिए, create एंडपॉइंट का इस्तेमाल करें. आपको यह जानकारी देनी होगी:

  • project-id: उस प्रोजेक्ट का नंबर जिसमें वेबहुक सेवा खाता बनाया गया था.
  • subscriberId: वह यूनीक आइडेंटिफ़ायर जो आपने सदस्य के लिए उपलब्ध कराया है. इस आईडी में 4 से 36 वर्ण होने चाहिए. साथ ही, यह रेगुलर एक्सप्रेशन ([a-z]([a-z0-9-]{2,34}[a-z0-9])) से मेल खाना चाहिए.
  • endpointUri: वेबहुक की सूचनाओं के लिए डेस्टिनेशन यूआरएल.
  • subscriberConfigs: डेटा टाइप जिनके लिए आपको सूचनाएं चाहिए. साथ ही, हर डेटा टाइप के लिए सदस्यता की नीति.
  • endpointAuthorization: आपके एंडपॉइंट के लिए अनुमति देने का तरीका. इसमें आपका दिया गया secret शामिल होना चाहिए. secret की वैल्यू, हर सूचना मैसेज के साथ Authorization हेडर में भेजी जाती है. इस टोकन का इस्तेमाल करके, यह पुष्टि की जा सकती है कि आने वाले अनुरोध, Google Health API से हैं या नहीं. उदाहरण के लिए, Bearer की पुष्टि करने के लिए, secret को Bearer R4nd0m5tr1ng123 पर सेट किया जा सकता है. इसके अलावा, बुनियादी पुष्टि के लिए, Basic dXNlcjpwYXNzd29yZA== पर सेट किया जा सकता है.

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

जवाब

{
  "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"
    }
  ]
}

सदस्यों की सूची

अपने प्रोजेक्ट के लिए रजिस्टर किए गए सभी सदस्यों की जानकारी पाने के लिए, 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",
      "subscriberConfigs": [
        {
          "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
          "subscriptionCreatePolicy": "AUTOMATIC"
        },
        {
          "dataTypes": ["sleep"],
          "subscriptionCreatePolicy": "MANUAL"
        }
      ],
      "endpointAuthorization": {
        "authorizationTokenSet": true
      }
    }
  ],
  "totalSize": 1
}

सदस्य की जानकारी अपडेट करना

अपने प्रोजेक्ट में किसी सदस्य की जानकारी अपडेट करने के लिए, patch एंडपॉइंट का इस्तेमाल करें. endpointUri, subscriberConfigs, और endpointAuthorization फ़ील्ड अपडेट किए जा सकते हैं.

फ़ील्ड अपडेट करने के लिए, updateMask क्वेरी पैरामीटर और अनुरोध का मुख्य हिस्सा दें. updateMask में, उन फ़ील्ड के नामों की कॉमा लगाकर अलग की गई सूची होनी चाहिए जिन्हें आपको अपडेट करना है. फ़ील्ड के नामों के लिए, कैमल केस का इस्तेमाल करें. उदाहरण के लिए, endpointUri. अनुरोध के मुख्य हिस्से में, Subscriber ऑब्जेक्ट का कुछ हिस्सा होना चाहिए. इसमें उन फ़ील्ड की नई वैल्यू होनी चाहिए जिन्हें आपको अपडेट करना है. सिर्फ़ updateMask में बताए गए फ़ील्ड अपडेट किए जाते हैं. अगर अनुरोध के मुख्य हिस्से में ऐसे फ़ील्ड दिए जाते हैं जो updateMask में नहीं हैं, तो उन्हें अनदेखा कर दिया जाता है.

endpointUri या endpointAuthorization को अपडेट करने पर, एंडपॉइंट की पुष्टि की जाती है. ज़्यादा जानकारी के लिए, एंडपॉइंट की पुष्टि देखें.

subscriberConfigs को अपडेट करते समय, ध्यान दें कि यह पूरी तरह से बदल जाएगा, मर्ज नहीं होगा. अगर subscriberConfigs को updateMask में शामिल किया गया है, तो उस सदस्य के लिए सेव किए गए सभी कॉन्फ़िगरेशन, अनुरोध के मुख्य हिस्से में दी गई सूची से बदल दिए जाते हैं. किसी कॉन्फ़िगरेशन को जोड़ने या हटाने के लिए, आपको कॉन्फ़िगरेशन का पूरा सेट देना होगा. अगर आपको अन्य फ़ील्ड अपडेट करने हैं और मौजूदा कॉन्फ़िगरेशन को बनाए रखना है, तो updateMask से subscriberConfigs को हटा दें.

अनुरोध

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",
  "subscriberConfigs": [
    {
      "dataTypes": ["steps", "altitude", "distance", "floors", "weight"],
      "subscriptionCreatePolicy": "AUTOMATIC"
    },
    {
      "dataTypes": ["sleep"],
      "subscriptionCreatePolicy": "MANUAL"
    }
  ]
}

किसी सदस्य को हटाना

अपने प्रोजेक्ट से किसी सदस्य को हटाने के लिए, delete एंडपॉइंट का इस्तेमाल करें. सदस्यता रद्द करने के बाद, सदस्य को सूचनाएं नहीं मिलेंगी.

अनुरोध

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

जवाब

अगर डेटा मिटाने की प्रोसेस पूरी हो जाती है, तो एचटीटीपी स्टेटस `200 OK` के साथ जवाब का मुख्य हिस्सा खाली दिखता है.
{}

एंडपॉइंट की पुष्टि की सुविधा

सूचनाएं सुरक्षित और भरोसेमंद तरीके से डिलीवर हों, यह पक्का करने के लिए Google Health API, दो चरणों में पुष्टि करने की ज़रूरी प्रक्रिया को पूरा करता है. ऐसा तब किया जाता है, जब कोई सदस्य बनाया जाता है या उसके एंडपॉइंट कॉन्फ़िगरेशन (endpointUri या endpointAuthorization) को अपडेट किया जाता है. यह प्रोसेस, एपीआई कॉल के दौरान सिंक्रोनस तरीके से पूरी की जाती है. यह सेवा, उपयोगकर्ता एजेंट Google-Health-API-Webhooks का इस्तेमाल करके, आपके एंडपॉइंट यूआरआई को अपने-आप दो पोस्ट अनुरोध भेजती है. इसमें JSON बॉडी {"type": "verification"} का इस्तेमाल किया जाता है.

  • अनुमति वाला हैंडशेक: पहला अनुरोध, आपके कॉन्फ़िगर किए गए Authorization हेडर के साथ भेजा जाता है. आपके सर्वर को 200 OK या 201 Created स्टेटस के साथ जवाब देना चाहिए.
  • Unauthorized Challenge: दूसरा अनुरोध, क्रेडेंशियल के बिना भेजा जाता है. आपके सर्वर को 401 Unauthorized या 403 Forbidden स्टेटस के साथ जवाब देना चाहिए.

इस हैंडशेक से यह पुष्टि होती है कि आपका एंडपॉइंट चालू है और सुरक्षा को सही तरीके से लागू कर रहा है. अगर इनमें से कोई भी चरण पूरा नहीं होता है, तो एपीआई अनुरोध पूरा नहीं हो पाता है और FAILED_PRECONDITION गड़बड़ी का मैसेज दिखता है. इस हैंडशेक के पूरा होने के बाद ही, आपके सब्सक्राइबर को सेव किया जाता है. साथ ही, सेहत के डेटा से जुड़ी सूचनाएं पाने की सुविधा चालू की जाती है.

डेटा सुरक्षित करने वाली कुंजी का नया वर्शन बनाना

अगर आपको endpointAuthorization के लिए कुंजियां बदलनी हैं, तो यह तरीका अपनाएं:

  1. अपने एंडपॉइंट को इस तरह कॉन्फ़िगर करें कि वह endpointAuthorization की पुरानी और नई, दोनों वैल्यू स्वीकार करे.
  2. ?updateMask=endpointAuthorization के साथ patch अनुरोध का इस्तेमाल करके, सदस्य के कॉन्फ़िगरेशन को नई endpointAuthorization वैल्यू के साथ अपडेट करें.
  3. अपने एंडपॉइंट को इस तरह कॉन्फ़िगर करें कि वह सिर्फ़ नई endpointAuthorization वैल्यू स्वीकार करे. ऐसा, दूसरे चरण के पूरा होने की पुष्टि करने के बाद करें.

उपयोगकर्ता की सदस्यताएं

Google Health API की मदद से, उपयोगकर्ता की सदस्यताओं को बेहतर तरीके से मैनेज किया जा सकता है. इससे उपयोगकर्ता को शामिल करने के दौरान, मैन्युअल तरीके से रजिस्ट्रेशन करने की ज़रूरत कम हो जाती है.

अपने-आप होने वाली सदस्यताएं

हमारा सुझाव है कि आप अपने-आप रिन्यू होने वाली सदस्यताओं का इस्तेमाल करें. इस सुविधा को चालू करने के लिए, खास डेटा टाइप के लिए अपने subscriberConfigs में subscriptionCreatePolicy को AUTOMATIC पर सेट करें. AUTOMATIC नीति के तहत तय किया गया dataTypes, उसी तरह का डेटा होता है जिसके लिए Google Health API सूचनाएं भेजता है. हालांकि, इसके लिए ज़रूरी है कि उपयोगकर्ता ने उस तरह के डेटा के लिए सहमति दी हो.

जब कोई उपयोगकर्ता, AUTOMATIC नीति वाले डेटा टाइप से जुड़े स्कोप के लिए ऐप्लिकेशन को सहमति देता है, तो Google Health API अपने-आप डेटा टाइप को ट्रैक करता है और सूचनाएं भेजता है. ये सूचनाएं, उपयोगकर्ता की सहमति वाले डेटा टाइप और उस उपयोगकर्ता के लिए, अपने-आप सदस्यता लेने वाले कॉन्फ़िगरेशन के डेटा टाइप के बीच इंटरसेक्शन से मिलने वाले डेटा टाइप के लिए भेजी जाती हैं. जब भी वह उपयोगकर्ता उन टाइप के लिए नया डेटा जनरेट करेगा, तब आपके एंडपॉइंट पर सूचनाएं भेजी जाएंगी. यह उन उपयोगकर्ताओं के लिए काम करता है जो सदस्य बनाने से पहले या बाद में सहमति देते हैं. सदस्यता लेने से पहले जनरेट किए गए डेटा के लिए, सूचनाएं बैकफ़िल नहीं की जाती हैं.

अगर कोई उपयोगकर्ता सहमति वापस ले लेता है, तो उससे जुड़े डेटा टाइप के लिए सूचनाएं मिलनी बंद हो जाएंगी. अपने-आप होने वाली सदस्यताओं को Google मैनेज करता है. इन्हें अलग से न तो सूची में शामिल किया जा सकता है और न ही मिटाया जा सकता है. इन्हें सिर्फ़ तब हटाया जाता है, जब पैरंट सब्सक्राइबर को मिटाया जाता है.

मैन्युअल तरीके से सदस्यताएं मैनेज करना

अगर आपके सब्सक्राइबर को डेटा के कुछ टाइप के लिए, MANUAL subscription_create_policy के साथ कॉन्फ़िगर किया गया है, तो आपको हर उपयोगकर्ता के लिए साफ़ तौर पर सदस्यताएं बनानी और मैनेज करनी होंगी. सदस्यता, किसी उपयोगकर्ता को आपके सब्सक्राइबर एंडपॉइंट से जोड़ती है. ऐसा, डेटा टाइप के तय सेट के लिए किया जाता है. डेवलपर, खास एपीआई का इस्तेमाल करके ये काम कर सकते हैं:

  • हर healthUserId के लिए (मैन्युअल तरीके से) सदस्यताएं बनाएं - किसी उपयोगकर्ता के लिए नई सदस्यता बनाता है. इस तरीके का इस्तेमाल करने के लिए, ज़रूरी है कि सदस्य ने अनुरोध किए गए डेटा टाइप के लिए, SubscriptionCreatePolicy को MANUAL पर सेट किया हो.
  • सदस्यता को मैन्युअल तरीके से अपडेट करना - इससे किसी मौजूदा उपयोगकर्ता की सदस्यता के लिए डेटा टाइप अपडेट किए जाते हैं.
  • Delete (manual) subscription - इससे किसी उपयोगकर्ता की सदस्यता मिटाई जाती है. मिटाए जाने के बाद, आपके सब्सक्राइबर एंडपॉइंट को इस उपयोगकर्ता के लिए, जुड़े हुए डेटा टाइप की सूचनाएं नहीं मिलेंगी.
  • सदस्यताओं की सूची (मैन्युअल) - इसमें किसी सदस्य की सभी चालू सदस्यताओं की सूची होती है. नतीजों को उपयोगकर्ता या डेटा टाइप के हिसाब से फ़िल्टर किया जा सकता है.

सूचनाएं

जब किसी उपयोगकर्ता का डेटा, सदस्यता वाले डेटा टाइप के लिए बदलता है, तो Google Health API, सदस्य के एंडपॉइंट यूआरएल पर एचटीटीपीएस पोस्ट अनुरोध भेजता है.

सूचना का फ़ॉर्मैट

सूचना के पेलोड में, डेटा में हुए बदलाव की जानकारी होती है. इसमें यूज़र आईडी, डेटा टाइप, और समय अंतराल शामिल होते हैं. इनका इस्तेमाल करके, अपडेट किए गए डेटा के बारे में क्वेरी की जा सकती है. जब कई अपडेट होते हैं या अपडेट एग्रीगेट किए जाते हैं, तो सूचनाओं को एक साथ बैच किया जाता है. साथ ही, उन्हें सूचना ऑब्जेक्ट के JSON कलेक्शन के तौर पर डिलीवर किया जाता है.

वेबहुक से जुड़ी सूचना ट्रिगर होने पर, Google Health API आपके सब्सक्राइबर एंडपॉइंट पर एचटीटीपीएस पोस्ट अनुरोध भेजता है. यह अनुरोध इस फ़ॉर्मैट में भेजा जाता है:

अपसर्ट (टाइम-सीरीज़ डेटा)

POST https://your-endpoint-uri
Authorization: Bearer example-secret-token
GOOGLE-HEALTH-API-SIGNATURE: signature-value
Content-Type: application/json

{
  "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"
        }
      }
    ]
  }
}

मिटाएं (टाइम-सीरीज़ डेटा)

POST https://your-endpoint-uri
Authorization: Bearer example-secret-token
GOOGLE-HEALTH-API-SIGNATURE: signature-value
Content-Type: application/json

[
  {
    "data": {
      "version": "1",
      "clientProvidedSubscriptionName": "subscription-name",
      "healthUserId": "health-user-id",
      "operation": "DELETE",
      "dataType": "steps",
      "intervals": [
        {
          "physicalTimeInterval": {
            "startTime": "2026-08-12T12:00:00Z",
            "endTime": "2026-08-12T12:30:00Z"
          },
          "civilIso8601TimeInterval": {
            "startTime": "2026-08-12T12:00:00",
            "endTime": "2026-08-12T12:30:00"
          }
        }
      ]
    }
  }
]

मिटाना (पहचान ज़ाहिर करने वाला डेटा)

POST https://your-endpoint-uri
Authorization: Bearer example-secret-token
GOOGLE-HEALTH-API-SIGNATURE: signature-value
Content-Type: application/json

{
  "data": {
    "version": "1",
    "clientProvidedSubscriptionName": "subscription-name",
    "healthUserId": "health-user-id",
    "operation": "DELETE",
    "dataType": "sleep",
    "intervals": [
      {
        "physicalTimeInterval": {
          "startTime": "2026-08-12T22:00:00Z",
          "endTime": "2026-08-13T06:00:00Z"
        },
        "civilIso8601TimeInterval": {
          "startTime": "2026-08-12T22:00:00",
          "endTime": "2026-08-13T06:00:00"
        }
      }
    ],
    "recordId": "9875412"
  }
}

बैच (कई उपयोगकर्ताओं और डेटा टाइप के लिए)

POST https://your-endpoint-uri
Authorization: Bearer example-secret-token
GOOGLE-HEALTH-API-SIGNATURE: signature-value
Content-Type: application/json

[
  {
    "data": {
      "version": "1",
      "clientProvidedSubscriptionName": "auto-project-number-subscriber-id-WEBHOOK_DATA_TYPE_STEPS",
      "healthUserId": "health-user-id-1",
      "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"
          }
        }
      ]
    }
  },
  {
    "data": {
      "version": "1",
      "clientProvidedSubscriptionName": "auto-project-number-subscriber-id-WEBHOOK_DATA_TYPE_WEIGHT",
      "healthUserId": "health-user-id-1",
      "operation": "UPSERT",
      "dataType": "weight",
      "intervals": [
        {
          "physicalTimeInterval": {
            "startTime": "2026-03-07T15:14:00Z",
            "endTime": "2026-03-07T15:16:00Z"
          },
          "civilDateTimeInterval": {
            "startDateTime": {
              "date": {
                "year": 2026,
                "month": 3,
                "day": 7
              },
              "time": {
                "hours": 7,
                "minutes": 14
              }
            },
            "endDateTime": {
              "date": {
                "year": 2026,
                "month": 3,
                "day": 7
              },
              "time": {
                "hours": 7,
                "minutes": 16
              }
            }
          },
          "civilIso8601TimeInterval": {
            "startTime": "2026-03-07T07:14:00",
            "endTime": "2026-03-07T07:16:00"
          }
        }
      ]
    }
  },
  {
    "data": {
      "version": "1",
      "clientProvidedSubscriptionName": "auto-project-number-subscriber-id-WEBHOOK_DATA_TYPE_STEPS",
      "healthUserId": "health-user-id-2",
      "operation": "UPSERT",
      "dataType": "steps",
      "intervals": [
        {
          "civilDateTimeInterval": {
            "startDateTime": {
              "date": {
                "year": 2026,
                "month": 8,
                "day": 20
              },
              "time": {
                "hours": 0,
                "minutes": 0
              }
            },
            "endDateTime": {
              "date": {
                "year": 2026,
                "month": 8,
                "day": 21
              },
              "time": {
                "hours": 0,
                "minutes": 0
              }
            }
          },
          "civilIso8601TimeInterval": {
            "startTime": "2026-08-20T00:00:00",
            "endTime": "2026-08-21T00:00:00"
          }
        }
      ]
    }
  },
  {
    "data": {
      "version": "1",
      "clientProvidedSubscriptionName": "subscription-name",
      "healthUserId": "health-user-id-2",
      "operation": "UPSERT",
      "dataType": "sleep",
      "intervals": [
        {
          "physicalTimeInterval": {
            "startTime": "2026-08-12T22:00:00Z",
            "endTime": "2026-08-13T06:00:00Z"
          },
          "civilDateTimeInterval": {
            "startDateTime": {
              "date": {
                "year": 2026,
                "month": 8,
                "day": 12
              },
              "time": {
                "hours": 22,
                "minutes": 0
              }
            },
            "endDateTime": {
              "date": {
                "year": 2026,
                "month": 8,
                "day": 13
              },
              "time": {
                "hours": 6,
                "minutes": 0
              }
            }
          },
          "civilIso8601TimeInterval": {
            "startTime": "2026-08-12T22:00:00",
            "endTime": "2026-08-13T06:00:00"
          }
        }
      ],
      "recordId": "9875412"
    }
  }
]

operation फ़ील्ड से पता चलता है कि किस तरह के बदलाव की वजह से सूचना ट्रिगर हुई:

  • UPSERT: यह इवेंट, डेटा जोड़ने या उसमें बदलाव करने पर भेजा जाता है.
  • DELETE: यह तब भेजा जाता है, जब कोई उपयोगकर्ता साफ़ तौर पर डेटा मिटाता है. जैसे, Fitbit ऐप्लिकेशन का इस्तेमाल करके dataPoints को मिटाना या एपीआई का इस्तेमाल करके, एक साथ कई डेटा मिटाना. सिस्टम-लेवल पर डेटा मिटाने से जुड़े इवेंट के लिए, वेबहुक सूचनाएं नहीं भेजी जाती हैं. जैसे, किसी उपयोगकर्ता का ऐप्लिकेशन की अनुमतियां वापस लेना या अपना Fitbit खाता मिटाना.

हमारा सुझाव है कि सूचनाओं को मैनेज करने के लिए, आइडेंपोटेंट लॉजिक का इस्तेमाल करें. खास तौर पर, UPSERT कार्रवाइयों के लिए, क्योंकि फिर से कोशिश करने पर डुप्लीकेट सूचनाएं भेजी जा सकती हैं.

clientProvidedSubscriptionName फ़ील्ड एक यूनीक आइडेंटिफ़ायर है:

  • MANUAL नीति वाली सदस्यताओं के लिए, इस फ़ील्ड में सदस्यता का वह नाम शामिल होता है जो डेवलपर ने सदस्यता बनाते समय तय किया था. यह नाम हमेशा के लिए होता है. इससे मैन्युअल तरीके से ली गई सदस्यताओं को मैनेज करने के लिए, एक स्टेबल आईडी मिलता है.
  • AUTOMATIC नीति के तहत बनाई गई सदस्यताओं के लिए, Google Health API अपने-आप एक आइडेंटिफ़ायर जनरेट करता है और उसे असाइन करता है. इसका फ़ॉर्मैट इस तरह का होता है: auto-<project-number>-<subscriber-id>-<WEBHOOK_DATA_TYPE_TOKEN>, जहां:
    • <project-number>, डेवलपर के Google Cloud प्रोजेक्ट का नंबर है. उदाहरण के लिए, 362978535920.
    • <subscriber-id>, सदस्य का रजिस्ट्रेशन आईडी / सदस्य का नाम है (उदाहरण के लिए, google-health-sync).
    • <WEBHOOK_DATA_TYPE_TOKEN>, खास डेटा टाइप को दिखाने वाला टोकन है. सभी संभावित टोकन के लिए, वेबहुक डेटा टाइप टोकन की शब्दावली देखें.

मैन्युअल और अपने-आप लागू होने वाली नीतियों, दोनों के लिए clientProvidedSubscriptionName को शामिल करने से, सभी तरह की सदस्यताओं के लिए सूचना पेलोड का फ़ॉर्मैट एक जैसा रहता है.

यूज़र आईडी की मैपिंग

healthUserId, उस उपयोगकर्ता के लिए Google Health API आइडेंटिफ़ायर है जिसका डेटा बदला है. अगर आपका ऐप्लिकेशन कई उपयोगकर्ताओं के लिए काम करता है, तो आपको उन सभी उपयोगकर्ताओं के लिए सूचनाएं मिल सकती हैं जिन्होंने आपके ऐप्लिकेशन को सहमति दी है. जब आपको कोई सूचना मिलती है, तो healthUserId का इस्तेमाल करके यह पता लगाएं कि किस उपयोगकर्ता का डेटा बदला है. इससे, उसके डेटा के बारे में क्वेरी करने के लिए, उसके OAuth क्रेडेंशियल का इस्तेमाल किया जा सकता है.

किसी उपयोगकर्ता के OAuth क्रेडेंशियल को उसके healthUserId से मैप करने के लिए, getIdentity एंडपॉइंट का इस्तेमाल करें. उपयोगकर्ता के शामिल होने के दौरान, उसके क्रेडेंशियल के साथ इस एंडपॉइंट को कॉल करें, ताकि उसका healthUserId वापस पाया जा सके. साथ ही, इस मैपिंग को सेव करें. यह मैपिंग समय के साथ नहीं बदलती. इसलिए, इसे हमेशा के लिए कैश मेमोरी में सेव किया जा सकता है. उदाहरण के लिए, यूज़र आईडी पाना लेख पढ़ें. इससे आपको सूचना में मौजूद healthUserId के आधार पर डेटा के लिए क्वेरी करते समय, उपयोगकर्ता के सही क्रेडेंशियल चुनने में मदद मिलती है.

समय अंतराल

intervals कलेक्शन में एक या उससे ज़्यादा ऑब्जेक्ट होते हैं. ये ऑब्जेक्ट, बदले गए डेटा के लिए समय के अंतराल को दिखाते हैं:

फ़ील्ड प्रकार ज़रूरी है ब्यौरा
physicalTimeInterval object नहीं बदले गए डेटा का यूटीसी फ़िज़िकल टाइम इंटरवल (YYYY-MM-DDTHH:MM:SSZ फ़ॉर्मैट). इंट्रा-डे मेट्रिक के लिए पॉप्युलेट किया गया; रोज़ के रोलअप और पूरे दिन की ऐक्टिविटी के लिए शामिल नहीं किया गया.
civilDateTimeInterval object हां बदले गए डेटा की स्थानीय कैलेंडर तारीख और समय का इंटरवल. इसमें यूटीसी या टाइमज़ोन ऑफ़सेट शामिल नहीं होता.
civilIso8601TimeInterval object हां स्थानीय समय अंतराल को आईएसओ 8601 स्ट्रिंग (YYYY-MM-DDTHH:MM:SS फ़ॉर्मैट) के तौर पर दिखाया जाता है. इसमें यूटीसी या टाइमज़ोन ऑफ़सेट शामिल नहीं होते.

पूरे दिन की गतिविधियों और रोज़ाना के एग्रीगेट के लिए, सूचना के पेलोड से physicalTimeInterval फ़ील्ड को जान-बूझकर हटा दिया जाता है. ऐसा इसलिए होता है, क्योंकि पूरे दिन के इवेंट को उनकी सामान्य तारीख के हिसाब से बकेट किया जाता है. साथ ही, टाइमज़ोन बदलने पर, इवेंट की अवधि गलत हो सकती है. पूरे दिन के इवेंट प्रोसेस करते समय, आपको सबसे सही तरीके के तौर पर civilDateTimeInterval या civilIso8601TimeInterval फ़ील्ड पर भरोसा करना चाहिए. सिविल टाइम फ़िल्टर का इस्तेमाल करके, इन डेटा पॉइंट के बारे में क्वेरी करने के तरीके के बारे में जानने के लिए, इंटरवल सिविल स्टार्ट टाइम के हिसाब से डेटा फ़िल्टर करना लेख पढ़ें.

यहां पूरे दिन की गतिविधि के लिए, सूचना के पेलोड का एक उदाहरण दिया गया है. इसमें physicalTimeInterval फ़ील्ड को शामिल नहीं किया गया है:

{
  "data": {
    "version": "1",
    "clientProvidedSubscriptionName": "auto-503461148219-lindasubscriber-WEBHOOK_DATA_TYPE_STEPS",
    "healthUserId": "343864966078399341",
    "operation": "UPSERT",
    "dataType": "steps",
    "intervals": [
      {
        "civilDateTimeInterval": {
          "startDateTime": {
            "date": {
              "year": 2026,
              "month": 7,
              "day": 14
            },
            "time": {}
          },
          "endDateTime": {
            "date": {
              "year": 2026,
              "month": 7,
              "day": 15
            },
            "time": {}
          }
        },
        "civilIso8601TimeInterval": {
          "startTime": "2026-07-14T00:00:00",
          "endTime": "2026-07-15T00:00:00"
        }
      }
    ]
  }
}

वेबहुक डेटा टाइप टोकन की शब्दावली

AUTOMATIC नीति का इस्तेमाल करने पर, जनरेट किए गए clientProvidedSubscriptionName में डेटा टाइप के आधार पर, अंग्रेज़ी के बड़े अक्षरों में लिखे गए WEBHOOK_DATA_TYPE_* सफ़िक्स टोकन में से कोई एक शामिल होता है:

वेबहुक डेटा टाइप टोकन इससे जुड़ा डेटा टाइप
WEBHOOK_DATA_TYPE_ACTIVE_MINUTES active-minutes
WEBHOOK_DATA_TYPE_ACTIVE_ZONE_MINUTES active-zone-minutes
WEBHOOK_DATA_TYPE_ACTIVITY_LEVEL activity-level
WEBHOOK_DATA_TYPE_ALTITUDE altitude
WEBHOOK_DATA_TYPE_BLOOD_GLUCOSE blood-glucose
WEBHOOK_DATA_TYPE_BODY_FAT body-fat
WEBHOOK_DATA_TYPE_CALORIES_IN_HEART_RATE_ZONE calories-in-heart-rate-zone
WEBHOOK_DATA_TYPE_DAILY_HEART_RATE_VARIABILITY daily-heart-rate-variability
WEBHOOK_DATA_TYPE_DAILY_HEART_RATE_ZONES daily-heart-rate-zones
WEBHOOK_DATA_TYPE_DAILY_OXYGEN_SATURATION daily-oxygen-saturation
WEBHOOK_DATA_TYPE_DAILY_RESPIRATORY_RATE daily-respiratory-rate
WEBHOOK_DATA_TYPE_DAILY_RESTING_HEART_RATE daily-resting-heart-rate
WEBHOOK_DATA_TYPE_DAILY_SLEEP_TEMPERATURE_DERIVATIONS daily-sleep-temperature-derivations
WEBHOOK_DATA_TYPE_DISTANCE distance
WEBHOOK_DATA_TYPE_EXERCISE exercise
WEBHOOK_DATA_TYPE_FLOORS floors
WEBHOOK_DATA_TYPE_HEART_RATE heart-rate
WEBHOOK_DATA_TYPE_HEART_RATE_VARIABILITY heart-rate-variability
WEBHOOK_DATA_TYPE_HEIGHT height
WEBHOOK_DATA_TYPE_HYDRATION_LOG hydration-log
WEBHOOK_DATA_TYPE_NUTRITION_LOG nutrition-log
WEBHOOK_DATA_TYPE_RESPIRATORY_RATE_SLEEP_SUMMARY respiratory-rate-sleep-summary
WEBHOOK_DATA_TYPE_RUN_VO2_MAX run-vo2-max
WEBHOOK_DATA_TYPE_SEDENTARY_PERIOD sedentary-period
WEBHOOK_DATA_TYPE_SLEEP sleep
WEBHOOK_DATA_TYPE_STEPS steps
WEBHOOK_DATA_TYPE_TIME_IN_HEART_RATE_ZONE time-in-heart-rate-zone
WEBHOOK_DATA_TYPE_WEIGHT weight
WEBHOOK_DATA_TYPE_USER_DELETED user-deleted (सिस्टम इवेंट)
WEBHOOK_DATA_TYPE_USER_REVOKED_ACCESS user-revoked-access (सिस्टम इवेंट)

अपडेट का एग्रीगेशन

नेटवर्क ट्रैफ़िक को कम करने के लिए, Google Health API मैसेज को एक साथ बैच करता है. सिस्टम को इस तरह कॉन्फ़िगर किया गया है कि वह हर बैच में ज़्यादा से ज़्यादा 99 मैसेज भेज सके. ये मैसेज उपलब्ध होते ही अपने-आप पुश हो जाते हैं.

जब मैसेज बैच में भेजे जाते हैं, तो पेलोड को JSON कलेक्शन के तौर पर डिलीवर किया जाता है. इसमें कई सूचना ऑब्जेक्ट शामिल होते हैं. एक बैच में, कई उपयोगकर्ताओं के लिए अपडेट शामिल हो सकते हैं. ये अपडेट, डेटा टाइप की कई कैटगरी के लिए हो सकते हैं. पेलोड का उदाहरण देखने के लिए, सूचना के फ़ॉर्मैट वाले सेक्शन में मौजूद बैच (एक से ज़्यादा उपयोगकर्ता और डेटा टाइप) का उदाहरण देखें.

किसी सूचना का जवाब देना

आपके सर्वर को Authorization हेडर की पुष्टि करनी होगी. साथ ही, सिंक्रोनस एंडपॉइंट की पुष्टि के हैंडशेक को मैनेज करना होगा. इसके अलावा, डेटा में बदलाव की सूचनाओं का जवाब, एचटीटीपी 204 No Content स्टेटस कोड के साथ तुरंत देना होगा. टाइम आउट से बचने के लिए, जवाब भेजने के बाद सूचना के पेलोड को एसिंक्रोनस तरीके से प्रोसेस करें. अगर Google Health API को कोई अन्य स्टेटस कोड मिलता है या अनुरोध की समयसीमा खत्म हो जाती है, तो वह बाद में फिर से सूचना भेजने की कोशिश करता है.

Node.js (Express) का उदाहरण:

app.post('/webhook-receiver', (req, res) => {
    if (req.headers.authorization !== EXPECTED_SECRET) {
        return res.status(401).send();
    }
    if (req.body && !Array.isArray(req.body) && req.body.type === 'verification') {
        return res.status(200).send();
    }

    // 1. Immediately acknowledge the notification batch
    res.status(204).send();

    // 2. Normalize single-object or batched array notifications and reconcile asynchronously
    const notifications = Array.isArray(req.body) ? req.body : [req.body];
    setImmediate(async () => {
        for (const notification of notifications) {
            const { healthUserId, dataType, intervals = [] } = notification.data || {};
            console.log(`Update for user ${healthUserId} of type ${dataType}`);
            // Query /v4/users/${healthUserId}/dataTypes/${dataType}/dataPoints:reconcile?filter=...
            // for each interval in `intervals` (using >= and < comparators; for sleep, filter on
            // sleep.interval.end_time or sleep.interval.civil_end_time).
        }
    });
});

सूचना वाले हर इंटरवल के लिए अपडेट किया गया डेटा फ़ेच करने के लिए, इंटरवल की समयसीमा के लिए फ़िल्टर के साथ reconcile एंडपॉइंट को कॉल करें. यह सुविधा, कनेक्ट किए गए डिवाइसों से ओवरलैप होने वाले इंटरवल की डुप्लीकेट कॉपी अपने-आप हटा देती है. ज़्यादा जानकारी और उदाहरणों के लिए, इंटरवल डेटा का मिलान किया गया व्यू पाना लेख पढ़ें.

डेटा में बदलाव की सूचना मिलने के बाद, अपने डेटाबेस को अपडेट करने की तीन सामान्य रणनीतियां हैं:

  • सूची में शामिल करना (सुझाया गया): आने वाली सूचनाओं को मैसेज की सूची में शामिल करें. इसके बाद, सिस्टम के संसाधनों के आधार पर, उन्हें सूची से बाहर प्रोसेस करें.
  • तुरंत डेटा वापस पाना: अपने बैकएंड को निर्देश दें कि वह अपडेट किया गया डेटा फ़ेच करने और उसे अपने डेटाबेस में सेव करने के लिए, Google Health API को तुरंत कॉल करे.
  • लेज़ी अपडेट: उपयोगकर्ता के लोकल डेटाबेस रिकॉर्ड को डर्टी के तौर पर मार्क करें. साथ ही, Google Health API से अपडेट किया गया डेटा सिर्फ़ तब फ़ेच करें, जब उपयोगकर्ता अगली बार आपके ऐप्लिकेशन पर आए.

सूची बनाने की रणनीति की मदद से, डेटा को करीब-करीब रीयल-टाइम में प्रोसेस किया जा सकता है. साथ ही, एक साथ कई सूचनाएं मिलने पर भी यह रणनीति काम करती है. उदाहरण के लिए, अगर सेवा में रुकावट आने की वजह से, सूचनाओं का बैकलाॉग एक साथ डिलीवर हो जाता है. संसाधनों को बचाने के लिए, इन सूची को लंबे समय के अंतराल वाले बैच शेड्यूल (उदाहरण के लिए, हर तीन घंटे में) पर प्रोसेस करने का विकल्प चुना जा सकता है. हालांकि, इसका नुकसान यह है कि उपयोगकर्ता आम तौर पर अपने डेटा को रीयल-टाइम में अपडेट होते देखना चाहते हैं.

सबसे सही तरीके

डेटा अपडेट को भरोसेमंद और असरदार तरीके से मैनेज करने के लिए, ये सबसे सही तरीके अपनाएं:

  • Subscription API का इस्तेमाल करें: Subscription API का इस्तेमाल करें, ताकि जब किसी उपयोगकर्ता के पास डाउनलोड करने के लिए नया डेटा हो, तो आपको सूचना मिल सके. इससे आपको एंडपॉइंट पोल करने की ज़रूरत नहीं पड़ेगी.
  • सूचनाओं को सूची में जोड़ना और उन्हें अलग से प्रोसेस करना: सदस्यता से जुड़ी सूचनाएं मिलने पर, उन्हें सूची में जोड़ें और अपने सिस्टम के संसाधनों के आधार पर उन्हें अलग से प्रोसेस करें. अनुरोध को तुरंत स्वीकार करके, वेबहुक एंडपॉइंट को हल्का रखें.

हस्ताक्षर की पुष्टि करना

वेबहुक सूचनाओं की प्रामाणिकता पक्का करने के लिए, बाहर जाने वाली हर वेबहुक सूचना के रॉ JSON पेलोड पर, Tink के PublicKeySign का इस्तेमाल करके निजी पासकोड से हस्ताक्षर किया जाता है. इससे अनुरोध में GOOGLE-HEALTH-API-SIGNATURE एचटीटीपी हेडर में Base64-एन्कोड किया गया हस्ताक्षर मिलता है. ये साइनिंग पासकोड हर 30 दिन में अपने-आप बदल जाते हैं. साथ ही, इनसे जुड़ा आधिकारिक सार्वजनिक कीसेट, JSON फ़ाइल के तौर पर इस स्थायी यूआरएल पर उपलब्ध कराया जाता है: https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json.

हस्ताक्षर की पुष्टि करने का तरीका

Tink का इस्तेमाल करना (सुझाया गया): डेवलपर, Tink के PublicKeyVerify प्रिमिटिव का इस्तेमाल करके, हस्ताक्षर की पुष्टि कर सकते हैं. स्थायी यूआरएल से सार्वजनिक कीसेट फ़ेच करें. इसके बाद, कीसेट के साथ PublicKeyVerify प्रिमिटिव को इंस्टैंशिएट करें. साथ ही, डिकोड किए गए GOOGLE-HEALTH-API-SIGNATURE हेडर की पुष्टि, रॉ वेबहुक JSON पेलोड के साथ करें.

मैन्युअल तरीके से पुष्टि करना (Tink के बिना): अगर डेवलपर Tink का इस्तेमाल नहीं करना चाहते, तो वे मैन्युअल तरीके से हस्ताक्षर की पुष्टि कर सकते हैं. इसके लिए, उन्हें यह तरीका अपनाना होगा:

  1. यह GOOGLE-HEALTH-API-SIGNATURE हेडर को Base64-डिकोड करता है, ताकि 5-बाइट वाले Tink प्रीफ़िक्स को असल DER-एन्कोड किए गए हस्ताक्षर से अलग किया जा सके. Tink प्रीफ़िक्स में, 1-बाइट वाला वर्शन प्रीफ़िक्स और 4-बाइट वाला keyId शामिल होता है.
  2. https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json से JSON कीसेट फ़ेच करें.
  3. पार्स किए गए keyId से मैच होने वाली कुंजी ढूंढें और उसकी वैल्यू फ़ील्ड को Base64-डिकोड करें. इसमें सीरियलाइज़ किया गया EcdsaPublicKey प्रोटोकॉल बफ़र होता है.
  4. इस बाइनरी पेलोड से, बिग-एंडियन x और y निर्देशांक (Protobuf टैग 3 और 4) निकालें.
  5. निकाले गए x और y निर्देशांकों का इस्तेमाल करके, पहले से मौजूद क्रिप्टोग्राफ़ी लाइब्रेरी में स्टैंडर्ड ECDSA P-256 सार्वजनिक पासकोड को इंस्टैंशिएट करें.
  6. SHA-256 एल्गोरिदम का इस्तेमाल करके, निकाले गए डीईआर सिग्नेचर के हिसाब से, रॉ वेबहुक JSON पेलोड की पुष्टि करें.

सदस्यता की स्थिति और उसे वापस पाना

अगर आपका सब्सक्राइबर एंडपॉइंट उपलब्ध नहीं है या गड़बड़ी का स्टेटस कोड (204 के अलावा कुछ और) दिखाता है, तो Google Health API, बाकी बची सूचनाओं को सात दिनों तक सेव रखता है. साथ ही, एक्स्पोनेंशियल बैकऑफ़ की मदद से, उन्हें फिर से डिलीवर करने की कोशिश करता है.

जब आपका एंडपॉइंट फिर से ऑनलाइन हो जाता है और 204 के साथ जवाब देता है, तो एपीआई, सेव किए गए मैसेज के बैकलाॉग को अपने-आप डिलीवर कर देता है. सात दिन से पुरानी सूचनाएं खारिज कर दी जाती हैं और उन्हें वापस नहीं लाया जा सकता.

आम तौर पर होने वाली गड़बड़ियां

गड़बड़ी का कोड मैसेज ब्यौरा सुझाव
400 खराब अनुरोध संसाधन के नाम में अमान्य प्रोजेक्ट नंबर अनुरोध के यूआरएल में प्रोजेक्ट नंबर के बजाय, Google Cloud प्रोजेक्ट आईडी का इस्तेमाल करके, किसी सदस्य को मिटाया या अपडेट किया जा रहा हो. यह projects.subscribers एंडपॉइंट का इस्तेमाल करने वाली वेबहुक सदस्यताओं पर लागू होता है. अनुरोध के यूआरएल में, अपने Google Cloud प्रोजेक्ट नंबर का इस्तेमाल करें, न कि प्रोजेक्ट आईडी का.
403 निषिद्ध कॉल करने वाले व्यक्ति के पास अनुमति नहीं है अनुरोध के यूआरएल में प्रोजेक्ट नंबर के बजाय, Google Cloud प्रोजेक्ट आईडी का इस्तेमाल करके, सदस्य बनाने या उनकी सूची बनाने पर. यह projects.subscribers एंडपॉइंट का इस्तेमाल करने वाली वेबहुक सदस्यताओं पर लागू होता है. अनुरोध के यूआरएल में, अपने Google Cloud प्रोजेक्ट नंबर का इस्तेमाल करें, न कि प्रोजेक्ट आईडी का.