Rich Presence
활동은 누군가가 지금 하고 있는 일입니다. 예를 들어 Tibia 플레이 중이고, 그 아래에 Roshamuul에서 사냥 중, 레벨 412 엘리트 나이트, 이미지와 타이머가 표시됩니다. GameVox는 Discord의 활동 객체와 Discord의 설정 방식을 사용하므로, Discord Rich Presence용으로 작성한 코드는 대부분 그대로 동작합니다. 어떤 이름을 표시할지는 GameVox가 정하고, 나머지는 모두 GameVox가 검사합니다.
개요
들어오는 길은 네 가지, 나가는 길은 하나입니다.
- 봇 자신의 상태: Identify의
presence와 게이트웨이 opcode 3. Discord와 똑같습니다. - 여러분의 서버(백엔드)에서 설정하는 사용자의 활동: 봇 토큰을 사용하는 REST 호출로, 앱을 허용한 사용자(
activities.write스코프)가 대상입니다. 이 기능을 쓰려면 GameVox의 앱 승인이 필요합니다. - 사용자 컴퓨터의 프로그램이 설정하는 사용자의 활동: 데스크톱 앱의 로컬 RPC로, Discord RPC IPC 프로토콜을 사용합니다.
- GameVox 자체의 게임 감지. 직접 제어할 수는 없지만 여러분의 활동과 병합될 수 있습니다.
- 나가는 길:
GUILD_PRESENCES인텐트를 가진 봇은 멤버의 상태나 활동이 바뀌면PRESENCE_UPDATE를 받습니다.
표시되는 곳: 서버 멤버 목록의 이름 아래, 프로필 카드(이미지, 세부 정보, 상태, 파티, 타이머, 버튼), DM 헤더, 친구 목록. 데스크톱, 웹, iOS, Android 모두에서 표시됩니다.
표시되는 내용
한 사람(또는 봇)에게는 최대 사용자 지정 상태(유형 4) 하나와 다른 활동 하나가 표시됩니다. 여러 소스가 동시에 무언가를 알리면 로컬 RPC가 앱보다, 앱이 봇 자신의 활동보다, 그리고 이들 모두가 감지된 게임보다 우선합니다. GameVox가 감지한 것과 같은 게임의 활동은 감지 결과와 병합됩니다. 세부 정보, 상태, 이미지는 여러분의 것을 쓰고, 게임 이름과 (여러분이 보내지 않았다면) 시작 시각은 GameVox의 것을 씁니다. 다른 대상의 활동은 감지된 게임을 대체합니다. 사람은 아직 사용자 지정 상태를 설정할 수 없지만, 봇은 설정할 수 있습니다.
활동 객체
필드는 Discord의 것입니다. 보낼 수 있는 내용은 보내는 쪽에 따라 다릅니다(각 섹션 참고). 모든 내용은 정리됩니다. 제어 문자와 방향 재정의 문자는 제거되고, 줄바꿈은 공백이 되며, 연속된 공백은 하나로 합쳐지고, 텍스트는 아래 제한에 맞춰 잘립니다.
| 필드 | 참고 |
|---|---|
name | 최대 128자. 봇은 자신의 이름을 직접 정합니다. 사용자의 활동에서는 GameVox가 이름을 정하고 여러분이 보낸 이름은 무시합니다(“이름” 참고). |
type | 유형 표를 참고하세요. 허용되는 유형은 소스에 따라 다릅니다. |
url | 스트리밍 전용이며, twitch.tv 또는 youtube.com의 https 링크만 됩니다. |
timestamps | 밀리초 또는 초 단위의 Unix 시간(1011 미만의 값은 초로 읽습니다). start는 증가하고, end는 감소합니다. 2000년 이전이거나, start가 하루 넘게 미래이거나, end가 start보다 앞서면 거부됩니다. |
details, state | 각각 최대 128자. 카드의 첫째 줄과 둘째 줄입니다. |
status_display_type | 1은 한 줄 형식에서 이름 대신 상태를 보여 주고(“레벨 412 엘리트 나이트 플레이 중”), 2는 세부 정보를 보여 줍니다. 0이거나 없으면 이름을 보여 줍니다. |
emoji | 사용자 지정 상태 전용: Unicode 이모지(이름, 최대 32자). 사용자 지정 이모지 ID는 버려집니다. |
party | id는 최대 128자, size는 [current, max]이며 0 ≤ current ≤ max ≤ 10000입니다. “5명 중 2명”처럼 표시됩니다. 크기가 잘못되면 크기만 버려집니다. |
assets | Rich Presence 탭에서 여러분의 애플리케이션에 업로드한 이미지의 키(a-z 0-9 _ - 1~32자)와 최대 128자의 마우스오버 텍스트입니다. URL과 mp: 값은 버려집니다. “이미지”를 참고하세요. |
buttons | 최대 2개이며, 각각 {label, url}입니다. 라벨은 최대 32자, https URL은 최대 512자. 승인된 앱과 퍼스트파티 앱만 가능합니다. 멤버는 GameVox의 외부 링크 경고를 거쳐 버튼을 엽니다. 자신의 카드에 있는 버튼은 아무도 보지 못합니다. |
정리된 후의 활동 전체가 JSON으로 4096바이트 안에 들어가야 합니다. 링크(url, 버튼 URL, details_url, state_url)는 https여야 하고, 공개 호스트 이름을 사용해야 하며, 사용자 이름, IP 주소, 포트를 포함할 수 없습니다. application_id, flags, instance, secrets, sync_id, 그 밖에 보낸 모든 것은 대체되거나 버려집니다.
활동 유형
| 유형 | 표시 |
|---|---|
0 | {name} 플레이 중 |
1 | {details or name} 스트리밍 중 |
2 | {name} 듣는 중 |
3 | {name} 시청 중 |
4 | {emoji} {state} |
5 | {name}에서 경쟁 중 |
한 줄 형식은 GameVox가 보는 사람의 언어로 번역합니다. 여러분의 텍스트는 번역되지 않습니다.
봇의 상태
Discord 방식으로 설정합니다. Identify(opcode 2)의 presence 필드와, 바뀔 때마다 게이트웨이 opcode 3(Presence Update)을 사용합니다. discord.js의 client.user.setPresence(), discord.py의 change_presence() 같은 것은 그대로 동작합니다.
{
"op": 2,
"d": {
"token": "<bot token>",
"intents": 513,
"properties": { "os": "linux", "browser": "my-bot", "device": "my-bot" },
"presence": {
"since": null,
"activities": [ { "name": "12 Tibia worlds", "type": 3 } ],
"status": "online",
"afk": false
}
}
} {
"op": 3,
"d": {
"since": null,
"activities": [ { "name": "Custom Status", "type": 4, "state": "/help for commands" } ],
"status": "dnd",
"afk": false
}
}
// discord.js
client.user.setPresence({
activities: [{ name: 'raid signups', type: ActivityType.Watching }],
status: 'idle',
});
# discord.py
await client.change_presence(activity=discord.Game(name="VALORANT"), status=discord.Status.online) GameVox가 사용하는 것
status:online,idle,dnd,invisible,offline중 하나. 자리 비움과 방해 금지는 봇의 상태 점을 바꿉니다. 보이지 않음과 오프라인은 봇을 활동 없는 오프라인으로 표시하지만, 봇은 연결을 유지한 채 계속 동작합니다. 상태가 없으면 온라인으로 간주하며, 그 밖의 값이면 업데이트 전체가 무시됩니다.activities: 활동마다name,type,state,url(스트리밍), 이모지 이름(사용자 지정)만 사용합니다. 나머지는 모두 버려집니다. 목록은 사용자 지정 상태 하나와 다른 활동 하나로 줄어듭니다.- 사용자 지정 상태(유형 4)에는
state또는 이모지가 필요합니다. 이름은 무엇이든 됩니다(Discord는 “Custom Status”를 보냅니다). since와afk는 받아들이지만 무시합니다.presence가 없는 Identify는 봇을 일반 온라인 상태로 되돌립니다. Resume은 봇이 가지고 있던 상태를 유지합니다.
제한
- Opcode 3은 연결당 20초에 5회로 제한됩니다. 제한을 넘으면 GameVox는 가장 최근 업데이트를 보관했다가 허용되는 시점에 적용합니다. 이 때문에 연결이 끊기는 일은 없습니다.
- 클라이언트를 열어 둔 구성원은 30초 안에 변경을 봅니다. GameVox는 봇마다 30초에 최대 한 번만 업데이트를 보내기 때문입니다. 나중에 연 구성원 목록에는 현재 상태가 표시됩니다.
- 같은 프레즌스를 다시 보내도 아무것도 바뀌지 않습니다.
상태는 구성원 목록의 봇 이름 아래와 봇의 프로필에 표시되며, 봇이 들어가 있는 모든 서버(셀프 호스팅 서버 포함)의 구성원에게 보입니다. 다른 봇은 이를 받지 않습니다.
앱에서 사용자의 활동 설정하기
여러분의 서버는 사용자 컴퓨터에서 아무것도 실행하지 않고도, 예를 들어 게임 서버 자체의 데이터를 바탕으로 사용자가 여러분의 게임에서 무엇을 하고 있는지 보여 줄 수 있습니다. 이는 GameVox 확장 기능이며, Discord에는 이런 엔드포인트가 없습니다.
필요한 것
- 승인. GameVox는 이 기능을 쓸 앱을 직접 검토해 승인합니다. 승인되기 전까지 모든 PUT은 코드 50001과 함께 403을 반환합니다. GameVox 지원팀에 문의하세요. GameVox의 퍼스트파티 앱은 이미 승인되어 있습니다.
- 사용자의 동의. 사용자는 일반적인 OAuth2 동의 화면(GameVox로 로그인)에서
activities.write스코프로 여러분의 앱을 승인합니다. 사용자는 설정에서 언제든지 이를 취소할 수 있으며, 그러면 여러분의 앱이 설정한 활동은 즉시 사라집니다. - 사용자의 스위치. “앱에서 내 활동을 설정하도록 허용”을 끈 사용자에게는 아무것도 표시되지 않습니다. 이때도 PUT은 204를 반환하므로 여러분은 이를 구별할 수 없습니다.
https://gamevox.com/oauth2/authorize/?client_id=1491200000000000000
&response_type=code
&scope=identify%20activities.write
&redirect_uri=https%3A%2F%2Fexample.com%2Fgamevox%2Fcallback
&state=8f2c1a 설정과 삭제
봇 토큰으로 인증합니다. {user_id}는 사용자의 snowflake로, 봇이 다른 곳에서 보는 것과 같습니다.
PUT https://app-api.gamevox.com/api/v10/applications/@me/users/1491250000000000003/activity
Authorization: Bot <token>
Content-Type: application/json
{
"activity": {
"type": 0,
"details": "Hunting in Roshamuul",
"state": "Level 412 Elite Knight",
"timestamps": { "start": 1761868000000 },
"party": { "size": [2, 5] },
"assets": {
"large_image": "roshamuul", "large_text": "Roshamuul",
"small_image": "knight", "small_text": "Elite Knight"
},
"buttons": [ { "label": "View character", "url": "https://example.com/characters/412" } ]
},
"ttl_seconds": 300
}
HTTP/1.1 204 No Content
DELETE https://app-api.gamevox.com/api/v10/applications/@me/users/1491250000000000003/activity
Authorization: Bot <token>
HTTP/1.1 204 No Content GameVox가 읽는 방식
ttl_seconds: 갱신 없이 활동이 유지되는 시간으로, 60~900초입니다(기본값 300, 범위를 벗어난 값은 범위 안으로 맞춥니다). 만료되기 전에 현재 상태를 다시 PUT하세요. 서비스가 멈추면 활동은 저절로 사라집니다.name은 무시됩니다. GameVox는 여러분의 앱이 연결된 게임의 이름을, 없으면 앱의 이름을 표시하고, 항상 여러분의 앱을 “통해” 설정되었음을 덧붙입니다.- 유형 0, 1, 2, 3, 5. 사용자 지정 상태(4)는 거부됩니다.
- PUT은 해당 사용자에 대한 여러분의 이전 활동을 대체합니다. 아무것도 바꾸지 않는 갱신은 TTL만 연장합니다. 유형과 이름이 그대로인 동안
created_at도 그대로이므로 카드가 새것처럼 보이지 않습니다. - 이미지 키는 여러분의 애플리케이션 에셋이어야 합니다. 알 수 없는 키는 버려지고 텍스트는 그대로 표시됩니다.
- DELETE는 해당 사용자에 대한 여러분 앱의 활동만 삭제하며, 권한 부여가 필요 없습니다. 활동이 있었는지와 관계없이 204를 반환합니다.
오류
| HTTP | 코드 | 참고 |
|---|---|---|
204 | 성공. 사용자가 “앱에서 내 활동을 설정하도록 허용”을 끈 경우에도 이 응답입니다(아무것도 저장되지 않습니다). | |
400 | 50035 | 본문이 JSON이 아니거나, activity가 없거나 객체가 아니거나, ttl_seconds가 정수가 아니거나, 활동이 거부된 경우입니다. errors.activity.<field>._errors[0].code가 이유를 알려 줍니다: ACTIVITY_TYPE_INVALID, ACTIVITY_NAME_REQUIRED, ACTIVITY_TIMESTAMPS_INVALID, ACTIVITY_TOO_LARGE, ACTIVITY_INVALID, BASE_TYPE_REQUIRED, NUMBER_TYPE_COERCE. |
403 | 50001 | 앱이 사용자 활동에 대해 승인되지 않았거나, 사용자가 앱에 activities.write를 허용하지 않았거나 취소한 경우입니다. |
404 | 10002 | 알 수 없는 애플리케이션. |
404 | 10013 | 알 수 없는 사용자(해당 snowflake가 GameVox 사용자가 아님). |
413 | 본문이 16 KB보다 큽니다. | |
429 | 레이트 리밋. 본문은 Discord와 같은 형식이며 retry_after를 포함합니다. |
HTTP/1.1 400 Bad Request
{
"code": 50035,
"message": "Invalid Form Body",
"errors": {
"activity": {
"type": {
"_errors": [
{ "code": "ACTIVITY_TYPE_INVALID",
"message": "This activity type is not allowed for an application. Use 0, 1, 2, 3 or 5." }
]
}
}
}
} 제한
- 사용자당 20초에 5회 요청. PUT과 DELETE는 따로 계산합니다.
- 애플리케이션당 모든 사용자를 합쳐 초당 50회 요청.
이미지
애플리케이션의 Rich Presence 탭에서 이미지를 업로드하고 각각 키를 붙입니다(1~32자의 영문자, 숫자, _, -. 앱마다 고유하며 대소문자는 구분하지 않습니다). PNG, JPEG, WebP로 최대 1 MB이며, 모든 업로드는 사용되기 전에 검사됩니다. 활동에서는 키를 assets.large_image 또는 assets.small_image에 넣습니다.
- GameVox는 활동이 속한 애플리케이션의 에셋에서 키를 찾습니다. REST 엔드포인트와 봇에서는 여러분의 앱, RPC에서는 로컬 클라이언트 ID가 가리키는 앱입니다. 그 밖의 것은 참조할 수 없습니다.
- 큰 이미지가 없으면 GameVox는 해당 게임에 대한 자체 아트를, 그것도 없으면 여러분 앱의 아이콘을 표시합니다. 작은 이미지는 큰 이미지 위에만 표시됩니다.
- 삭제한 에셋은 몇 분 안에 카드에서 사라집니다.
- 이미지 URL, Discord
mp:미디어 프록시 값, 다른 앱의 키는 버려집니다.
앱의 에셋 나열하기
에셋 목록은 Discord와 마찬가지로 공개되어 있어, 도구에서 어떤 키가 있는지 확인할 수 있습니다. 인증이 필요 없습니다.
GET https://app-api.gamevox.com/api/v10/oauth2/applications/1491200000000000000/assets
HTTP/1.1 200 OK
Cache-Control: public, max-age=300
[
{ "id": "6f1c2e3a-…", "name": "roshamuul", "type": 1 },
{ "id": "9b0d4c7e-…", "name": "knight", "type": 1 }
] - 이미지 에셋만, 오래된 순서입니다.
id는 에셋의 ID,name은 그 키,type은 항상1입니다. - 알 수 없는 애플리케이션은 코드 10002와 함께 404를 반환합니다.
- 응답은 5분 동안 캐시되므로 새로 업로드한 것이 표시되기까지 그만큼 걸릴 수 있습니다. IP당 분당 30회 요청.
데스크톱 로컬 RPC
사용자 컴퓨터의 프로그램(게임, 런처, 미디어 플레이어)은 GameVox 데스크톱 앱(Windows, macOS, Linux)을 통해 사용자의 활동을 설정할 수 있습니다. 이 앱은 Discord RPC IPC 프로토콜을 사용하므로, Discord Game SDK와 커뮤니티 Rich Presence 라이브러리의 프레이밍이 그대로 동작합니다. 웹, iOS, Android 앱에는 로컬 RPC가 없습니다.
연결할 곳
- Windows: 명명된 파이프
\\.\pipe\gamevox-ipc-0(-0부터-9까지 시도하세요). - macOS와 Linux:
$XDG_RUNTIME_DIR, 없으면$TMPDIR/gamevox-<uid>/안의 Unix 소켓gamevox-ipc-0부터-9까지. - 같은 OS 사용자로 실행 중인 프로그램만 연결할 수 있습니다. 네트워크에서는 아무것도 수신 대기하지 않으며, WebSocket이나 HTTP 전송 방식도 없습니다.
- 사용자는 GameVox 설정에서 로컬 RPC를 끌 수 있습니다(기본값은 켜짐).
Discord RPC용으로 만든 프로그램을 위한 호환성 모드
Discord 파이프 이름만 아는 프로그램도, 사용자가 GameVox 설정에서 호환성 모드를 켜면(기본값은 꺼짐) GameVox를 찾을 수 있습니다. 이때 GameVox는 discord-ipc-0부터 -9에서도 응답하지만, Discord가 실행 중이 아닐 때만 그렇습니다. Discord가 시작되면 즉시 물러나고 10초마다 다시 확인합니다. 가능하면 직접 gamevox-ipc-N에 연결하세요. 대부분의 라이브러리는 파이프 이름을 설정할 수 있으며, 그러면 호환성 모드가 필요 없습니다.
프레이밍
각 프레임은 8바이트 헤더(opcode와 페이로드 길이를 부호 없는 32비트 리틀 엔디언 정수로)와 그 길이만큼의 UTF-8 JSON으로 이루어집니다. 64 KB보다 큰 프레임은 연결을 닫습니다.
| Opcode | 참고 |
|---|---|
0 HANDSHAKE | 첫 번째 프레임이며, 첫 번째 프레임에서만 사용합니다. |
1 FRAME | 명령과 그 응답. |
2 CLOSE | 어느 쪽이든 닫을 수 있습니다. GameVox가 연결을 거부할 때는 {code, message}를 보냅니다. |
3 PING | GameVox는 같은 페이로드의 PONG으로 응답합니다. |
4 PONG | PING에 대한 응답. |
핸드셰이크와 READY
연결 후 10초 안에 {"v": 1, "client_id": "…"}를 보내세요. client_id는 애플리케이션 ID(15~21자리)입니다. GameVox는 로그인한 사용자(그 사용자의 GameVox snowflake)를 담은 READY 디스패치로 응답합니다. 잘못된 핸드셰이크에는 코드 4000의 CLOSE로 응답합니다.
→ op 0 HANDSHAKE
{ "v": 1, "client_id": "1491200000000000000" }
← op 1 FRAME
{
"cmd": "DISPATCH",
"evt": "READY",
"nonce": null,
"data": {
"v": 1,
"config": {
"cdn_host": "files.gamevox.com",
"api_endpoint": "//app-api.gamevox.com/api",
"environment": "production"
},
"user": {
"id": "1491250000000000003", "username": "ben", "discriminator": "0",
"global_name": "Ben", "avatar": null, "bot": false, "flags": 0, "premium_type": 0
}
}
} SET_ACTIVITY
응답에는 GameVox가 받아들인 형태의 활동이 들어 있습니다. "activity": null로 활동을 지우며, 연결을 닫아도 지워집니다. 로컬 활동은 하나뿐이며, 마지막으로 활동을 설정한 프로그램이 그것을 소유합니다.
→ op 1 FRAME
{
"cmd": "SET_ACTIVITY",
"nonce": "7c1f0a52",
"args": {
"pid": 4242,
"activity": {
"type": 0,
"details": "Hunting in Roshamuul",
"state": "Level 412 Elite Knight",
"timestamps": { "start": 1761868000 },
"assets": { "large_image": "roshamuul", "large_text": "Roshamuul" },
"party": { "id": "p1", "size": [2, 5] }
}
}
}
← op 1 FRAME
{
"cmd": "SET_ACTIVITY",
"evt": null,
"nonce": "7c1f0a52",
"data": {
"id": "a41c09e2f3b8d715", "name": "Tibia", "type": 0, "url": null,
"created_at": 1761868800000,
"timestamps": { "start": 1761868000000 },
"application_id": "1491200000000000000",
"details": "Hunting in Roshamuul", "state": "Level 412 Elite Knight", "emoji": null,
"party": { "id": "p1", "size": [2, 5] },
"assets": { "large_image": "roshamuul", "large_text": "Roshamuul" },
"flags": 0
}
} | 명령 | 참고 |
|---|---|
SET_ACTIVITY | 활동을 설정하거나 지웁니다(위 참고). 유형 0, 2, 3, 5만 가능합니다. GameVox가 거부하는 것에는 evt: "ERROR"와 코드 4000으로 응답합니다. |
SUBSCRIBE | join, spectate, ready 이벤트를 구독하는 SDK가 계속 동작하도록 수락만 합니다. GameVox는 이 이벤트들을 절대 보내지 않습니다. |
UNSUBSCRIBE | SUBSCRIBE와 같습니다. |
* | 그 밖의 모든 것(AUTHORIZE, AUTHENTICATE, GET_GUILDS, 음성 및 로비 명령 등)에는 evt: "ERROR", 코드 4006, “Not supported by GameVox”로 응답합니다. |
동의와 신원
- 사용자가 여러분의 프로그램을 허용하기 전까지는 아무것도 컴퓨터 밖으로 나가지 않습니다. 처음에 GameVox는 허용, 나중에, 항상 거부 중에서 고르도록 묻습니다. 답은 실행 파일과 클라이언트 ID별로 기억됩니다. 그동안에도 SET_ACTIVITY는 평소처럼 응답하고 활동은 대기합니다.
- 여러분의 프로그램이 GameVox가 감지한 게임이고 클라이언트 ID가 GameVox에서 그 게임에 연결되어 있으면, GameVox는 묻지 않고 허용합니다.
- GameVox는 여러분이 누구인지 운영 체제(파이프 반대편의 프로세스와 그 실행 파일)를 통해 알아내며,
args.pid나 페이로드의 다른 내용으로 판단하지 않습니다. - 이름은 여러분이 아니라 GameVox가 정합니다. GameVox에서 클라이언트 ID가 연결된 게임 또는 앱, 없으면 실행 파일이 그 게임일 때 GameVox가 감지한 게임, 없으면 카탈로그가 그 실행 파일에 대응시키는 게임, 그것도 없으면 “앱”입니다. 활동의
name은 무시됩니다. - 버튼은 클라이언트 ID가 승인된 GameVox 앱이나 퍼스트파티 GameVox 앱의 것일 때만 표시됩니다. 이미지는 그 앱의 에셋에서 찾습니다.
- 텍스트는 GameVox 서버에서 다시 검사되며, 부적절한 세부 정보나 상태는 제거됩니다.
제한: 연결당 20초에 SET_ACTIVITY 5회, 최소 500ms 간격. 더 빠른 업데이트는 합쳐지며 가장 최근 것이 적용됩니다. 동시에 연결할 수 있는 프로그램은 최대 16개입니다.
구성원 프레즌스 받기
GUILD_PRESENCES 인텐트가 있으면, 봇이 들어가 있는 서버의 구성원이 상태나 활동을 바꿀 때 봇이 Discord와 같은 형식의 PRESENCE_UPDATE를 받습니다.
{
"op": 0,
"t": "PRESENCE_UPDATE",
"d": {
"user": { "id": "1491250000000000003" },
"guild_id": "1491230000000000001",
"status": "online",
"activities": [ {
"id": "a41c09e2f3b8d715", "name": "Tibia", "type": 0, "url": null,
"created_at": 1761868800000,
"timestamps": { "start": 1761868000000 },
"application_id": "1491200000000000000",
"details": "Hunting in Roshamuul", "state": "Level 412 Elite Knight", "emoji": null,
"assets": { "large_image": "roshamuul", "large_text": "Roshamuul" },
"buttons": [ "View character" ],
"flags": 0
} ],
"client_status": { "desktop": "online" }
}
} status는online,idle,dnd,offline중 하나입니다. 오프라인으로 표시 중인 구성원은 활동 없는offline입니다.client_status에는 항상desktop이 들어갑니다.- 서버 구성원이 보는 것과 같은 것을 봅니다. 구성원이 이 서버와 공유하지 않은 게임, 표시하기로 선택하지 않은 성인용 게임은 없으며, 세부 정보를 끈 구성원에게서는 이름과 유형만 받습니다.
- 활동은
id와created_at이 있는 Discord의 객체입니다.buttons는 라벨만 있으며, 버튼 URL이나 GameVox 자체 필드는 절대 받지 않습니다. - 변경 사항만 옵니다. GUILD_CREATE나 구성원 청크에는 프레즌스가 없습니다. 변경 사항은 구성원별로 약 2초 동안 묶여서 옵니다.
- 봇 자신의 상태는 다른 봇에게 보내지 않습니다.
셀프 호스팅 서버
셀프 호스팅 서버에서는 다음과 같습니다.
- 봇의 상태는 똑같이 동작하며 서버의 구성원에게 표시됩니다.
- 데스크톱 로컬 RPC도 똑같이 동작하지만, 서버는 클라이언트 ID를 조회할 수 없습니다. 활동이 감지된 게임의 것이면 그 게임의 이름을, 아니면 “앱”을 표시합니다. 버튼은 없으며, 이미지는 GameVox 자체 파일 호스트의 것만 쓸 수 있습니다.
- REST 엔드포인트로 앱에서 설정한 활동은 GameVox 클라우드(프로필, 친구, 클라우드 서버)에 표시되며, 셀프 호스팅 서버에는 표시되지 않습니다.
PRESENCE_UPDATE도 똑같이 동작하며, 서버가 직접 보냅니다.
지원하지 않는 것
- 참가, 관전, 참가 요청(
secrets,party.privacy, 로비)과 이에 따른 RPC 이벤트. - 이미지 URL과 Discord 미디어 프록시(
mp:) 이미지. 대신 에셋을 업로드하세요. - WebSocket 또는 HTTP를 통한 RPC와 RPC 권한 부여(AUTHORIZE / AUTHENTICATE).
- 사람의 사용자 지정 상태와 헤드리스 세션.