שליחת נתוני Apple Health ל-webhook
ל-Apple Health אין API לרשת, ולכן הנתונים שלכם מגיעים ל-webhook רק כשאפליקציה ב-iPhone שולחת אותם. Marrow Health עושה זאת בחינם: אוטומציה שולחת POST עם מדדי הבריאות, האימונים, סטי הכוח, יומן התזונה או התסמינים ומצב הרוח שלכם לכל כתובת, כ-JSON או כ-CSV, לפי הלוח שתבחרו, כשהאפליקציה סגורה. להלן ההגדרה, המטען, ומקבלים שעובדים עבור n8n, Home Assistant ושרת פשוט. אנחנו מפתחים את Marrow.
הגדרת האוטומציה
- ב-Marrow Health, פתחו את לשונית ייצוא, ואז אוטומטי, ואז אוטומציה חדשה.
- הדביקו את כתובת ה-webhook שלכם (השתמשו ב-HTTPS). הוסיפו את הכותרות שהמקבל שלכם בודק, כמו אסימון bearer של
Authorizationאו מפתח header-auth של n8n. - בחרו את סוג הנתונים: מדדי בריאות, אימונים, יומן כוח, יומן תזונה או תסמינים ומצב רוח. אוטומציה אחת שולחת סוג אחד, ואפשר ליצור עד עשר.
- בחרו JSON או CSV, את טווח התאריכים (מאז הריצה האחרונה הוא ברירת המחדל) ואת תדירות ההרצה, בדקות, בשעות או בימים.
- הפעילו אותה והקישו על הפעל כעת כדי לשלוח מטען ראשון בזמן שאתם עוקבים אחרי המקבל.
כל בקשה היא POST עם Content-Type: application/json (או text/csv) והכותרות שלכם. כל הרצה, עם קוד התגובה שלה, מופיעה בהיסטוריה של האוטומציה באפליקציה.
מה מגיע
מדדי בריאות מגיעים כסיכומים יומיים, ביחידה שמצוינת ב-units. הדופק מגיע כממוצע, מינימום ומקסימום של כל יום, והשינה כל לילה עם השלבים שלו, בשעות:
{"data": {"metrics": [
{"name": "body_mass", "units": "kg",
"data": [{"date": "2026-09-11", "qty": 81.3}]},
{"name": "step_count", "units": "count",
"data": [{"date": "2026-09-11", "qty": 8746}]},
{"name": "heart_rate", "units": "bpm",
"data": [{"date": "2026-09-11", "Avg": 71, "Min": 52, "Max": 148}]},
{"name": "sleep_analysis", "units": "h",
"data": [{"date": "2026-09-11", "totalSleep": 7.2, "asleep": 7.2, "deep": 1.1, "rem": 1.6, "core": 4.3, "awake": 0.2,
"sleepStart": "2026-09-10 23:36:00 -0400", "sleepEnd": "2026-09-11 07:02:00 -0400"}]}
]}}
המטענים של אימונים, כוח, תזונה ומצב רוח, דגימות גולמיות במקום סיכומים יומיים, ומבנה ה-CSV נמצאים בהפניה של האוטומציות.
קבלה ב-n8n
- הוסיפו צומת Webhook. הגדירו את HTTP Method ל-
POSTותנו לו נתיב, למשלapple-health. - לסוד, הגדירו את Authentication ל-Header Auth והוסיפו את אותו שם כותרת ואותו ערך לאוטומציה ב-Marrow.
- לחצו על Listen for test event, ואז הקישו על הפעל כעת ב-Marrow בתוך שתי דקות. המטען יופיע בעורך.
- פרסמו את תהליך העבודה והפנו את Marrow אל ה-Production URL (זה שיש בו
/webhook/, לא/webhook-test/). כתובת הבדיקה מפסיקה להאזין אחרי בדיקה אחת.
המטען נמצא תחת body, ולכן הצעדים של היום הם {{ $json.body.data.metrics.find(m => m.name === 'step_count').data.at(-1).qty }} בביטוי. הוסיפו צומת Split Out על body.data.metrics כדי לטפל בכל מדד כפריט נפרד. n8n מקבל כברירת מחדל מטענים עד 16 MB, מה שמכסה שנים של סיכומים יומיים. הרצות בייצור מופיעות תחת Executions, לא בעורך. (תיעוד n8n Webhook)
קבלה ב-Home Assistant
טריגר webhook מקבל את ה-POST בכתובת /api/webhook/<webhook_id>. האוטומציה הזו שומרת את ספירת הצעדים האחרונה בעזר מספרי בשם input_number.steps_today (צרו אותו קודם, עם מקסימום מעל היום הטוב ביותר שלכם):
automation:
- alias: "Apple Health from Marrow"
triggers:
- trigger: webhook
webhook_id: "pick-a-long-random-id"
allowed_methods:
- POST
local_only: false
actions:
- action: input_number.set_value
target:
entity_id: input_number.steps_today
data:
value: >-
{{ ((trigger.json.data.metrics
| selectattr('name', 'eq', 'step_count') | first).data
| last).qty }}
- גוף ה-JSON נמצא ב-
trigger.jsonכי Marrow שולחContent-Type: application/json. local_onlyפועל כברירת מחדל, ולכן מתקבלות רק בקשות מרשת הבית שלכם או מכתובת webhook בענן של Nabu Casa. הגדירו אותו ל-falseכשהטלפון שולח דרך האינטרנט לכתובת ה-HTTPS שלכם.- מזהה ה-webhook הוא הסוד היחיד, ולכן עשו אותו ארוך ואקראי.
(תיעוד הטריגר webhook של Home Assistant)
קבלה בשרת שלכם
כל נקודת קצה שמקבלת POST ב-HTTPS ועונה 2xx מתאימה. זו מארכבת כל מטען לקובץ:
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
class H(BaseHTTPRequestHandler):
def do_POST(self):
body = self.rfile.read(int(self.headers.get("Content-Length", 0)))
with open(f"marrow-{int(time.time())}.json", "wb") as f:
f.write(body)
self.send_response(200)
self.end_headers()
HTTPServer(("0.0.0.0", 8798), H).serve_forever()
שימו אותה מאחורי HTTPS עם Cloudflare Tunnel, Tailscale Funnel או reverse proxy. אם אתם מעדיפים מסד נתונים שאפשר לשאול עליו שאילתות במקום תיקייה של קבצים, המראה באירוח עצמי של Marrow היא המקבל הזה כבר כתוב, וגם סוכני AI יכולים לשאול אותה.
שלושה כללים למקבל שאף פעם לא מאבד נתונים
- האחרון קובע. שמרו כל ערך לפי מדד ויום, וכתבו מעליו כשהוא חוזר. מאז הריצה האחרונה שולח שוב את היומיים האחרונים בכוונה, כי Apple Health ממשיך להשלים יום גם אחרי שהוא נגמר.
- שמרו קודם את הגוף הגולמי, ואז פענחו אותו. באג בפענוח לא אמור לעלות לכם בנתונים.
- ענו מהר. Marrow ממתין עד זמן ההמתנה שהגדרתם (60 שניות כברירת מחדל), ואם הרצה נכשלה, הוא מנסה שוב מהחלון המוצלח האחרון בתור הבא שלו.
מתי זה רץ?
בכל פעם ש-iOS מאפשר ל-Marrow לרוץ: אחרי סנכרון עם Apple Health, כשפותחים אותו, ובמהלך רענון ברקע, אחרי שעבר המרווח שבחרתם. iOS מחליט מתי רענון ברקע קורה, ולכן טלפון שנשאר נעול כל היום שולח כשיפתחו אותו שוב, ומאז הריצה האחרונה מכסה את הפער.
דרכים אחרות לעשות את זה
- Health Auto Export גם הוא שולח נתוני Apple Health ל-webhooks, ול-JSON של המדדים שלו יש אותו מבנה כמו של Marrow. האוטומציות שלו דורשות את מסלול Premium.
- Apple Shortcuts יכול לקרוא דגימות בריאות ולשלוח אותן עם Get Contents of URL, באוטומציה אישית בשעה קבועה. זה בחינם, זה יכול לקרוא נתוני Health רק כשהטלפון פתוח, ואתם בונים ומתחזקים כל מדד בעצמכם.
- export.zip של Apple הוא גיבוי מלא חד-פעמי, לא זרם נתונים. כדי להפוך אחד כזה ל-CSV, השתמשו בממיר שלנו בדפדפן.