Marrow Health
VI
Tải về

Gửi dữ liệu Apple Health tới webhook

Apple Health không có API web, nên dữ liệu của bạn chỉ tới được webhook khi một ứng dụng trên iPhone gửi nó. Marrow Health làm việc này miễn phí: một tác vụ tự động hóa POST chỉ số sức khỏe, bài tập, hiệp tập sức mạnh, nhật ký ăn uống, hoặc triệu chứng và tâm trạng của bạn tới bất kỳ URL nào, dưới dạng JSON hoặc CSV, theo lịch bạn chọn, kể cả khi đã đóng ứng dụng. Bên dưới là cách thiết lập, payload và các bên nhận chạy được cho n8n, Home Assistant và một máy chủ thông thường. Chúng tôi làm ra Marrow.

Thiết lập tác vụ tự động hóa

  1. Trong Marrow Health, mở tab Xuất, rồi Tự động, rồi Tự động hóa mới.
  2. Dán URL webhook của bạn (dùng HTTPS). Thêm các tiêu đề mà bên nhận kiểm tra, như token bearer Authorization hoặc khóa header-auth của n8n.
  3. Chọn loại dữ liệu: Chỉ số sức khỏe, Bài tập, Nhật ký tập sức mạnh, Nhật ký dinh dưỡng hoặc Triệu chứng và tâm trạng. Mỗi tác vụ gửi một loại dữ liệu, và bạn có thể có tối đa mười tác vụ.
  4. Chọn JSON hoặc CSV, khoảng ngày (Kể từ lần chạy trước là mặc định) và tần suất chạy, tính bằng phút, giờ hoặc ngày.
  5. Bật nó lên rồi chạm Chạy ngay để gửi payload đầu tiên trong lúc bạn theo dõi bên nhận.

Mỗi yêu cầu là một POST với Content-Type: application/json (hoặc text/csv) và các tiêu đề của bạn. Mỗi lần chạy, kèm mã phản hồi, được liệt kê trong lịch sử của tác vụ trong ứng dụng.

Dữ liệu nhận được

Chỉ số sức khỏe đến dưới dạng tổng theo ngày, theo đơn vị ghi trong units. Nhịp tim đến dưới dạng trung bình, thấp nhất và cao nhất của mỗi ngày, còn giấc ngủ là từng đêm kèm các giai đoạn, tính bằng giờ:

{"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 của bài tập, sức mạnh, dinh dưỡng và tâm trạng, mẫu thô thay cho tổng theo ngày, và cấu trúc CSV nằm ở trang tham chiếu tự động hóa.

Nhận trong n8n

  1. Thêm một node Webhook. Đặt HTTP Method thành POST và đặt cho nó một đường dẫn, chẳng hạn apple-health.
  2. Để có mật khẩu bí mật, đặt Authentication thành Header Auth và thêm cùng tên và giá trị header đó vào tác vụ tự động hóa của Marrow.
  3. Nhấp Listen for test event, rồi trong vòng hai phút chạm Chạy ngay trong Marrow. Payload sẽ hiện trong trình soạn thảo.
  4. Xuất bản workflow và trỏ Marrow tới Production URL (URL có /webhook/, không phải /webhook-test/). URL thử nghiệm ngừng lắng nghe sau một lần thử.

Payload nằm trong body, nên số bước chân hôm nay là {{ $json.body.data.metrics.find(m => m.name === 'step_count').data.at(-1).qty }} trong một biểu thức. Thêm một node Split Out trên body.data.metrics để xử lý mỗi chỉ số như một mục riêng. n8n mặc định nhận payload tới 16 MB, đủ cho nhiều năm tổng theo ngày. Các lần chạy production hiện trong Executions, không hiện trong trình soạn thảo. (Tài liệu n8n Webhook)

Nhận trong Home Assistant

Một trigger webhook nhận POST tại /api/webhook/<webhook_id>. Tác vụ tự động hóa này lưu số bước chân mới nhất vào một number helper tên input_number.steps_today (hãy tạo nó trước, với giá trị tối đa cao hơn ngày tốt nhất của bạn):

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 }}

(Tài liệu về trigger webhook của Home Assistant)

Nhận trên máy chủ của riêng bạn

Bất kỳ endpoint nào nhận HTTPS POST và trả lời 2xx đều dùng được. Cái này lưu mọi payload vào một tệp:

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()

Đặt nó sau HTTPS bằng Cloudflare Tunnel, Tailscale Funnel hoặc reverse proxy. Nếu bạn muốn một cơ sở dữ liệu truy vấn được hơn là một thư mục đầy tệp, bản sao tự lưu trữ của Marrow chính là bên nhận đã viết sẵn đó, và các agent AI cũng truy vấn được nó.

Ba quy tắc cho bên nhận không bao giờ mất dữ liệu

Khi nào nó chạy?

Bất cứ khi nào iOS cho phép Marrow chạy: sau khi nó đồng bộ với Apple Health, khi bạn mở nó, và trong lúc làm mới nền, một khi khoảng thời gian bạn chọn đã trôi qua. iOS quyết định khi nào việc làm mới nền diễn ra, nên một chiếc điện thoại khóa cả ngày sẽ gửi khi được mở khóa lần tiếp theo, và Kể từ lần chạy trước bù lại khoảng trống đó.

Những cách khác