discord-api
Discord API
Discord API는 여러분이 만든 **봇(bot)**이나 **앱(app)**이 Discord에 연결해 서버에서 일어나는 일을 듣고, 메시지를 보내고, 명령어에 응답할 수 있게 해 주는 공식 개발 인터페이스예요. 봇은 서버에 APP 태그를 단 봇 유저로 등장해서 이벤트를 감지하고, 슬래시 명령어(slash command)에 반응하고, 서버를 관리하고, 메시지를 전송하는 등 다양한 일을 여러분의 코드로 처리할 수 있어요.
Discord 앱이 Discord에 연결하는 방식은 크게 두 가지예요. 하나는 실시간 이벤트를 받는 Gateway WebSocket이고, 다른 하나는 별도의 상시 연결 없이 슬래시 명령어나 UI 컴포넌트를 처리하는 HTTP 인터랙션 엔드포인트예요. 대부분의 봇은 쓰임새에 따라 둘 중 하나 또는 둘 다를 조합해서 사용해요.
봇의 전형적인 쓰임새는 서버 관리 도구, 서버 유틸리티, 게임, 외부 서비스와의 연동, 자동화 워크플로 등 다양해요. 만약 채널에 메시지를 넣기만 하면 되는 경우라면 완전한 봇보다 **웹훅(webhook)**이 더 적합할 수 있어요. 웹훅은 설정이 훨씬 간단하고 리치 임베드(embed)를 담은 메시지를 보낼 수 있지만, 봇처럼 이벤트를 듣거나 인터랙션에 응답할 수는 없어요.
출처: 문서
본문
봇(Bot) 만들기
봇은 가장 흔한 타입의 Discord 앱이에요. 봇은 Gateway WebSocket으로 실시간 이벤트를 받을 수도 있고, HTTP 인터랙션 엔드포인트로 슬래시 명령어와 UI 컴포넌트에 응답할 수도 있어요. Discord API의 기본 주소는 https://discord.com/api/v10이에요.
봇을 만드는 첫걸음 순서는 크게 이렇게 돼요:
- Discord Developer Portal에서 애플리케이션을 만들고 Bot 탭에서 봇 유저를 추가해요.
- Bot 토큰을 발급받아요. 이 토큰은 봇의 비밀번호 같은 것이므로 절대 공개하면 안 돼요.
- 봇을 추가하고 싶은 서버(guild)에 OAuth2 인증 URL로 초대해요.
- 코드에서 토큰을 사용해 Gateway에 연결하거나 REST API를 호출해요.
Gateway
Gateway API는 앱이 Discord와 보안 WebSocket 연결을 열어 서버(guild)에서 일어나는 동작(채널이 업데이트되거나 역할이 생성되는 등)에 대한 이벤트를 받을 수 있게 해 주는 실시간 통신 수단이에요. 대부분의 REST 작업은 HTTP API로 처리할 수 있고, Gateway는 주로 실시간 알림을 받는 데 쓰여요.
Gateway 이벤트는 앱과 Discord 사이 오가는 페이로드(payload)예요. 모든 Gateway 이벤트는 하나의 이벤트 페이로드로 캡슐화돼요. 예시:
{
"op": 0,
"d": {},
"s": 42,
"t": "GATEWAY_EVENT_NAME"
}
op— opcode(명령 종류)예요.d— 이벤트 데이터예요.s— 시퀀스 번호로, 하트비트와 재연결(Resume)에 사용돼요.t— 디스패치 이벤트의 이름이에요.
Gateway 연결 주기는 대략 이렇게 돌아가요:
Get Gateway또는Get Gateway Bot엔드포인트로 WSS URL을 가져와 캐시해요.- Discord가 하트비트 주기를 담은
Hello(opcode 10) 이벤트를 보내요. - 앱이 하트비트(Heartbeat, opcode 1)를 주기마다 보내고, Discord는
Heartbeat ACK(opcode 11)로 응답해요. - 앱이
Identify(opcode 2)로 최초 핸드셰이크를 하고, Discord가Ready(opcode 0)를 보내면 연결이 성립돼요. - 연결이 끊기면
Resume(opcode 6)으로 재개하거나 처음부터 다시 연결해요.
연결 URL은 보통 이렇게 되어요:
wss://gateway.discord.gg/?v=10&encoding=json
인텐트(Intents): 대부분의 이벤트는 앱이 Identify할 때 인텐트를 정의해야 받을 수 있어요. 인텐트는 비트 값이라서 |(OR) 연산으로 원하는 이벤트 묶음을 표시할 수 있어요. 굳이 상시 WebSocket 연결이 필요 없다면 REST API나 인터랙션으로 충분한 경우가 많아요.
인터랙션과 슬래시 명령어
**인터랙션(Interaction)**은 사용자가 앱과 소통하는 방식이에요. **애플리케이션 명령어(Application Command)**는 Discord 클라이언트 안에서 앱과 상호작용하는 기본적인 방법으로, 세 가지 타입이 있어요:
CHAT_INPUT(type 1) — 슬래시 명령어로,/명령어형식이에요.USER(type 2) — 사용자를 우클릭했을 때 나오는 컨텍스트 메뉴 명령어예요.MESSAGE(type 3) — 메시지를 우클릭했을 때 나오는 컨텍스트 메뉴 명령어예요.
명령어는 HTTP 엔드포인트로만 등록할 수 있어요. 글로벌(global) 명령어는 모든 서버에 적용되고, 길드(guild) 명령어는 특정 서버에만 즉시 적용돼요. 개발 중에는 길드 명령어로 빠르게 테스트하고, 공개할 때는 글로벌 명령어로 전환하는 걸 권장해요.
글로벌 슬래시 명령어를 등록하는 예시:
import requests
url = "https://discord.com/api/v10/applications/<my_application_id>/commands"
# 이건 type 1인 CHAT_INPUT, 즉 슬래시 명령어 예시예요
json = {
"name": "blep",
"type": 1,
"description": "Send a random adorable animal photo",
"options": [
{
"name": "animal",
"description": "The type of animal",
"type": 3,
"required": True,
"choices": [
{"name": "Dog", "value": "animal_dog"},
{"name": "Cat", "value": "animal_cat"},
{"name": "Penguin", "value": "animal_penguin"}
]
},
{
"name": "only_smol",
"description": "Whether to show only baby animals",
"type": 5,
"required": False
}
]
}
# 인증에는 봇 토큰을 쓰거나
headers = {"Authorization": "Bot <my_bot_token>"}
# 아니면 applications.commands.update 스코프의 client credentials 토큰을 써요
headers = {"Authorization": "Bearer <my_credentials_token>"}
r = requests.post(url, headers=headers, json=json)
길드 명령어는 스코프만 특정 guild_id로 바꿔서 등록해요:
url = "https://discord.com/api/v10/applications/<my_application_id>/guilds/<guild_id>/commands"
명령어는 같은 타입과 스코프 안에서 이름이 고유하기 때문에, 같은 이름으로 다시 POST하면 기존 명령어를 **업데이트(upsert)**해요. 삭제는 DELETE, 수정은 PATCH 호출로 해요.
임베드(Embed)
임베드는 메시지에 풍부한(리치) 형식의 콘텐츠를 담아 보여주는 구조예요. 색상, 제목, 설명, 푸터, 필드 등을 이용해 예쁘고 읽기 쉬운 메시지를 만들 수 있어요. 임베드 객체(Embed Object)의 주요 필드는 다음과 같아요:
| Field | Type | Description |
|---|---|---|
| title? | string | 임베드의 제목 |
| description? | string | 임베드의 설명 |
| url? | string | 임베드의 URL |
| timestamp? | ISO8601 timestamp | 임베드 내용의 타임스탬프 |
| color? | integer | 임베드의 색상 코드 |
| footer? | embed footer object | 임베드의 푸터 정보 |
| fields* | array of embed field | 임베드의 필드 목록 |
{
"embeds": [
{
"title": "안녕하세요, Discord API",
"description": "이것은 임베드 예시입니다.",
"color": 7506394,
"fields": [
{
"name": "필드 이름",
"value": "필드 값",
"inline": true
}
]
}
]
}
임베드는 봇이 메시지를 보낼 때 embeds 배열로 전달하거나, 웹훅으로도 보낼 수 있어요. 임베드는 메시지 하나에 여러 개 넣을 수 있고, 서버 관리 알림이나 게임 결과 표시 같은 곳에 아주 유용해요.
사용 예시 요약
- 메시지 보내기:
POST /channels/{channel.id}/messages— 봇 토큰으로 인증. - 슬래시 명령어 등록:
POST /applications/{application.id}/commands— 로컬 또는 길드 스코프. - 실시간 이벤트 수신:
wss://gateway.discord.gg/?v=10&encoding=json— Gateway WebSocket 연결. - 임베드:
/messages전송 시embeds배열에 담아 보냄. - 간단한 메시지 전송만 필요할 때: 완전한 봇 대신 웹훅 사용 권장.
성숙한 커뮤니티 라이브러리(discord.js, discord.py 등)를 쓰면 Gateway 연결과 인텐트, 재연결 같은 복잡한 부분을 많이 줄일 수 있어요. 다만 커스텀 구현을 직접 하려면 Gateway 문서를 끝까지 꼼꼼히 읽어야 해요.