跳到主要内容

外部API和程序

当您需要使用简单的外部程序、脚本、本地服务器或后端服务来控制您当前的 Chastify 锁时,请使用此页面。

最简单的方法是创建一个用户范围的 DEV 令牌,然后将其作为持有者令牌发送到 /api/apps/v1/* 端点。

/api/apps/v1/* 仅供您自己的活动锁定会话使用。如果您正在构建一个供其他 Chastify 用户使用的公共扩展程序,请使用应用范围的开发者 API 密钥,并将 /api/extensions/sessions/:sessionId/* 和 iframe mainToken 传递给 x-chastify-main-token

创建 DEV 令牌

  1. 打开 Chastify。
  2. 前往 Developer API
  3. 找到 User-wide DEV API keys
  4. 创建密钥。
  5. 立即复制令牌。它只显示一次。

在类似这样的请求中使用它:

curl https://chastify.net/api/apps/v1/session \
-H "Authorization: Bearer YOUR_DEV_TOKEN"

DEV 代币:

  • 无需创建扩展程序
  • 不会自动过期
  • 适用于您当前和未来的活动锁定会话
  • 使用您在活动锁上的角色,无论是佩戴者还是钥匙持有者。
  • 可以从开发者 API 页面撤销授权。

请将 DEV 令牌视为密码。任何拥有此令牌的人都可以像您一样调用开发者 API。

首先:检查当前锁

首先:

GET https://chastify.net/api/apps/v1/session

例子:

curl https://chastify.net/api/apps/v1/session \
-H "Authorization: Bearer YOUR_DEV_TOKEN"

这将返回您当前的锁定上下文、角色、范围、剩余时间和 lockData

锁定数据助手

GET /api/apps/v1/session 包含 lockData,其设计旨在方便程序和规则引擎读取。

常用布尔值:

  • frozen
  • unlockable
  • trusted
  • taskAssigned:当活动锁打开时,trueTaskRun

常用数字:

  • timeLockedSeconds
  • timeRemainingSeconds
  • maxTimeRemainingSeconds
  • taskPoints

常用字符串:

  • lockTitle
  • 佩戴者个人资料字段
  • 关键持有人资料字段

隐私声明:

  • 当该用户禁用在线状态时,wearerLastSeenTimestampkeyholderLastSeenTimestamp 变为 null

主锁动作端点

这些端点是大多数外部程序用来修改锁的端点。

POST https://chastify.net/api/apps/v1/action
POST https://chastify.net/api/apps/v1/lock/apply-time
POST https://chastify.net/api/apps/v1/lock/freeze
POST https://chastify.net/api/apps/v1/lock/unfreeze
POST https://chastify.net/api/apps/v1/logs/custom

所有请求均使用:

Authorization: Bearer YOUR_DEV_TOKEN
Content-Type: application/json

添加或删除时间

如果您只想更改剩余时间,请使用简单的时间端点。

加10分钟:

curl -X POST https://chastify.net/api/apps/v1/lock/apply-time \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"deltaSeconds":600}'

减去 5 分钟:

curl -X POST https://chastify.net/api/apps/v1/lock/apply-time \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"deltaSeconds":-300}'

冷冻和解冻

冷冻30分钟:

curl -X POST https://chastify.net/api/apps/v1/lock/freeze \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"durationSeconds":1800}'

解冻:

curl -X POST https://chastify.net/api/apps/v1/lock/unfreeze \
-H "Authorization: Bearer YOUR_DEV_TOKEN"

一般行动终点

使用:

POST https://chastify.net/api/apps/v1/action

体型:

{
"name": "add_time",
"params": 600
}

例子:

curl -X POST https://chastify.net/api/apps/v1/action \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"add_time","params":600}'

支持的操作名称

name 支持:

  • add_time
  • remove_time
  • freeze
  • pillory
  • unfreeze
  • toggle_freeze
  • settings.patch
  • task.assign
  • task.start_timer
  • task.complete
  • hygienic_unlock.start
  • pillory.end

行动限制:

  • 执行任务操作需要在该锁上启用“任务”模块。
  • hygienic_unlock.start 需要启用卫生开启功能,且没有活动的卫生会话。
  • 设备命令需要已连接的受支持设备和相应的权限。

实用行动示例

减少 15 分钟:

{
"name": "remove_time",
"params": 900
}

冷冻5分钟:

{
"name": "freeze",
"params": {
"durationSeconds": 300
}
}

切换冻结模式:

{
"name": "toggle_freeze",
"params": {
"durationSeconds": 300
}
}

分配任务:

{
"name": "task.assign",
"params": {
"actor": "extension",
"taskText": "Drink water",
"points": 5,
"verificationRequired": false,
"durationSeconds": 900
}
}

这将为活动锁创建一个 TaskRun。如果另一个任务运行已经打开,则当前实现会取消旧的打开的运行并创建一个新的运行。

启动活动任务计时器:

{
"name": "task.start_timer",
"params": {}
}

完成当前任务:

{
"name": "task.complete",
"params": {
"successful": true
}
}

至此,针对当前活动锁的最新开放 TaskRun 已完成。

开始卫生解锁:

{
"name": "hygienic_unlock.start",
"params": {
"durationSeconds": 900
}
}

结束公开示众:

{
"name": "pillory.end",
"params": {}
}

自定义锁定日志

当你的程序执行了某些操作,并且你希望该操作在锁定历史记录中可见时,请使用此选项。

POST https://chastify.net/api/apps/v1/logs/custom

例子:

curl -X POST https://chastify.net/api/apps/v1/logs/custom \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"title":"Program check completed","description":"The external rule script ran successfully.","role":"extension"}'

身体字段:

  • title:必填
  • description:可选
  • roleextensionwearerkeyholder
  • icon:可选
  • color:可选的十六进制颜色代码,例如 #ffcc00

设备命令

设备命令可让您触发佩戴者连接的设备的震动和振动。

POST https://chastify.net/api/apps/v1/device-command

可与您的 DEV 令牌配合使用——无需会话 ID。服务器会自动根据您的令牌解析锁和佩戴者信息。

curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.start","params":{"intensityPct":75,"durationSeconds":10}}'

请求体

{
"command": "<command>",
"params": { ... }
}
  • command(字符串,必需)— 要执行的设备命令。
  • params(对象,可选)— 命令特定参数(见下文)。

支持的命令及其参数

shock.start

对佩戴者的设备启动电击。

参数类型范围默认值描述
intensityPct数字1–10050Shock 强度百分比
durationSeconds数字1–30060Shock 持续时间(秒)
message字符串向佩戴者显示的可选消息
备注

无论您发送什么信号,佩戴者配置的最大电压始终作为硬性上限强制执行。对于 Lockink 设备,这是每个设备的电压限制。对于 QIUI 设备,这是 shockVolt 设置(1-4 刻度)。如果您发送 intensityPct: 80,但佩戴者的限制为 50%,则设备只会输出 50% 的电压。

例子:

curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.start","params":{"intensityPct":75,"durationSeconds":10,"message":"Extension shock"}}'

shock.stop

停止佩戴者设备上的所有电击。无需任何参数。

curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.stop"}'

vibration.start

启动佩戴者设备的振动。

参数类型范围默认值描述
intensityPct数字1–10050振动强度百分比
durationSeconds数字1–30030振动持续时间(秒)
frequencyPct数字1–10050振动频率(百分比)
message字符串向佩戴者显示的可选消息

例子:

curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"vibration.start","params":{"intensityPct":60,"durationSeconds":15,"frequencyPct":40}}'

vibration.stop

停止所有振动。无需任何参数。

curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"vibration.stop"}'

all.stop

停止设备的所有活动(震动、振动等)。无需任何参数。

curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"all.stop"}'

shock.random.set

启用或禁用佩戴者设备上的随机震动模式。

参数类型范围默认值描述
enabled布尔值启用 (true) 或禁用 (false) 随机模式
minIntensityPct数字1–10020最小冲击强度百分比
maxIntensityPct数字1–10080最大冲击强度百分比
message字符串向佩戴者显示的可选消息
备注

佩戴者配置的最大电压始终是硬性上限。如果您设置了 maxIntensityPct: 80,但佩戴者的限制为 50,则实际最大值将为 50%。

例子:

curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.random.set","params":{"enabled":true,"minIntensityPct":25,"maxIntensityPct":75}}'

shock.berserk.set

启用或禁用佩戴者设备上的狂暴冲击模式。

参数类型范围默认值描述
enabled布尔值启用 (true) 或禁用 (false) 狂暴模式
message字符串向佩戴者显示的可选消息

例子:

curl -X POST https://chastify.net/api/apps/v1/device-command \
-H "Authorization: Bearer YOUR_DEV_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"shock.berserk.set","params":{"enabled":true}}'

设备命令取决于活动锁、设备可用性和命令策略。

设备选择

您无需指定设备 ID 或设备类型。每位佩戴者一次只能激活一个设备——服务器会自动选择。

响应中会返回 deviceType,以便您知道哪个设备收到了命令。

回复

成功(200)

{
"ok": true,
"command": "shock.start",
"result": {
"success": true,
"message": "Shock command sent (10s)",
"deviceType": "lockink-aa-a1012"
},
"active": {
"shock": true,
"vibration": false
}
}
字段描述
oktrue 当命令被接受时
command执行的命令
result.successtrue 如果设备确认命令
result.message人类可读的状态信息
result.deviceType佩戴者的设备类型(例如 lockink-aa-a1012cellmate-pro-3
active.shock佩戴者设备上当前是否启用电击功能
active.vibration佩戴者设备当前是否启用振动功能

注意: shock.startvibration.start 最多需要等待 25 秒才能收到设备确认。停止命令(shock.stopvibration.stopall.stop)会立即返回。

失败

所有失败均返回 HTTP 4xx/5xx 错误,并附带 JSON 响应体:

{
"success": false,
"error": "no_device",
"message": "No shock-capable device found for user"
}
场景HTTPerrormessage
未找到锁或无活动锁404lock_not_foundNo active lock found
锁定已解除409lock_endedThe lock is no longer active
佩戴者会话缺失400no_wearerMissing wearer session
缺少或无效的 durationSeconds400invalid_paramsdurationSeconds is required for server-initiated shocks
在不支持的设备上启用随机/狂暴模式400unsupported_deviceRandom mode only supported on Lockink AA-A1012
用户未授予电击同意403not_authorizedUser not eligible for shock commands (consent or device check failed)
未配对支持震动/振动功能的设备404no_deviceNo shock-capable device found for user
设备离线(无套接字连接)404device_offlineNo active device socket found for user
设备未及时确认(25秒)504device_timeoutDevice verification timeout
未识别或未处理的故障400400 ZXQ代码0ZXQZXQ代码1ZXQ

如果可用,则响应中包含 deviceType

常见故障场景详解

警告

设备必须通过移动应用程序连接。

Shock 的振动功能需要佩戴者配对支持的蓝牙设备,并且手机上必须运行 Chastify 移动应用程序。该应用程序会维护实时套接字连接,并将命令传递给设备。如果应用程序关闭或手机没有连接到互联网,则命令将无法执行。

no_device — 用户尚未在 Chastify 应用中配对具备震动功能的设备(例如 CellMate Pro 3、Cagink Metal、Lockink AA-A1012)。设备必须先完成配对、激活和配置,API 才能对其进行识别。

device_offline — 佩戴者的设备已配对,但原生 Shock 服务未启用或未在 Android 应用中运行。这是最常见的故障——佩戴者必须在 Android 应用的设置中启用原生 Shock 服务,才能可靠地接收命令。

device_timeout — 命令已发送至移动应用,但应用未在 25 秒内确认蓝牙设备已收到该命令。这通常意味着佩戴者的蓝牙已关闭、设备超出范围或设备已关机。除非启用保持连接功能,否则 Lockink 设备在闲置 3 分钟后会自动进入睡眠状态——即使启用了保持连接功能,手机的 OEM 电池优化也可能限制后台蓝牙活动,从而导致保持连接功能无法可靠运行。

not_authorized — 佩戴者未在其设备设置中明确授予电击功能。这是一项安全要求——即使设备已配对,佩戴者也必须选择启用远程电击/振动指令。

unsupported_device — 随机模式和狂暴模式仅适用于 Lockink AA-A1012 (Beesting)。其他设备,例如 CellMate Pro 3 或 Cagink Metal,不支持这些模式。

常见错误

  • 401 missing_token:发送 Authorization: Bearer YOUR_DEV_TOKEN
  • 401 invalid_token:令牌错误或复制不正确。
  • 401 revoked_token:DEV 密钥已被撤销。
  • 403 insufficient_scope:密钥不具备所需的作用域。
  • 409 no_active_lock_session:用户当前没有活动的锁。
  • 409 lock_ended:已解析的锁不再处于活动状态。
信息

了解 device_timeout (504)

device_timeout 错误表示服务器已将电击指令发送到佩戴者的 Android 应用,但该应用未在 25 秒内确认已将指令发送到蓝牙设备。这是最复杂的错误——以下是 Android 端发生的情况:

  1. 服务器 → 应用程序:命令通过 Socket.IO 传递到佩戴者手机上运行的 Native Shock 服务。
  2. 应用→设备:应用通过低功耗蓝牙 (BLE) 连接到设备并发送电击指令。对于 QIUI 设备,这需要先从设备制造商的 API 获取令牌,然后写入 BLE 指令。对于 Lockink 设备,则直接发送 BLE 指令。
  3. 应用→服务器:应用向服务器发送确认信息。

25 秒超时从步骤 1 开始计算。步骤 2 超时可能是由于以下原因造成的:

  • 蓝牙已关闭 或设备超出佩戴者手机的信号范围。
  • 设备已进入睡眠状态。 Lockink 设备在 BLE 连接闲置 3 分钟后即进入深度睡眠状态。虽然保持连接功能可以防止这种情况发生,但 OEM 厂商(例如三星、小米、华为等)的电池优化可能会终止后台蓝牙连接,导致保持连接功能不稳定。
  • BLE 连接失败。 该应用程序会重试 BLE 连接,但如果设备没有响应,则会超时。
  • 安全防护机制。 该应用程序内置安全系统,可根据活动识别和 GPS 速度,在检测到佩戴者处于移动状态(例如驾驶、骑行)时,自动屏蔽震动。如果佩戴者处于运动状态,震动将被静默屏蔽并报告为失败。
  • QIUI 令牌获取失败。 对于 CellMate Pro 3 和 Cagink 设备,应用程序必须先从 QIUI 的云 API 获取命令令牌,然后才能发送 BLE 命令。如果佩戴者的手机没有网络连接,或者 QIUI 的 API 响应缓慢/无法访问,则此步骤可能会占用 25 秒窗口的大部分时间。

实用模式

大多数外部程序都遵循以下流程:

  1. 拨打 GET /api/apps/v1/session
  2. 读取 lockData
  3. 决定接下来该怎么做。
  4. 调用 /api/apps/v1/action 或更简单的锁定端点之一。
  5. (可选)写入自定义日志,使用 /api/apps/v1/logs/custom

例如,脚本可以检查 timeRemainingSeconds,在规则失败时添加时间,然后编写自定义日志解释发生了什么。