개발자 포털
실험적 봇 및 앱 플랫폼은 활발히 개발 중입니다. 자체 호스팅 서버 지원은 2026-08-13에 출시되었으며 클라우드보다 기능 범위가 좁습니다. 지원 항목 보기.
← 문서

Discord에서 마이그레이션

설정값 두 개(REST 기본 URL과 게이트웨이 URL)만 바꾸면 기존 Discord 봇을 GameVox에서 실행할 수 있습니다. 코드 변경도, SDK 교체도 필요 없습니다.

1. GameVox 봇 애플리케이션 만들기

  1. developers.gamevox.com에 로그인
  2. 새 애플리케이션 클릭
  3. 생성 창에서 봇 토큰을 복사(한 번만 표시되므로 바로 저장하세요)

2. 라이브러리를 GameVox로 향하게 하기

discord.js(Node, v14+)

const { Client, GatewayIntentBits } = require('discord.js');

const client = new Client({
  intents: [
    GatewayIntentBits.Guilds,
    GatewayIntentBits.GuildMessages,
    GatewayIntentBits.MessageContent,
  ],
  rest: { api: 'https://bot-api.gamevox.com/api' },
  ws:   { gatewayURL: 'wss://gateway.gamevox.com' },
});

client.login(process.env.GAMEVOX_BOT_TOKEN);

discord.py

import discord

discord.http.Route.BASE = 'https://bot-api.gamevox.com/api/v10'
discord.gateway.DiscordWebSocket.DEFAULT_GATEWAY = (
    'wss://gateway.gamevox.com/?v=10&encoding=json'
)

intents = discord.Intents.default()
intents.message_content = True

client = discord.Client(intents=intents)
client.run(GAMEVOX_BOT_TOKEN)

JDA(Java)

JDA jda = JDABuilder.createDefault(GAMEVOX_BOT_TOKEN)
    .setGatewayEncoding(GatewayEncoding.JSON)
    .setRestConfig(new RestConfig().setBaseUrl("https://bot-api.gamevox.com/api"))
    .setGatewayPool(scheduler)
    .build();
// JDA는 시작할 때 /gateway/bot 에서 게이트웨이 URL을 읽습니다.
// 저희 REST 심은 여기서 wss://gateway.gamevox.com 을 반환합니다.

Eris(Node)

const Eris = require('eris');

const client = new Eris(GAMEVOX_BOT_TOKEN, {
  rest: { baseURL: 'https://bot-api.gamevox.com/api/v10' },
  ws: { gateway: 'wss://gateway.gamevox.com' },
  // Eris는 기본적으로 ETF를 씁니다. JSON을 강제하세요(GameVox는 아직 ETF를 지원하지 않습니다).
});

client.connect();

DSharpPlus(.NET)

var discord = new DiscordClient(new DiscordConfiguration
{
    Token = Environment.GetEnvironmentVariable("GAMEVOX_BOT_TOKEN"),
    TokenType = TokenType.Bot,
    Intents = DiscordIntents.AllUnprivileged | DiscordIntents.MessageContents,
    ApiChannelEndpoint = "https://bot-api.gamevox.com/api/v10",
    GatewayUri = new Uri("wss://gateway.gamevox.com"),
});

await discord.ConnectAsync();

serenity(Rust)

let mut client = Client::builder(&token, intents)
    .event_handler(Handler)
    .api_base("https://bot-api.gamevox.com/api/v10")
    .gateway_url("wss://gateway.gamevox.com")
    .await?;
client.start().await?;

3. 봇을 서버에 설치하기

개발자 포털에서 애플리케이션의 OAuth2 탭을 열고, 필요한 권한으로 설치 URL을 만들어 공유하세요. URL은 Discord와 같은 형태입니다.

https://gamevox.com/oauth2/authorize?client_id=YOUR_APP_ID&scope=bot+applications.commands&permissions=8

서버 소유자가 링크를 눌러, 자신이 소유한 GameVox 서버를 고르고 확인하면 됩니다.

4. 다른 점

