APPLE 健康 → 你的服务器

把睡眠记录
留在自己的数据库里。

使用 iPhone 自带「快捷指令」读取睡眠样本,直接上传到此服务器。其他应用使用独立的只读密钥访问数据。此页面不加载第三方脚本、字体或统计工具。

1. 在家中网络创建密钥

将手机连到家中 Wi-Fi,打开内网管理页,选择「手机上传」,名称可填「我的 iPhone」。设备标识保留 iphone-main,以后轮换同一手机密钥时保持一致。复制页面上只显示一次的密钥。

内网管理页只对家庭局域网开放;外部应用要单独创建「应用只读」密钥。上传密钥不能读取记录,只读密钥不能上传。密钥放在自己的手机或应用服务器中,不要分享带密钥的快捷指令。

2. 新建「同步睡眠」快捷指令

  1. 添加「查找健康样本」,类型选择「睡眠」,开始日期范围选择过去 3 天,按开始日期从早到晚排序,关闭数量限制。这样能覆盖跨夜记录及手表延迟回传的数据。若支持来源筛选,选择主要睡眠设备。
  2. 添加「重复每一项」,输入为找到的健康样本。在循环里获取每条样本的开始日期、结束日期、值(睡眠阶段)。日期用「格式化日期」设为 ISO 8601,必须保留时区偏移。
  3. 在循环内添加「字典」,包含三个键:start 接格式化的开始日期,end 接结束日期,value 接样本的实际阶段。字典应是循环里的最后一个动作,让「重复结果」成为字典列表。保留清醒和卧床样本,后续应用可自行分析。
  4. 在循环外添加「获取 URL 内容」,地址填 https://health.awtza.com/v1/sleep/import,方法选 POST。请求头添加 Authorization,内容为 Bearer 你的上传密钥(Bearer 后有一个空格)。
  5. 请求体选择 JSON,添加 timezone(文本),在温哥华填写 America/Vancouver;在中国大陆填写 Asia/Shanghai。添加 source(文本),如 Apple Watch,以后保持一致。添加 samples(数组),值选择前面的「重复结果」。不要把整个列表变成带引号的字符串。
  6. 添加「显示结果」,解锁手机后手动运行。允许读取睡眠记录及访问此域名。成功结果包含 ok: true;inserted 表示新增数量,duplicates 表示已存在的记录。首次同步后,到内网管理页刷新记录数量。

iOS 版本不同,动作中文名称可能略有差异。若「值」返回的是时长、空值或仅有「睡眠」二字,先用「快速查看」检查样本属性;服务器会拒绝未知阶段,不会猜测写入。

3. 设置每天触发

先确认手动上传成功,再进入「快捷指令 → 自动化」,选择你每天会打开的某个 App,触发条件「打开时」,执行「同步睡眠」,选「立即运行」。也可保留桌面一键运行。重复上传会去重。

手机锁屏时健康数据可能不可读,因此仅设置每天固定时刻并不能保证同步。睡眠结束后解锁手机再运行更可靠。若用定时自动化,请保留失败时手动重试的入口。

4. 让其他应用读取

在内网管理页为每个应用单独创建「应用只读」密钥。应用后端发送 Authorization: Bearer 只读密钥,访问以下接口:

地址用途
GET /v1/sleep/status记录数量与最近同步时间
GET /v1/sleep/samples分段记录,默认每页 1000 条

支持 start、end(带时区的 ISO 8601,URL 编码)、source、after_id 和 limit。时间筛选返回与指定范围相交的完整样本。用返回的 next_after_id 继续翻页;has_more 表示是否还有数据。服务器本机应用可用 http://127.0.0.1:8165,同样需要只读密钥。

数据含义

数据库保留每个阶段的起止时间、来源、设备标识和提交时区。core、deep、rem、asleep_unspecified 为睡眠;awake 为清醒,in_bed 为卧床。

统计睡眠时应排除清醒与卧床,并对重叠区间取并集,避免多个来源重复计时。每天归属需按所选时区和应用规则计算,不能直接按 UTC 日期截断。

参考:Apple 睡眠阶段支持 · 快捷指令发送 JSON