채널의 룰렛과 항목을 조회하고 만들고 고치고 지우는 API입니다. 룰렛은 채널 안에서 이름으로 구분하며, 바꾼 내용은 1초 안에 봇에 반영됩니다.
룰렛 객체
단건 조회·만들기·수정 API는 룰렛을 아래 객체로 돌려줍니다. 각 설정의 동작은 룰렛 가이드와 같습니다.
| 필드 |
타입 |
설명 |
roulette_name |
string |
룰렛 이름. 채널 안에서 룰렛을 구분하는 값이고 경로의 {roulette_name}에 씁니다. 영문 대소문자는 구분하지 않습니다 |
send_message |
boolean |
true면 당첨 결과를 채팅으로 보냅니다(결과 알리기와 TTS) |
trigger_donation_min_amount |
integer 또는 null |
룰렛 가격. 이 금액의 배수를 후원하면 그 배수만큼 돕니다. null이면 후원으로 돌지 않고, 0은 1,000으로 처리됩니다(후원으로 돌리기) |
trigger_donation_max_amount |
integer 또는 null |
최대 후원 금액. 이보다 큰 후원에는 돌지 않습니다. null이나 0이면 상한이 없습니다 |
trigger_donation_text |
string 또는 null |
후원 메시지에 이 문구가 들어 있어야 돕니다. null이면 문구 조건이 없습니다 |
trigger_donation_allow_remainder |
boolean |
true면 후원 금액이 룰렛 가격의 배수가 아니어도 금액 ÷ 가격(소수점 버림)만큼 돌고 남는 금액은 무시합니다. false면 정확한 배수일 때만 돕니다 |
max_multi_roulette_limit |
integer |
한 번에 돌릴 수 있는 최대 연차 횟수. 0이면 제한이 없습니다. 채팅 명령어 연차는 이 값과 상관없이 100회까지입니다(명령어로 돌리기) |
allowed_multi_list |
array of integer |
지정 연차 횟수(오름차순). 비어 있지 않으면 이 횟수만 허용하고 max_multi_roulette_limit은 무시합니다. 쓰지 않으면 [] |
multi_bonus_enabled |
boolean |
true면 연차 보너스를 줍니다(연차 보너스) |
multi_bonus_trigger_count |
integer |
보너스가 붙는 연차 횟수 n. n연차마다 m회가 붙습니다(20연차면 2m회) |
multi_bonus_extra_count |
integer |
보너스로 무료로 더 돌리는 횟수 m. 1~100 |
command_id |
integer 또는 null |
연결한 명령어의 id(명령어 객체). 그 명령어의 point가 한 번 돌리는 비용입니다. null이면 명령어로 돌지 않습니다 |
activate |
boolean |
false면 명령어로도 후원으로도 돌지 않습니다 |
tts_enabled |
boolean |
true면 오버레이가 당첨 항목을 소리 내어 읽습니다 |
multi_collect_enabled |
boolean |
true면 오버레이가 연차를 최대 10판씩 모아 한 번에 돌립니다(연차 모아보기) |
items |
array |
항목 목록. 배열 순서가 표시 순서입니다(항목과 확률) |
items[].data |
string |
항목 이름. 당첨되면 이 문구가 결과로 나옵니다 |
items[].weight |
number |
뽑힐 비율. 다른 항목의 weight와 비교한 비율로 뽑으므로 합이 100이 아니어도 됩니다. 정수면 정수로 옵니다 |
items[].ticket |
boolean |
당첨되면 티켓으로 쌓는 항목이면 true. 아니면 이 키가 없습니다(티켓·카운터와 연결하기) |
목록 조회의 각 룰렛에는 아래 세 필드가 더 있습니다. 단건 조회·만들기·수정 응답에는 없습니다.
| 필드 |
타입 |
설명 |
streamer_uid |
string |
채널 UID |
index |
integer |
대시보드 룰렛 탭의 순서. 작을수록 앞이고 새 룰렛은 맨 뒤에 붙습니다. API로는 바꿀 수 없습니다 |
command_text |
string 또는 null |
command_id 명령어의 이름. 연결이 없거나 그 명령어가 없으면 null |
룰렛 목록 조회
채널의 룰렛을 모두 가져옵니다. 대시보드 탭 순서(index 오름차순)로 정렬되며 페이지 없이 한 번에 옵니다.
GET/api/v1/developer/roulettes권한: roulette:read
요청
요청 파라미터가 없습니다.
GET /api/v1/developer/roulettes
Authorization: Bearer ACCESS_TOKEN
응답
| 필드 |
타입 |
설명 |
[] |
array |
룰렛 배열. 각 항목은 룰렛 객체에 streamer_uid, index, command_text가 더해진 형태입니다. 룰렛이 없으면 [] |
[
{
"streamer_uid": "4f2a8c1e9b7d4e3fa6c5b0d1e2f3a4b5",
"roulette_name": "간식 룰렛",
"send_message": true,
"index": 0,
"trigger_donation_min_amount": 1000,
"trigger_donation_max_amount": null,
"trigger_donation_text": null,
"trigger_donation_allow_remainder": false,
"trigger_donation_allow_remainder": false,
"max_multi_roulette_limit": 10,
"allowed_multi_list": [],
"multi_bonus_enabled": false,
"multi_bonus_trigger_count": 10,
"multi_bonus_extra_count": 1,
"command_id": 4,
"activate": true,
"tts_enabled": false,
"multi_collect_enabled": false,
"command_text": "!룰렛",
"items": [
{"data": "꽝", "weight": 70},
{"data": "간식", "weight": 25, "ticket": true},
{"data": "음료", "weight": 5}
]
}
]
오류
| 상태 |
응답 |
원인 |
| 401, 403 |
공통 오류 |
토큰이 유효하지 않거나 roulette:read 권한이 없습니다 |
룰렛 조회
이름으로 룰렛 하나를 가져옵니다.
GET/api/v1/developer/roulettes/{roulette_name}권한: roulette:read
요청
| 이름 |
위치 |
타입 |
필수 |
설명 |
roulette_name |
path |
string |
예 |
룰렛 이름. URL 인코딩해서 넣습니다 |
GET /api/v1/developer/roulettes/%EA%B0%84%EC%8B%9D%20%EB%A3%B0%EB%A0%9B
Authorization: Bearer ACCESS_TOKEN
응답
| 필드 |
타입 |
설명 |
| (본문) |
object |
룰렛 객체 |
{
"roulette_name": "간식 룰렛",
"send_message": true,
"trigger_donation_min_amount": 1000,
"trigger_donation_max_amount": null,
"trigger_donation_text": null,
"trigger_donation_allow_remainder": false,
"max_multi_roulette_limit": 10,
"allowed_multi_list": [],
"multi_bonus_enabled": false,
"multi_bonus_trigger_count": 10,
"multi_bonus_extra_count": 1,
"command_id": 4,
"activate": true,
"tts_enabled": false,
"multi_collect_enabled": false,
"items": [
{"data": "꽝", "weight": 70},
{"data": "간식", "weight": 25, "ticket": true},
{"data": "음료", "weight": 5}
]
}
오류
| 상태 |
응답 |
원인 |
| 404 |
{"detail": "룰렛을 찾을 수 없습니다"} |
그 이름의 룰렛이 없습니다 |
| 401, 403 |
공통 오류 |
토큰이 유효하지 않거나 roulette:read 권한이 없습니다 |
룰렛 만들기
새 룰렛을 만듭니다. 새 룰렛은 탭 맨 뒤에 붙습니다.
POST/api/v1/developer/roulettes권한: roulette:write
요청
| 이름 |
위치 |
타입 |
필수 |
설명 |
roulette_name |
body |
string |
예 |
룰렛 이름. 1~30자 |
items |
body |
array |
아니요 |
항목 목록. 기본값 []. 항목 없이도 만들 수 있지만 그 상태로는 돌지 않습니다 |
items[].data |
body |
string |
예 |
항목 이름. 1~100자이고, 앞뒤 공백을 지워 저장합니다. 공백뿐인 항목은 저장하지 않습니다 |
items[].weight |
body |
number |
아니요 |
뽑힐 비율. 0 이상의 유한한 수, 기본값 1. "50"처럼 숫자로 된 문자열도 받습니다 |
items[].ticket |
body |
boolean |
아니요 |
당첨되면 티켓으로 쌓을 항목이면 true. 기본값 false |
send_message |
body |
boolean |
아니요 |
결과를 채팅으로 보낼지. 기본값 false |
activate |
body |
boolean |
아니요 |
바로 켤지. 기본값 true |
trigger_donation_min_amount |
body |
integer 또는 null |
아니요 |
룰렛 가격. 32비트 정수, 기본값 null(후원으로 돌지 않음) |
trigger_donation_max_amount |
body |
integer 또는 null |
아니요 |
최대 후원 금액. 32비트 정수, 기본값 null(상한 없음) |
trigger_donation_text |
body |
string 또는 null |
아니요 |
후원 메시지에 들어 있어야 할 문구. 100자까지. 빈 문자열은 null로 저장합니다 |
trigger_donation_allow_remainder |
body |
boolean 또는 null |
아니요 |
배수가 아닌 후원도 가능한 만큼 돌리기. 기본값 false |
command_id |
body |
integer 또는 null |
아니요 |
연결할 명령어의 id. 32비트 정수이며 있는 명령어인지는 검사하지 않습니다. 기본값 null |
max_multi_roulette_limit |
body |
integer 또는 null |
아니요 |
최대 연차 횟수. 0~2,147,483,647, 기본값 0(제한 없음) |
allowed_multi_list |
body |
array of integer 또는 null |
아니요 |
지정 연차 횟수. 1 이상인 값만 남기고 중복을 지운 뒤 오름차순으로 저장합니다. 기본값 null([]로 조회됨) |
tts_enabled |
body |
boolean 또는 null |
아니요 |
오버레이 TTS. 기본값 false |
multi_collect_enabled |
body |
boolean 또는 null |
아니요 |
연차 모아보기. 기본값 false |
multi_bonus_enabled |
body |
boolean 또는 null |
아니요 |
연차 보너스. 기본값 false |
multi_bonus_trigger_count |
body |
integer 또는 null |
아니요 |
보너스가 붙는 연차 횟수 n. 1~2,147,483,647, 기본값 10 |
multi_bonus_extra_count |
body |
integer 또는 null |
아니요 |
보너스 횟수 m. 1~100, 기본값 1 |
weight가 0인 항목은 뽑히지 않으며, 항목이 하나라도 있으면 weight 합계가 0보다 커야 합니다. 32비트 정수는 -2,147,483,648~2,147,483,647입니다. 항목 하나마다 JSON 키가 2~3개 들어가므로 항목이 수백 개면 JSON 키 1,000개 한도에 걸릴 수 있습니다.
POST /api/v1/developer/roulettes
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"roulette_name": "간식 룰렛",
"items": [
{"data": "꽝", "weight": 70},
{"data": "간식", "weight": 25, "ticket": true},
{"data": "음료", "weight": 5}
],
"send_message": true,
"command_id": 4,
"max_multi_roulette_limit": 10
}
응답
성공 상태는 201이 아니라 200입니다.
| 필드 |
타입 |
설명 |
| (본문) |
object |
만든 룰렛 객체 |
{
"roulette_name": "간식 룰렛",
"send_message": true,
"trigger_donation_min_amount": null,
"trigger_donation_max_amount": null,
"trigger_donation_text": null,
"trigger_donation_allow_remainder": false,
"max_multi_roulette_limit": 10,
"allowed_multi_list": [],
"multi_bonus_enabled": false,
"multi_bonus_trigger_count": 10,
"multi_bonus_extra_count": 1,
"command_id": 4,
"activate": true,
"tts_enabled": false,
"multi_collect_enabled": false,
"items": [
{"data": "꽝", "weight": 70},
{"data": "간식", "weight": 25, "ticket": true},
{"data": "음료", "weight": 5}
]
}
오류
| 상태 |
응답 |
원인 |
| 400 |
{"detail": "이미 존재하는 룰렛 이름입니다"} |
같은 이름의 룰렛이 있습니다. 영문 대소문자만 다른 이름도 같은 이름입니다 |
| 400 |
{"detail": "확률은 0 이상의 유한한 숫자여야 합니다."} |
weight가 음수이거나 무한대·NaN입니다 |
| 400 |
{"detail": "확률 합계는 0보다 큰 유한한 숫자여야 합니다."} |
항목이 있는데 weight 합계가 0입니다 |
| 400 |
{"detail": "룰렛을 생성하지 못했습니다. 이름이나 입력값을 확인해 주세요."} |
저장하지 못했습니다. 봇을 켠 적이 없는 채널처럼 잼쿠봇에 채널 정보가 없으면 이 오류가 납니다 |
| 422 |
{"detail": [...]} |
필수 값이 없거나 길이·타입·범위가 맞지 않습니다. 이름 30자, trigger_donation_text 100자, 정수 범위를 넘거나 data가 빈 문자열이거나 weight가 null·숫자가 아닐 때입니다 |
| 401, 403 |
공통 오류 |
토큰이 유효하지 않거나 roulette:write 권한이 없습니다 |
룰렛 수정
룰렛 하나를 고칩니다. 본문의 roulette_name은 바꾼 뒤의 이름이라 항상 보내고, 나머지는 바꿀 필드만 보냅니다.
PUT/api/v1/developer/roulettes/{roulette_name}권한: roulette:write
요청
| 이름 |
위치 |
타입 |
필수 |
설명 |
roulette_name |
path |
string |
예 |
고칠 룰렛의 지금 이름. URL 인코딩해서 넣습니다 |
roulette_name |
body |
string |
예 |
바꾼 뒤의 이름. 이름을 그대로 두려면 지금 이름을 보냅니다. 1~30자 |
items |
body |
array |
아니요 |
보내면 항목 전체를 이 목록으로 바꿉니다. []이면 항목을 모두 지웁니다. 빼면 기존 항목을 그대로 둡니다 |
send_message, activate |
body |
boolean |
아니요 |
빼면 기존 값을 유지합니다. null은 422입니다 |
trigger_donation_min_amount, trigger_donation_max_amount, trigger_donation_text, command_id |
body |
만들기와 같음 |
아니요 |
빼면 기존 값을 유지하고, null을 보내면 값을 지웁니다. command_id에 null을 보내면 명령어 연결이 풀립니다 |
max_multi_roulette_limit, allowed_multi_list, tts_enabled, multi_bonus_enabled, multi_bonus_trigger_count, multi_bonus_extra_count, multi_collect_enabled, trigger_donation_allow_remainder |
body |
만들기와 같음 |
아니요 |
빼거나 null을 보내면 기존 값을 유지합니다. 최대 연차 제한을 없애려면 0, 지정 연차를 없애려면 []를 보냅니다 |
items를 보내면 만들기와 같은 확률 검사를 다시 합니다.
주의items는 통째로 바뀝니다
항목 하나만 고칠 때도 전체 목록을 보내야 합니다. 이때 ticket을 빼면 그 항목의 티켓 표시가 꺼지니, 조회한 항목을 고쳐 보낼 때 ticket 키를 그대로 두세요.
PUT /api/v1/developer/roulettes/%EA%B0%84%EC%8B%9D%20%EB%A3%B0%EB%A0%9B
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json
{
"roulette_name": "주말 간식 룰렛",
"trigger_donation_min_amount": 2000
}
응답
| 필드 |
타입 |
설명 |
| (본문) |
object |
수정한 뒤의 룰렛 객체. 이름을 바꿨으면 새 이름으로 조회한 결과입니다 |
{
"roulette_name": "주말 간식 룰렛",
"send_message": true,
"trigger_donation_min_amount": 2000,
"trigger_donation_max_amount": null,
"trigger_donation_text": null,
"trigger_donation_allow_remainder": false,
"max_multi_roulette_limit": 10,
"allowed_multi_list": [],
"multi_bonus_enabled": false,
"multi_bonus_trigger_count": 10,
"multi_bonus_extra_count": 1,
"command_id": 4,
"activate": true,
"tts_enabled": false,
"multi_collect_enabled": false,
"items": [
{"data": "꽝", "weight": 70},
{"data": "간식", "weight": 25, "ticket": true},
{"data": "음료", "weight": 5}
]
}
오류
| 상태 |
응답 |
원인 |
| 400 |
{"detail": "이미 존재하는 룰렛 이름입니다"} |
바꾸려는 이름의 룰렛이 이미 있습니다. 영문 대소문자는 구분하지 않고 비교합니다 |
| 400 |
{"detail": "확률은 0 이상의 유한한 숫자여야 합니다."} |
보낸 items의 weight가 음수이거나 무한대·NaN입니다 |
| 400 |
{"detail": "확률 합계는 0보다 큰 유한한 숫자여야 합니다."} |
보낸 items가 있는데 weight 합계가 0입니다 |
| 400 |
{"detail": "룰렛을 수정하지 못했습니다. 입력값을 확인해 주세요."} |
저장 중 오류가 났습니다 |
| 404 |
{"detail": "룰렛을 찾을 수 없습니다"} |
경로의 이름으로 된 룰렛이 없습니다 |
| 422 |
{"detail": [...]} |
본문에 roulette_name이 없거나, items·send_message·activate에 null을 보냈거나, 길이·타입·범위가 맞지 않습니다 |
| 401, 403 |
공통 오류 |
토큰이 유효하지 않거나 roulette:write 권한이 없습니다 |
룰렛 삭제
룰렛 하나를 지웁니다. 지운 룰렛은 되돌릴 수 없지만 그동안의 실행 기록은 룰렛 내역에 남습니다.
DELETE/api/v1/developer/roulettes/{roulette_name}권한: roulette:write
요청
| 이름 |
위치 |
타입 |
필수 |
설명 |
roulette_name |
path |
string |
예 |
지울 룰렛의 이름. URL 인코딩해서 넣습니다 |
DELETE /api/v1/developer/roulettes/%EA%B0%84%EC%8B%9D%20%EB%A3%B0%EB%A0%9B
Authorization: Bearer ACCESS_TOKEN
응답
| 필드 |
타입 |
설명 |
ok |
boolean |
항상 true |
{"ok": true}
오류
| 상태 |
응답 |
원인 |
| 404 |
{"detail": "룰렛을 찾을 수 없습니다"} |
그 이름의 룰렛이 없습니다 |
| 401, 403 |
공통 오류 |
토큰이 유효하지 않거나 roulette:write 권한이 없습니다 |