호환성은 100%를 목표로 합니다. 봇 로직이 “Discord가 아니다”라는 사실을 알 필요는 없습니다. 다만 알아 두면 좋은 몇 가지가 있습니다.

  • 앱 설정은 클라이언트 안에서 합니다. GameVox는 서버 설정 안에 앱의 설정 폼을 렌더링할 수 있어, 설정이 있는 봇도 더 이상 호스팅된 대시보드가 필요하지 않습니다. 이는 의도적인 유일한 비호환이자, Discord에 대응물이 없는 유일한 부분입니다. 전체 문서 →
  • Snowflake 에포크: Discord와 동일합니다(1420070400000, 2015-01-01 UTC). Discord용으로 작성한 파서는 GameVox ID에서도 그대로 동작합니다. 자세히 →
  • 스레드 / 포럼 게시물은 아직 지원하지 않습니다.
  • 음성은 Lavalink로 동작합니다. 별도 설정은 없습니다. VOICE_SERVER_UPDATEcompatible-voice-gateway-{region}.gamevox.com을 가리키기만 하면 나머지는 Lavalink가 처리합니다.
  • 커스텀 이모지: 서버 소유 이모지는 Discord와 똑같이 메시지에서 동작합니다. 앱 소유 이모지는 당분간 개발자 포털에서 관리하며, 봇 API는 GET만 제공합니다. 이모지를 참고하세요.
  • 자체 호스팅 서버: 고객은 자체 하드웨어에서 GameVox를 운영할 수 있습니다. 봇도 거기서 동작하지만 기능 범위는 더 좁습니다(아직 웹훅과 인터랙션은 없습니다). 자체 호스팅 문서를 참고하세요.
  • EU / AP 쓰기 지연: us-east 밖에서 호스팅되는 봇은 Aurora 쓰기 전달로 인해 쓰기 작업에서 약 80~150ms의 추가 지연이 생깁니다. 최상의 성능을 원한다면 us-east에서 호스팅하세요.

5. GameVox 안에서 앱 설정하기

Discord에서는 설정이 조금이라도 있는 봇이면 웹 대시보드를 함께 만들게 됩니다. 도메인, OAuth2 로그인, 세션, 권한 확인, 호스팅까지 — 대개는 운영자가 로그 채널을 고르고 기능 세 개를 켜고 끄게 하려는 것뿐입니다. GameVox는 운영자가 누구인지, 어떤 서버를 설정하는지, 그럴 권한이 있는지 이미 알고 있으므로 그 화면을 앱에 바로 제공합니다.

앱은 게이트웨이로 폼을 기술하고, GameVox가 서버 설정 ▸ 통합 ▸ 설정에 렌더링한 뒤 편집된 값을 그대로 돌려줍니다. GameVox는 아무것도 저장하지 않으며, 설정의 소유자는 오직 여러분의 앱입니다.

GameVox 클라이언트의 서버 설정 창. 설치된 앱의 설정 탭에 언어 드롭다운, 토글, 채널 체크리스트가 보입니다.
봇 하나의 응답만으로 전부 렌더링되었습니다. 봇은 채널 id를 보내지 않았고, 선택기가 종류를 지정하면 GameVox가 이 서버의 선택지를 채워 넣습니다. 서버와 채널 이름은 가렸습니다.

통합 전체는 게이트웨이 핸들러 하나와 REST 호출 하나뿐입니다.

client.on("raw", async (packet) => {
  if (packet.t !== "APP_SETTINGS_REQUEST") return;
  const { nonce, server_id, action, values } = packet.d;

  const body = action === "save"
    ? { message: await save(server_id, values) }
    : { version: 2, sections: await describe(server_id) };

  await client.rest.post("/applications/@me/settings-response", {
    body: { nonce, ...body },
    query: new URLSearchParams({ server_id }),
  });
});

GameVox가 내용을 채워 주는 채널·역할 선택기를 포함해 12가지 필드 유형, 조건부 필드, 가려진 시크릿, 섹션을 사용할 수 있습니다. 앱 내 설정 →

6. 확인해 보기

가장 간단한 확인 방법은 !pingpong으로 답하는 것입니다.

client.on(Events.MessageCreate, async (msg) => {
  if (msg.author.bot) return;
  if (msg.content === '!ping') {
    await msg.reply('pong');
  }
});

READY가 로그에 찍히고 답장이 도착하면 봇은 완전히 연결된 것입니다. 슬래시 명령어, 음성, 컴포넌트도 변경이 필요 없습니다.