ส่งข้อมูล Apple Health ไปยัง webhook
Apple Health ไม่มี Web API ข้อมูลของคุณจึงไปถึง webhook ได้ก็ต่อเมื่อมีแอปบน iPhone ส่งไปให้ Marrow Health ทำเรื่องนี้ได้ฟรี การทำงานอัตโนมัติจะ POST ตัวชี้วัดสุขภาพ การออกกำลังกาย เซ็ตเวทเทรนนิ่ง ไดอารี่อาหาร หรืออาการและอารมณ์ของคุณไปยัง URL ใดก็ได้ เป็น JSON หรือ CSV ตามเวลาที่คุณกำหนด แม้ปิดแอปอยู่ ด้านล่างคือวิธีตั้งค่า payload และตัวรับที่ใช้งานได้จริงสำหรับ n8n, Home Assistant และเซิร์ฟเวอร์ธรรมดา เราทำ Marrow
ตั้งค่าการทำงานอัตโนมัติ
- ใน Marrow Health เปิดแท็บส่งออก แล้วเลือก อัตโนมัติ จากนั้นเลือก การทำงานอัตโนมัติใหม่.
- วาง URL ของ webhook (ใช้ HTTPS) เพิ่มเฮดเดอร์ที่ตัวรับของคุณตรวจสอบ เช่น bearer token แบบ
Authorizationหรือคีย์ header-auth ของ n8n - เลือกชนิดข้อมูล: ตัวชี้วัดสุขภาพ, การออกกำลังกาย, บันทึกเวทเทรนนิ่ง, ไดอารี่โภชนาการ หรือ อาการและอารมณ์ หนึ่งการทำงานอัตโนมัติส่งได้หนึ่งชนิด และสร้างได้สูงสุดสิบรายการ
- เลือก JSON หรือ CSV ช่วงวันที่ (ค่าเริ่มต้นคือ ตั้งแต่ครั้งล่าสุด) และความถี่ในการทำงาน เป็นนาที ชั่วโมง หรือวัน
- เปิดใช้งาน แล้วแตะ สั่งทำงานตอนนี้ เพื่อส่ง payload แรกระหว่างที่คุณดูฝั่งตัวรับ
แต่ละคำขอเป็น 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"}]}
]}}
payload ของการออกกำลังกาย เวทเทรนนิ่ง โภชนาการ และอารมณ์ ตัวอย่างดิบแทนยอดรวมรายวัน และรูปแบบ CSV อยู่ในเอกสารอ้างอิงการทำงานอัตโนมัติ.
รับข้อมูลใน n8n
- เพิ่มโหนด Webhook ตั้ง HTTP Method เป็น
POSTและกำหนด path เช่นapple-health. - ถ้าต้องการใช้ความลับ ให้ตั้ง Authentication เป็น Header Auth แล้วใส่ชื่อและค่าของเฮดเดอร์เดียวกันในการทำงานอัตโนมัติของ Marrow
- คลิก Listen for test event แล้วแตะ สั่งทำงานตอนนี้ ใน Marrow ภายในสองนาที payload จะปรากฏในตัวแก้ไข
- เผยแพร่เวิร์กโฟลว์ แล้วชี้ Marrow ไปที่ Production URL (อันที่มี
/webhook/ไม่ใช่/webhook-test/) URL สำหรับทดสอบจะหยุดรับข้อมูลหลังการทดสอบ
payload อยู่ใต้ body ดังนั้นก้าวของวันนี้ในนิพจน์คือ {{ $json.body.data.metrics.find(m => m.name === 'step_count').data.at(-1).qty }} เพิ่มโหนด Split Out ที่ body.data.metrics เพื่อจัดการแต่ละตัวชี้วัดเป็นรายการของตัวเอง n8n รับ payload ได้สูงสุด 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เปิดอยู่โดยค่าเริ่มต้น ซึ่งรับ POST เฉพาะจากเครือข่ายในบ้านของคุณหรือ URL webhook บนคลาวด์ของ Nabu Casa ตั้งเป็นfalseเมื่อโทรศัพท์ POST ผ่านอินเทอร์เน็ตมายังที่อยู่ HTTPS ของคุณเอง- webhook ID เป็นความลับเพียงอย่างเดียว จึงควรตั้งให้ยาวและสุ่ม
(เอกสารทริกเกอร์ webhook ของ Home Assistant)
รับข้อมูลบนเซิร์ฟเวอร์ของคุณเอง
endpoint ใดก็ได้ที่รับ HTTPS POST และตอบกลับ 2xx ก็ใช้ได้ ตัวอย่างนี้เก็บทุก payload ลงไฟล์:
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 ไปยัง webhook ได้เช่นกัน และ JSON ของตัวชี้วัดมีโครงสร้างเหมือนของ Marrow การทำงานอัตโนมัติของมันต้องใช้ระดับ Premium
- Apple Shortcuts อ่านตัวอย่างข้อมูลสุขภาพและโพสต์ด้วย Get Contents of URL ได้ ผ่านระบบอัตโนมัติส่วนตัวตามเวลาที่ตั้งไว้ ใช้ฟรี แต่อ่านข้อมูลสุขภาพได้เฉพาะตอนที่ปลดล็อกโทรศัพท์ และคุณต้องสร้างและดูแลแต่ละตัวชี้วัดเอง
- export.zip ของ Apple เป็นข้อมูลสำรองทั้งหมดแบบครั้งเดียว ไม่ใช่ฟีดข้อมูล หากต้องการแปลงเป็น CSV ใช้ตัวแปลงในเบราว์เซอร์ของเรา.