Google Health API به برنامه شما اجازه میدهد وقتی دادههای سلامتی کاربر تغییر میکند، اعلانهای همزمان دریافت کند. بهجای نظرسنجی برای تغییرات، سرور شما بهمحض دردسترس قرار گرفتن دادهها در Google Health API، درخواست HTTPS POST وبقلاب را دریافت میکند.
انواع دادههای پشتیبانیشده
اعلانهای Webhook برای انواع دادههای زیر پشتیبانی میشود:
| نوع داده | عملیات دردسترس |
حوزه |
|---|---|---|
|
دقیقههای فعال
dataType:
active-minutesfilter parameter: active_minutes
نوع گزارش: فاصله زمانی
وضوح ذخیرهسازی: ۱ دقیقه
دستگاههای سازگار
|
list, reconcile, rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
دقایق محدوده فعالیت
dataType:
active-zone-minutesfilter parameter: active_zone_minutes
نوع گزارش: فاصله زمانی
وضوح ذخیرهسازی: ۱ دقیقه
دستگاههای سازگار
|
list, reconcile, rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
سطح فعالیت
|
فهرست، تطبیق دادن | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
ارتفاع
|
list, reconcile, rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
قند خون
dataType:
blood-glucosefilter parameter: blood_glucose
نوع گزارش: نمونه
|
list, get, reconcile, rollup, dailyRollup | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
چربی بدن
dataType:
body-fatfilter 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-zonefilter parameter: calories_in_heart_rate_zone
نوع گزارش: فاصله زمانی
وضوح ذخیرهسازی: ۱ دقیقه
|
rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
تغییرپذیری ضربان قلب روزانه
dataType:
daily-heart-rate-variabilityfilter parameter: daily_heart_rate_variability
نوع ضبط: روزانه
دستگاههای سازگار
|
فهرست، تطبیق دادن | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
محدودههای ضربان قلب روزانه
dataType:
daily-heart-rate-zonesfilter parameter: daily_heart_rate_zones
نوع ضبط: روزانه
|
فهرست، تطبیق دادن | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
اشباع اکسیژن روزانه
dataType:
daily-oxygen-saturationfilter parameter: daily_oxygen_saturation
نوع ضبط: روزانه
دستگاههای سازگار
|
فهرست، تطبیق دادن | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
سرعت تنفس روزانه
dataType:
daily-respiratory-ratefilter parameter: daily_respiratory_rate
نوع ضبط: روزانه
دستگاههای سازگار
|
فهرست، تطبیق دادن | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
ضربان قلب روزانه در حالت استراحت
dataType:
daily-resting-heart-ratefilter parameter: daily_resting_heart_rate
نوع ضبط: روزانه
دستگاههای سازگار
|
فهرست، تطبیق دادن | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
انحرافات دمای خواب روزانه
dataType:
daily-sleep-temperature-derivationsfilter parameter: daily_sleep_temperature_derivations
نوع ضبط: روزانه
دستگاههای سازگار
|
فهرست، تطبیق دادن | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
مسافت
dataType:
distancefilter parameter: distance
نوع گزارش: فاصله زمانی
وضوح ذخیرهسازی: ۱ دقیقه
دستگاههای سازگار
|
list, reconcile, rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
ورزش
dataType:
exercisefilter parameter: exercise
نوع ضبط: جلسه
دستگاههای سازگار
|
list, get, reconcile, create, update, batchDelete | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
طبقات
|
reconcile, rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
ضربان قلب
dataType:
heart-ratefilter parameter: heart_rate
نوع گزارش: نمونه
وضوح فضای ذخیرهسازی: ۱ ثانیه
دستگاههای سازگار
|
list, reconcile, rollup, dailyRollup | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
تغییرپذیری ضربان قلب
dataType:
heart-rate-variabilityfilter parameter: heart_rate_variability
نوع گزارش: نمونه
دستگاههای سازگار
|
فهرست، تطبیق دادن | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
قد
|
list, get, reconcile, create, update, batchDelete | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
گزارش آبرسانی
|
list, get, reconcile, rollup, dailyRollup, create, update, batchDelete | .nutrition.readonly.nutrition.writeonly |
|
گزارش تغذیه
dataType:
nutrition-logfilter parameter: nutrition_log
نوع ضبط: جلسه
دستگاههای سازگار
|
list, get, reconcile, rollup, dailyRollup, create, update, batchDelete | .nutrition.readonly.nutrition.writeonly |
|
خلاصه اطلاعات خواب سرعت تنفس
dataType:
respiratory-rate-sleep-summaryfilter parameter: respiratory_rate_sleep_summary
نوع گزارش: نمونه
دستگاههای سازگار
|
فهرست، تطبیق دادن | .health_metrics_and_measurements.readonly.health_metrics_and_measurements.writeonly |
|
اجرای حداکثر اکسیژن مصرفی
dataType:
run-vo2-maxfilter parameter: run_vo2_max
نوع گزارش: نمونه
دستگاههای سازگار
|
list, reconcile, rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
دوره بیتحرکی
dataType:
sedentary-periodfilter parameter: sedentary_period
نوع گزارش: فاصله زمانی
دستگاههای سازگار
|
list, reconcile, rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
خواب
dataType:
sleepfilter parameter: sleep
نوع ضبط: جلسه
دستگاههای سازگار
|
list, get, reconcile, create, update, batchDelete | .sleep.readonly.sleep.writeonly |
|
مراحل
dataType:
stepsfilter parameter: steps
نوع گزارش: فاصله زمانی
وضوح ذخیرهسازی: ۱ دقیقه
دستگاههای سازگار
|
list, reconcile, rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
زمان در محدوده ضربان قلب
dataType:
time-in-heart-rate-zonefilter parameter: time_in_heart_rate_zone
نوع گزارش: فاصله زمانی
وضوح ذخیرهسازی: ۱ دقیقه
|
list, reconcile, rollup, dailyRollup | .activity_and_fitness.readonly.activity_and_fitness.writeonly |
|
وزن
dataType:
weightfilter 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.readonlyhttps://www.googleapis.com/auth/googlehealth.activity_and_fitness.writeonly
- سنجههای سلامتی که نوع داده وزن را پوشش میدهد:
https://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.readonlyhttps://www.googleapis.com/auth/googlehealth.health_metrics_and_measurements.writeonly
- خواب، که نوع داده خواب را پوشش میدهد:
https://www.googleapis.com/auth/googlehealth.sleep.readonlyhttps://www.googleapis.com/auth/googlehealth.sleep.writeonly
حسابهای سرویس IAM
هرچند الزامی نیست، توصیه میکنیم هنگام پیکربندی مشترکین برای Google Health API از حساب سرویس IAM استفاده کنید. حسابهای خدمات ازطریق ویژگیهای زیر، امنیت بهتری برای حجم کاری برنامهها درمقایسه با حسابهای کاربری استاندارد فراهم میکنند:
- اعتبارنامههای کوتاهمدت خودکارسازیشده: وقتی به محیط اجرای Google Cloud (مانند Compute Engine، Cloud Run، یا Google Kubernetes Engine) متصل میشوند، حسابهای سرویس بهطور خودکار اعتبارنامههای امن و کوتاهمدت را دریافت و تعویض میکنند. این کار خطرات مدیریت و ذخیره کردن کلیدهای ثابت دائمی را ازبین میبرد.
- اصل حداقل امتیاز: حسابهای سرویس هویتهای اختصاصی برای حجمهای کاری ارائه میدهند. میتوانید فقط اجازههای خاصی را که برای مدیریت نقاط پایانی مشترک لازم است به آنها اعطا کنید و از دسترسی گستردهتر به منابع Google Cloud خود جلوگیری کنید.
- استقلال چرخه حیات: حسابهای خدماتی مستقل از حساب هر کاربر حقیقی عمل میکنند، که این امر تضمین میکند تغییرات پرسنل بر پایداری اصالتسنجی بلندمدت تأثیر نمیگذارد.
راهاندازی حساب سرویس
برای پیکربندی برنامه مشترک خود برای اصالتسنجی بااستفاده از حساب سرویس:
- ایجاد حساب سرویس: در کنسول Google Cloud، به صفحه IAM و «سرپرست» پروژه بروید تا حساب سرویس جدیدی با مدیریت کاربر ایجاد کنید.
- اعطای نقشهای IAM لازم: نقشهای مناسب را به حساب سرویس اختصاص دهید که برای مدیریت مشترکین در پروژه Google Cloud شما لازم است.
- حساب خدمات را به حجم کاریتان پیوست کنید: محیط میزبان منطق مشترک را پیکربندی کنید تا بهعنوان حساب خدمات جدید اجرا شود.
این کار به کد برنامه شما (مانند کتابخانههای کارخواه Google API) اجازه میدهد
هنگام فراخوانی
projects.subscribersREST API، بهطور خودکار اعتبارنامههای کوتاهمدت حساب سرویس را شناسایی و استفاده کند.
نقشهای CPE
برای مدیریت «مشترکین» یا «اشتراکهای» Google Health API، باید نقش مناسب را به «حساب سرویس» جعلشده که تماسهای API را برقرار میکند اعطا کنید. بسته به سطح دسترسی موردنیاز، یکی از نقشهای زیر را اختصاص دهید:
- Google Health API Read
- ویرایشگر Google Health API
- Google Health API Admin
درباره اجازهها و نقشهای IAM در Google Health API بیشتر بدانید.
مدیریت مشترکان
قبلاز اینکه بتوانید اعلان دریافت کنید، باید «مشترک» ثبت کنید که
نشاندهنده نقطه پایانی اعلان برنامه شما است. میتوانید مشترکین را بااستفاده از REST API موجود در
projects.subscribers مدیریت کنید.
نقطه پایانی مشترک شما باید از HTTPS (TLSv1.2+) استفاده کند و بهطور عمومی دردسترس باشد.
درطول ایجاد و بهروزرسانی مشترک، Google Health API یک چالش درستیسنجی انجام میدهد تا مطمئن شود شما مالک URI نقطه پایانی هستید. اگر درستیسنجی
ناموفق باشد، عملیات ایجاد و بهروزرسانی مشترک با
FailedPreconditionException ناموفق خواهد بود.
ایجاد مشترک
برای ثبت مشترک جدید برای پروژهتان، از نقطه پایانی
create
استفاده کنید. باید موارد زیر را ارائه کنید:
-
project-id: شماره پروژهای که حساب سرویس وبقلاب در آن ایجاد شده است. subscriberId: شناسه یکتایی که برای مشترک ارائه میدهید. این شناسه باید بین ۴ تا ۳۶ نویسه باشد و با عبارت باقاعده ([a-z]([a-z0-9-]{2,34}[a-z0-9])) مطابقت داشته باشد.-
endpointUri: نشانی وب مقصد برای اعلانهای وبقلاب. subscriberConfigs: انواع دادههایی که میخواهید برای آنها اعلان دریافت کنید، و خطمشی اشتراک برای هرکدام.endpointAuthorization: سازوکار مجوز برای نقطه پایانی شما. این باید حاویsecretباشد که شما ارائه میدهید. مقدارsecretدر سرصفحهAuthorizationبا هر پیام اعلان ارسال میشود. میتوانید از این کد برای تأیید اینکه درخواستهای ورودی از Google Health API هستند استفاده کنید. برای مثال، میتوانیدsecretرا رویBearer R4nd0m5tr1ng123برای اصالتسنجی Bearer، یاBasic dXNlcjpwYXNzd29yZA==برای اصالتسنجی Basic تنظیم کنید.
در 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). بدنه درخواست باید حاوی شیء «مشترک» جزئی با مقادیر جدید برای فیلدهایی باشد که میخواهید بهروز کنید. فقط فیلدهای مشخصشده
در 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",
"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
پاسخ
اگر حذف موفقیتآمیز باشد، بدنه پاسخ خالی با وضعیت HTTP `200 OK` برگردانده میشود.{}درستیسنجی نقطه پایان
برای اطمینان از امنیت و قابلیت اطمینان ارسال اعلان، Google Health API هرگاه مشترکی ایجاد کنید یا پیکربندی نقطه پایانی آن را بهروز کنید (endpointUri یا endpointAuthorization)، یک دستدهی درستیسنجی دومرحلهای اجباری انجام میدهد. این فرایند بهصورت همزمان درطول فراخوانی API انجام میشود. این سرویس دو درخواست POST خودکار به URI نقطه پایانی شما ارسال میکند،
از User-Agent Google-Health-API-Webhooks استفاده میکند، و بدنه JSON آن
{"type": "verification"} است.
- دستدهی مجاز: اولین درخواست با سرصفحه
Authorizationپیکربندیشده شما ارسال میشود. سرور شما باید با وضعیت200 OKیا201 Createdپاسخ دهد. - Unauthorized Challenge: درخواست دوم بدون اطلاعات کاربری ارسال شده است.
سرور شما باید با وضعیت
401 Unauthorizedیا403 Forbiddenپاسخ دهد.
این دستدهی تأیید میکند که نقطه پایانی شما فعال است و بهدرستی امنیت را اعمال میکند. اگر هرکدام از مراحل ناموفق باشد، درخواست API با خطای
FAILED_PRECONDITION ناموفق میشود. فقط پساز موفقیتآمیز بودن این دستدهی، مشترک شما ذخیره و فعال میشود تا اعلانهای دادههای سلامتی را دریافت کند.
چرخش کلید
اگر لازم است کلیدهای endpointAuthorization را بچرخانید، این مراحل را دنبال کنید:
- نقطه پایانیتان را پیکربندی کنید تا هم مقادیر قدیمی و هم مقادیر جدید
endpointAuthorizationرا بپذیرد. - پیکربندی مشترک را با مقدار
endpointAuthorizationجدید بااستفاده از درخواستpatchبا?updateMask=endpointAuthorizationبهروز کنید. - پساز تأیید موفقیتآمیز بودن مرحله ۲،
نقطه پایانیتان را برای پذیرش فقط مقدار جدید
endpointAuthorizationپیکربندی کنید.
اشتراکهای کاربر
Google Health API به شما کمک میکند اشتراکهای کاربر را بهطور مؤثر مدیریت کنید و نیاز به ثبت دستی درطول آمادهسازی کاربر را کاهش دهید.
اشتراکهای خودکار
توصیه میکنیم از اشتراکهای خودکار استفاده کنید. برای فعال کردن این ویژگی،
subscriptionCreatePolicy را روی AUTOMATIC در subscriberConfigs برای
انواع داده خاص تنظیم کنید. dataTypes که با خطمشی AUTOMATIC مشخص میکنید
همان نوع دادههایی هستند که Google Health API برای آنها اعلان ارسال میکند،
بهشرطی که رضایت کاربر نیز برای آن نوع دادهها اعطا شده باشد.
وقتی کاربر برای گسترههایی که با انواع دادههای دارای خطمشی AUTOMATIC مطابقت دارند رضایت برنامه را اعطا میکند، Google Health API بهطور خودکار انواع دادههای حاصل از تقاطع بین انواع دادههای رضایتدادهشده کاربر و انواع دادههای پیکربندی مشترک خودکار برای آن کاربر را ردیابی میکند و برای آنها اعلان ارسال میکند. سپس هرگاه آن کاربر دادههای جدیدی برای آن نوعها تولید کند،
اعلانها به نقطه پایانی شما ارسال میشود. این روش برای کاربرانی کار میکند که
قبل یا بعداز ایجاد مشترک، رضایت خود را اعلام میکنند. اعلانها
برای دادههای تولیدشده قبلاز ایجاد مشترک، تکمیل نمیشوند.
اگر کاربری رضایتش را لغو کند، اعلانهای مربوط به انواع دادههای مربوطه متوقف خواهد شد. اشتراکهای خودکار توسط Google مدیریت میشوند و نمیتوان آنها را بهصورت جداگانه فهرست یا حذف کرد؛ این اشتراکها فقط زمانی برداشته میشوند که مشترک اصلی حذف شود.
اشتراکهای دستی
اگر مشترک شما با MANUAL subscription_create_policy
برای انواع دادههای خاص پیکربندی شده است، باید بهطور صریح اشتراکها را برای هر کاربر ایجاد و مدیریت کنید. «اشتراک» کاربر خاصی را برای مجموعه مشخصی از انواع داده به نقطه پایانی مشترک شما پیوند میدهد. توسعهدهندگان میتوانند از میاناهای برنامهسازی کاربردی خاصی برای موارد زیر استفاده کنند:
- ایجاد اشتراک (دستی) برای هر
healthUserId- اشتراک جدیدی برای کاربر خاصی ایجاد میکند. این روش مستلزم آن است که مشترکSubscriptionCreatePolicyرا برای انواع دادههای درخواستشده رویMANUALتنظیم کرده باشد. - بهروزرسانی اشتراک (دستی) - انواع داده را برای اشتراک کاربر موجود بهروز میکند.
- حذف اشتراک (دستی) - اشتراک کاربر خاصی را حذف میکند. پساز حذف، نقطه پایانی مشترک شما دیگر برای این کاربر برای انواع دادههای مرتبط اعلان دریافت نخواهد کرد.
- فهرست کردن اشتراکها (غیرخودکار) - همه اشتراکهای فعال را برای مشترک موردنظر فهرست میکند. میتوانید نتایج را براساس کاربر یا نوع داده فیلتر کنید.
اعلانها
وقتی دادههای کاربر برای نوع داده مشترکشده تغییر میکند، Google Health API درخواست HTTPS POST را به نشانی وب نقطه پایانی مشترک ارسال میکند.
قالب اعلان
بار داده اعلان حاوی جزئیاتی درباره تغییر داده است، ازجمله شناسه کاربر، نوع داده، و بازههای زمانی که میتوانید از آنها برای جستجوی دادههای بهروزشده استفاده کنید. وقتی چند بهروزرسانی انجام میشود یا بهروزرسانیها تجمیع میشوند، اعلانها باهم دستهبندی میشوند و بهصورت آرایه JSON از اشیای اعلان ارسال میشوند.
وقتی اعلان وبقلاب راهاندازی میشود، Google Health API درخواست HTTPS POST را با قالب زیر به نقطه پایانی مشترک شما ارسال میکند:
Upsert (دادههای سری زمانی)
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: زمانی ارسال میشود که کاربر بهطور صریح دادهها را حذف کند (مثلاً حذف کردنdataPointsبااستفاده از برنامه Fitbit یا انجام حذف دستهای بااستفاده از میانای برنامهسازی کاربردی). اعلانهای Webhook برای رویدادهای حذف در سطح سیستم، مانند لغو اجازههای برنامه توسط کاربر یا حذف حساب 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 |
نه | بازه زمانی فیزیکی UTC دادههای اصلاحشده (قالب YYYY-MM-DDTHH:MM:SSZ). برای سنجههای درونروز پر میشود؛ برای خلاصههای روزانه و فعالیتهای کل روز حذف میشود. |
civilDateTimeInterval |
object |
بله | تاریخ تقویم مدنی (محلی) و فاصله زمانی دادههای اصلاحشده، بدون ساعت هماهنگ جهانی یا انحراف منطقه زمانی. |
civilIso8601TimeInterval |
object |
بله | بازه زمانی مدنی (محلی) که بهصورت رشته ISO 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 پیامها را بهصورت دستهای ارسال میکند. سیستم بهگونهای پیکربندی شده است که حداکثر ۹۹ پیام در هر دسته ارسال کند، که بهمحض دردسترس قرار گرفتن بهطور خودکار ارسال میشوند.
وقتی پیامها دستهبندی میشوند، بار مفید بهعنوان آرایه JSON حاوی چند شیء اعلان ارسال میشود. یک دسته واحد میتواند شامل بهروزرسانیهای چند کاربر در چندین نوع داده مشترکشده باشد. برای مشاهده نمونه بار داده، به مثال دستهای (چند کاربر و نوع داده) در بخش «قالب اعلان» مراجعه کنید.
پاسخ دادن به اعلان
سرور شما باید سرصفحه Authorization را اعتبارسنجی کند، دستدهی همگام
درستیسنجی نقطه پایانی را مدیریت کند، و بلافاصله با رمز وضعیت HTTP 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 استفاده کنید تا وقتی کاربر دادههای جدیدی برای بارگیری دارد، بهجای نظرسنجی از نقاط پایانی، به شما اطلاع داده شود.
- اعلانها را بهطور جداگانه صفبندی و پردازش کنید: هنگام دریافت اعلانهای اشتراک، آنها را در صف قرار دهید و براساس منابع سیستم خود بهطور جداگانه پردازش کنید. با تأیید فوری درخواست، نقطه پایانی وبقلاب را سبک نگه دارید.
درستیسنجی امضا
برای اطمینان از اصالت اعلانهای Webhooks، بار داده JSON خام هر اعلان وبقلاب خروجی بااستفاده از PublicKeySign Tink با کلید خصوصی امضا میشود و امضای کدگذاریشده Base64 را در سرایند HTTP GOOGLE-HEALTH-API-SIGNATURE در درخواست ارائه میدهد. این کلیدهای امضا هر ۳۰ روز یکبار بهطور خودکار چرخانده میشوند و مجموعه کلیدهای عمومی رسمی مربوطه بهصورت فایل JSON در نشانی وب دائمی https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json توزیع میشود.
نحوه درستیسنجی کردن امضا
استفاده از Tink (توصیهشده): توسعهدهندگان میتوانند امضا را بااستفاده از
PublicKeyVerify
اولیه Tink درستیسنجی کنند. مجموعه کلید عمومی را از نشانی وب دائمی واکشی کنید،
PublicKeyVerify اولیه را با مجموعه کلید نمونهسازی کنید، و
سرصفحه GOOGLE-HEALTH-API-SIGNATURE رمزگشاییشده را دربرابر بار خالص JSON وبقلاب خام درستیسنجی کنید.
درستیسنجی دستی (بدون Tink): اگر توسعهدهندگان انتخاب کنند که از Tink استفاده نکنند، میتوانند با دنبال کردن این مراحل، امضا را بهصورت دستی درستیسنجی کنند:
- سرصفحه
GOOGLE-HEALTH-API-SIGNATUREرا با ۶۴پایهای رمزگشایی میکند تا پیشوند ۵ بایتی Tink (که حاوی پیشوند نسخه ۱ بایتی و keyId ۴ بایتی است) را از امضای واقعی کدبندیشده با DER جدا کند. - مجموعه کلید JSON را از https://www.gstatic.com/googlehealthapi/webhooks/webhooks_public_keyset.json واکشی کنید.
- کلید منطبق با keyId تجزیهشده را پیدا کنید و فیلد مقدار آن را که حاوی میانگیر پروتکل EcdsaPublicKey سریالیشده است، با Base64 رمزگشایی کنید.
- مختصات x و y با ترتیب بایتهای باارزشتر (برچسبهای Protobuf ۳ و ۴) را از این بارداده دودویی استخراج کن.
- بااستفاده از مختصات x و y استخراجشده، یک کلید عمومی استاندارد ECDSA P-256 را در کتابخانه رمزنگاری داخلی نمونهسازی کنید.
- پایهبار JSON وبقلاب خام را بااستفاده از الگوریتم SHA-256 دربرابر امضای DER استخراجشده درستیسنجی کنید.
وضعیت مشترک و بازیابی
اگر نقطه پایانی مشترک شما دردسترس نباشد یا کد وضعیت خطا برگرداند
(هر چیزی غیراز 204)، Google Health API اعلانهای معلقه را تا ۷ روز ذخیره میکند و تحویل را با عقبنشینی نمایی دوباره امتحان میکند.
وقتی نقطه پایانیتان دوباره آنلاین شد و با 204 پاسخ داد، API
بهطور خودکار پیامهای ذخیرهشده در صف انتظار را تحویل میدهد. اعلانهای قدیمیتر از ۷ روز دور انداخته میشوند و قابلبازیابی نیستند.
خطاهای رایج
| کد خطا | پیام | شرح | توصیه |
|---|---|---|---|
| خطای ۴۰۰ - درخواست نامناسب | شماره پروژه در نام منبع نامعتبر است | هنگام حذف یا بهروزرسانی مشترک بااستفاده از شناسه پروژه Google Cloud در نشانی وب درخواست بهجای شماره پروژه. این مورد برای اشتراکهای وبقلاب که از نقطه پایانی projects.subscribers استفاده میکنند اعمال میشود. |
از شماره پروژه Google Cloud در نشانی وب درخواست استفاده کنید، نه شناسه پروژه. |
| خطای ۴۰۳ - ممنوع است | تماسگیرنده اجازه ندارد | هنگام ایجاد یا فهرست کردن مشترکین بااستفاده از شناسه پروژه Google Cloud در نشانی وب درخواست بهجای شماره پروژه. این مورد برای اشتراکهای وبقلاب که از نقطه پایانی projects.subscribers استفاده میکنند اعمال میشود. |
از شماره پروژه Google Cloud در نشانی وب درخواست استفاده کنید، نه شناسه پروژه. |