외부 API 및 프로그램
이 페이지는 간단한 외부 프로그램, 스크립트, 로컬 서버 또는 백엔드 서비스를 사용하여 현재 Chastify 잠금 장치를 제어하려는 경우에 사용하십시오.
가장 쉬운 방법은 사용자 전체에 적용되는 DEV 토큰을 생성한 다음, 해당 토큰을 베어러 토큰으로 /api/apps/v1/* 엔드포인트로 전송하는 것입니다.
/api/apps/v1/*는 본인의 활성 잠금 세션에만 사용됩니다. 다른 Chastify 사용자가 사용하는 공개 확장 프로그램을 개발하는 경우, 앱 범위의 개발자 API 키인 /api/extensions/sessions/:sessionId/*를 사용하고 iframe인 mainToken를 x-chastify-main-token에 전달하십시오.
DEV 토큰을 생성하세요
- Chastify를 엽니다.
Developer API로 이동하세요.User-wide DEV API keys를 찾으세요.- 키를 생성하세요.
- 토큰을 즉시 복사하세요. 토큰은 한 번만 표시됩니다.
다음과 같은 요청에 사용하세요:
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가 포함되어 있습니다.
일반적인 부울 값:
frozenunlockabletrustedtaskAssigned: 활성 잠금 장치에 열린TaskRun가 있을 때true
일반적인 숫자:
timeLockedSecondstimeRemainingSecondsmaxTimeRemainingSecondstaskPoints
일반적인 문자열:
lockTitle- 착용자 프로필 필드
- 열쇠 소지자 프로필 필드
개인정보 보호 고지:
- 사용자가 온라인 상태를 비활성화한 경우
wearerLastSeenTimestamp및keyholderLastSeenTimestamp는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_timeremove_timefreezepilloryunfreezetoggle_freezesettings.patchtask.assigntask.start_timertask.completehygienic_unlock.startpillory.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: 선택 사항role:extension,wearer또는keyholdericon: 선택 사항color: 선택 사항인 16진수 색상 코드(예:#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–100 | 50 | Shock 강도(백분율) |
durationSeconds | 숫자 | 1–300 | 60 | Shock 지속 시간(초) |
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–100 | 50 | 진동 강도(백분율) |
durationSeconds | 숫자 | 1–300 | 30 | 진동 지속 시간(초) |
frequencyPct | 숫자 | 1–100 | 50 | 진동 주파수(백분율) |
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–100 | 20 | 최소 충격 강도 백분율 |
maxIntensityPct | 숫자 | 1–100 | 80 | 최대 충격 강도 백분율 |
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
}
}
| 분야 | 설명 |
|---|---|
ok | true 명령이 수락되었을 때 |
command | 실행된 명령 |
result.success | 장치가 명령을 확인하면 true |
result.message | 사람이 읽을 수 있는 상태 메시지 |
result.deviceType | 착용자의 기기 유형 (예: lockink-aa-a1012, cellmate-pro-3) |
active.shock | 착용자의 기기에서 현재 충격이 활성화되어 있는지 여부 |
active.vibration | 착용자의 기기에서 현재 진동이 활성화되어 있는지 여부 |
참고: shock.start 및 vibration.start는 기기에서 수신 확인을 위해 최대 25초 동안 대기합니다. 정지 명령(shock.stop, vibration.stop, all.stop)은 즉시 반환됩니다.
실패
모든 오류는 JSON 본문과 함께 HTTP 4xx/5xx 오류를 반환합니다.
{
"success": false,
"error": "no_device",
"message": "No shock-capable device found for user"
}
| 시나리오 | HTTP | error | message |
|---|---|---|---|
| 잠금 장치를 찾을 수 없거나 활성화된 잠금 장치가 없습니다 | 404 | lock_not_found | No active lock found |
| 잠금이 더 이상 활성화되어 있지 않습니다 | 409 | lock_ended | The lock is no longer active |
| 착용자 누락 세션 | 400 | no_wearer | Missing wearer session |
durationSeconds가 누락되었거나 유효하지 않습니다 | 400 | invalid_params | durationSeconds is required for server-initiated shocks |
| 지원되지 않는 기기에서의 무작위/광폭 모드 | 400 | unsupported_device | Random mode only supported on Lockink AA-A1012 |
| 사용자가 충격 동의를 하지 않았습니다 | 403 | not_authorized | User not eligible for shock commands (consent or device check failed) |
| 충격/진동 감지 장치가 페어링되지 않았습니다 | 404 | no_device | No shock-capable device found for user |
| 장치가 오프라인 상태입니다(소켓 연결 없음) | 404 | device_offline | No active device socket found for user |
| 장치가 제때 확인하지 못했습니다(25초) | 504 | device_timeout | Device verification timeout |
| 인식되지 않거나 처리되지 않은 오류 | 400 | command_failed | command_failed |
가능한 경우 deviceType가 응답에 포함됩니다.
일반적인 오류 시나리오 설명
기기는 모바일 앱을 통해 연결되어야 합니다.
Shock의 진동 기능을 사용하려면 착용자가 지원되는 블루투스 장치와 페어링되어 있어야 하고, 휴대전화에 Chastify 모바일 앱이 실행 중이어야 합니다. 이 앱은 장치에 명령을 전달하는 실시간 소켓 연결을 유지합니다. 앱이 닫혀 있거나 휴대전화에 인터넷 연결이 없으면 명령이 실패합니다.
no_device — 착용자가 Chastify 앱에서 전기 충격 기능이 있는 기기(예: CellMate Pro 3, Cagink Metal, Lockink AA-A1012)를 페어링하지 않았습니다. API에서 기기를 대상으로 지정하려면 기기가 페어링되고 활성화되어 완전히 구성되어 있어야 합니다.
device_offline — 착용자의 기기는 페어링되었지만, Android 앱에서 네이티브 Shock 서비스가 활성화되어 있지 않거나 실행 중이 아닙니다. 이는 가장 흔한 오류이며, 명령을 안정적으로 전달받으려면 착용자가 Android 앱 설정에서 네이티브 Shock 서비스를 활성화해야 합니다.
device_timeout — 모바일 앱으로 명령이 전송되었지만, 앱에서 25초 이내에 블루투스 기기가 명령을 수신했음을 확인하지 못했습니다. 이는 일반적으로 착용자의 블루투스가 꺼져 있거나, 기기가 블루투스 범위 밖에 있거나, 기기가 꺼져 있음을 의미합니다. Lockink 기기는 연결 유지 기능이 활성화되지 않은 경우 3분 동안 활동이 없으면 절전 모드로 전환됩니다. 또한, 연결 유지 기능이 활성화된 경우에도 휴대폰의 배터리 최적화 설정으로 인해 백그라운드 블루투스가 제한되어 연결 유지 기능이 안정적으로 작동하지 않을 수 있습니다.
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 측에서 발생하는 상황은 다음과 같습니다.
- 서버 → 앱: 명령은 Socket.IO를 통해 사용자의 휴대폰에서 실행 중인 네이티브 Shock 서비스로 전달됩니다.
- 앱 → 기기: 앱은 블루투스 저에너지(BLE)를 통해 기기에 연결하고 전기 충격 명령을 전송합니다. QIUI 기기의 경우, 먼저 기기 제조업체의 API에서 토큰을 가져온 후 BLE 명령을 작성해야 합니다. Lockink 기기의 경우, BLE 명령이 직접 전송됩니다.
- 앱 → 서버: 앱이 서버로 확인 응답을 보냅니다.
25초 타임아웃은 1단계부터 시작됩니다. 2단계에서 타임아웃이 발생하는 이유는 다음과 같습니다.
- 블루투스가 꺼져 있거나 기기가 착용자의 휴대폰에서 블루투스 연결 범위를 벗어났습니다.
- 케이지가 절전 모드에 들어갑니다. Lockink 장치는 BLE 활동이 3분 동안 없으면 절전 모드로 전환됩니다. 연결 유지 기능이 이를 방지할 수 있지만, 제조사(삼성, 샤오미, 화웨이 등)의 배터리 최적화 정책으로 인해 백그라운드 블루투스 연결이 종료될 수 있으며, 이로 인해 연결 유지 기능이 제대로 작동하지 않을 수 있습니다.
- BLE 연결에 실패했습니다. 앱은 BLE 연결을 다시 시도하지만, 기기가 응답하지 않으면 시간 초과됩니다.
- 안전 차단 기능. 이 앱에는 착용자가 활동 감지 및 GPS 속도 기반으로 움직이는 경우(예: 운전, 자전거 타기) 전기 충격을 차단하는 안전 시스템이 내장되어 있습니다. 착용자가 움직이는 동안에는 전기 충격이 조용히 차단되고 실패로 보고됩니다.
- QIUI 토큰 가져오기 실패. CellMate Pro 3 및 Cagink 기기의 경우, 앱은 BLE 명령을 전송하기 전에 QIUI의 클라우드 API에서 명령 토큰을 가져와야 합니다. 착용자의 휴대폰에 인터넷 연결이 없거나 QIUI의 API 속도가 느리거나 연결할 수 없는 경우, 이 단계에서 25초 중 대부분의 시간이 소요될 수 있습니다.
실용적인 패턴
대부분의 외부 프로그램은 다음과 같은 흐름을 따릅니다.
GET /api/apps/v1/session로 전화하세요.lockData를 읽으세요.- 무슨 일이 일어나야 할지 결정하세요.
/api/apps/v1/action또는 더 간단한 잠금 엔드포인트 중 하나를 호출하십시오.- 선택적으로
/api/apps/v1/logs/custom를 사용하여 사용자 지정 로그를 작성할 수 있습니다.
예를 들어 스크립트는 timeRemainingSeconds를 확인하고, 규칙이 실패했을 때 시간을 추가한 다음, 발생한 상황을 설명하는 사용자 지정 로그를 작성할 수 있습니다.