디스코드 봇, 직접 만들어보고 싶다는 생각 한 번쯤 해보셨을 겁니다. Discord.js는 Node.js 기반으로 돌아가는 라이브러리인데, 이를 통해 Discord API를 직접 사용하지 않고도 디스코드 봇을 만들 수 있습니다. 앞으로 몇 개의 글에 걸쳐서 봇 개발의 A부터 Z까지는 아니더라도, 필요한 핵심 내용들을 쭉 훑어보려고 합니다. 그 첫 단계로, 오늘은 코딩을 시작하기 전에 필요한 준비물들을 챙기고 첫 프로젝트를 세팅하는 과정을 같이 해보겠습니다.
Node.js 설치
우선 디스코드 봇이 뛰어놀 수 있는 환경, 바로 Node.js를 설치해야 합니다. Node.js는 자바스크립트 코드를 웹 브라우저 바깥에서도 실행할 수 있게 해주는 친구라고 생각하시면 됩니다. Discord.js 자체가 Node.js 위에서 돌아가기 때문에 이게 없으면 시작조차 할 수 없죠.
설치는 간단합니다. 먼저 Node.js 공식 홈페이지에 접속해주세요. 홈페이지에 들어가면 LTS 버전과 Current 버전이 보일 텐데, 특별한 이유가 없다면 LTS (Long Term Support) 버전을 받는 것이 좋습니다. 사용하시는 운영체제(윈도우, 맥 등)에 맞는 파일을 내려받아 설치를 진행하면 됩니다.
설치가 잘 끝났는지 확인하려면 터미널을 열어야 합니다. 맥에서는 Terminal, 윈도우에서는 CMD나 PowerShell을 실행하고 아래 명령어를 한 줄씩 입력해보세요.
node -v
npm -v
각각 vXX.X.X
하는 버전 정보가 뜨면 성공입니다. npm
은 Node.js를 설치할 때 같이 딸려오는 패키지 매니저인데, 앞으로 라이브러리를 설치하거나 할 때 계속 사용하게 될 겁니다.
VS Code 설치
코드를 작성할 편집기가 필요하겠죠? 물론 메모장으로도 코딩은 가능하지만... 정신 건강을 위해 좋은 도구를 쓰는 게 좋습니다. 저는 Visual Studio Code (VS Code)를 추천합니다. 마이크로소프트에서 만들었고, 무료인데다 기능도 강력하고, 사양도 많이 타지 않습니다.
VS Code 공식 홈페이지에서 본인 운영체제에 맞는 설치 파일을 받아 설치하면 됩니다.
VS Code를 설치했다면, 몇 가지 유용한 확장 프로그램을 깔아두면 좋습니다.
- ESLint: 우리가 작성하는 코드의 문법 오류를 잡아주거나, 정해진 코딩 스타일을 따르도록 도와줍니다.
- Prettier - Code formatter: 코드 줄 바꿈이나 띄어쓰기 같은 걸 예쁘게 자동으로 정리해줍니다. 일명 '코드 포맷터'죠.
- Node.js 관련 스니펫: VS Code 마켓플레이스에서
Node.js Snippets
같은 키워드로 검색해보면 코드 자동완성이나 템플릿을 제공하는 확장 프로그램들이 있습니다. 이런 걸 사용하면 반복적인 코드 작성을 줄일 수 있습니다.
Discord.js 프로젝트 생성하기
자, 이제 Node.js도 깔았고 VS Code도 준비됐으니 진짜 프로젝트를 만들어볼 시간입니다.
먼저 봇 프로젝트를 담아둘 폴더를 하나 만들어야겠죠. 터미널에서 아래 명령어를 사용하거나, 그냥 파일 탐색기에서 새 폴더를 만들어도 됩니다. 폴더 이름은 discordjs_tutorial
으로 했는데, 원하시는 대로 바꿔도 상관없습니다.
mkdir discordjs_tutorial
cd discordjs_tutorial
이제 이 폴더 안에서 Node.js 프로젝트를 시작한다는 신호를 줘야 합니다. package.json
이라는 파일을 만드는 과정인데, 이 파일에는 프로젝트 이름, 버전, 그리고 어떤 라이브러리들을 사용하고 있는지 같은 정보들이 기록됩니다.
npm init -y
-y
옵션을 붙이면 이것저것 물어보지 않고 기본값으로 빠르게 package.json
파일을 만들어줍니다.
다음은 오늘의 주인공, Discord.js 라이브러리를 설치할 차례입니다.
npm install discord.js
그리고 중요한 정보, 예를 들어 봇 토큰 같은 민감한 데이터를 코드에 직접 적어두는 건 별로 좋은 생각이 아닙니다. 이런 정보들을 별도의 파일에 안전하게 보관하고 쉽게 불러다 쓸 수 있게 해주는 dotenv
라는 라이브러리도 같이 설치해줍시다.
npm install dotenv
TypeScript 설정: 더 강력하고 안전한 코딩을 위해
JavaScript도 훌륭하지만, TypeScript를 사용하면 코드의 타입을 명시적으로 지정하여 개발 과정에서 발생할 수 있는 많은 오류를 미리 방지하고, 코드 자동 완성 기능도 더 강력하게 활용할 수 있습니다. 앞으로의 튜토리얼은 TypeScript를 기반으로 진행될 예정이니, 함께 설정해봅시다.
필수 패키지 설치: TypeScript와 ts-node
(TypeScript 코드를 바로 실행해주는 도구), 그리고 Node.js 타입 정의를 설치합니다.
```bash
npm install typescript ts-node @types/node --save-dev
```
`--save-dev` (또는 `-D`) 옵션은 개발 시에만 필요한 패키지임을 명시합니다. 이 패키지들은 실제 봇이 실행될 때는 직접적으로 필요하지 않고, 개발 과정에만 도움을 줍니다.
tsconfig.json 생성: TypeScript 컴파일러의 설정을 담는 tsconfig.json
파일을 생성합니다. 프로젝트 루트에서 다음 명령어를 실행하면 기본적인 설정 파일이 만들어집니다.
```bash
npx tsc --init
```
이 명령으로 `tsconfig.json` 파일이 생성됩니다. 처음에는 기본 설정으로도 충분하지만, 좀 더 체계적인 프로젝트 관리를 위해 몇 가지 옵션을 손보는 것이 좋습니다. 예를 들어, 우리 TypeScript 소스 코드는 `src` 폴더에, TypeScript가 JavaScript로 변환한 결과물(컴파일된 코드)은 `dist` 폴더에 저장하도록 설정할 수 있습니다. `tsconfig.json` 파일을 열고 `compilerOptions` 객체 안에 아래 내용을 참고하여 수정하거나 추가해보세요 (지금 당장 필수는 아니지만, 알아두면 좋습니다):
```json
{
"compilerOptions": {
// ... 다른 기본 옵션들 ...
"target": "ES2020", // 어떤 버전의 JavaScript로 컴파일할지 (Node.js LTS 버전에 맞춰 조정 가능)
"module": "commonjs", // 모듈 시스템 (Node.js 환경에서는 commonjs가 일반적)
"rootDir": "./src", // TypeScript 소스 파일들이 있는 루트 폴더
"outDir": "./dist", // 컴파일된 JavaScript 파일들이 저장될 폴더
"esModuleInterop": true, // ES 모듈과 CommonJS 모듈 간의 호환성을 높여줌
"strict": true, // 모든 엄격한 타입 검사 옵션을 활성화 (권장)
"skipLibCheck": true, // 모든 의존성 라이브러리의 타입 검사를 건너뛰어 빌드 속도 향상
"forceConsistentCasingInFileNames": true, // 파일 이름의 대소문자를 일관되게 사용하도록 강제
"moduleResolution": "node" // 모듈 해석 전략
// ...
},
"include": ["src/**/*"], // 컴파일할 파일들의 패턴 (src 폴더 아래 모든 .ts 파일)
"exclude": ["node_modules", "**/*.spec.ts"] // 컴파일에서 제외할 파일/폴더
}
```
src 폴더 생성: TypeScript 소스 코드를 모아둘 src
폴더를 프로젝트 루트에 만듭니다.
```bash
mkdir src
```
첫 번째 봇 코드
프로젝트 기본 세팅은 끝났습니다. 이제 봇을 실제로 움직이게 할 코드를 작성해볼게요.
디스코드 봇 토큰: 봇의 신분증
코드를 짜기 전에, 우리 봇이 디스코드 서버에 접속할 때 필요한 '봇 토큰'이라는 걸 발급받아야 합니다. 이를 위해 이 글을 참고해주세요.
.env 파일: 비밀은 소중하니까
아까 복사한 봇 토큰을 프로젝트에 안전하게 넣어둘 차례입니다. 프로젝트 폴더 최상단 (아까 package.json
파일 만든 곳)에 .env
라는 이름으로 새 파일을 만드세요. 그리고 그 안에 아래와 같이 내용을 적습니다.
# .env
DISCORD_TOKEN=봇_토큰
src/index.ts: 봇의 두뇌
이제 진짜 코드를 작성할 파일을 만들겠습니다. 위에서 생성한 src
폴더 안에 index.ts
라는 이름으로 파일을 만들고 (다른 이름, 예를 들어 bot.ts
로 해도 됩니다) 아래 코드를 붙여넣어 보세요. 이 코드는 TypeScript를 사용하며, 기본적인 봇의 동작을 정의합니다.
// src/index.ts
import { Client, Events, GatewayIntentBits } from 'discord.js';
import dotenv from 'dotenv';
// .env 파일에서 환경 변수를 로드합니다.
dotenv.config();
const token = process.env.DISCORD_TOKEN;
// 토큰이 설정되지 않았으면 오류를 출력하고 종료합니다.
if (!token) {
console.error('오류: DISCORD_TOKEN이 .env 파일에 설정되어 있지 않습니다. .env 파일을 확인해주세요.');
process.exit(1);
}
// 새로운 디스코드 클라이언트 인스턴스를 생성합니다.
// 인텐트(Intents)는 봇이 어떤 종류의 이벤트에 접근할 수 있는지를 명시합니다.
const client = new Client({
intents: [
GatewayIntentBits.Guilds, // 서버 관련 이벤트 (봇 추가/제거, 서버 정보 변경 등)
GatewayIntentBits.GuildMessages, // 서버 내 메시지 생성/수정/삭제 이벤트
GatewayIntentBits.MessageContent, // 메시지의 내용을 읽기 위한 권한 (중요! Discord Developer Portal에서 활성화 필요)
],
});
// 클라이언트(봇)가 준비되었을 때 한 번 실행되는 이벤트 리스너입니다.
// readyClient는 로그인된 클라이언트, 즉 우리 봇 자신을 가리킵니다.
client.once(Events.ClientReady, (readyClient) => {
console.log(\`로그인 성공! \${readyClient.user.tag} (으)로 접속 완료!\`);
console.log('봇이 준비되었습니다. 달려봅시다!');
// 봇의 활동 상태를 설정합니다. 예: "메시지 기다리는 중" (WATCHING)
// type: 0 (Playing), 1 (Streaming), 2 (Listening), 3 (Watching), 5 (Competing)
readyClient.user.setActivity('메시지 기다리는 중', { type: 3 /* Watching */ });
});
// 서버에서 메시지가 생성될 때마다 실행되는 이벤트 리스너입니다.
client.on(Events.MessageCreate, async (message) => {
// 메시지를 보낸 이가 봇이라면 아무 작업도 하지 않고 반환합니다 (무한 루프 방지).
if (message.author.bot) return;
// 사용자가 "핑" 이라고 메시지를 보내면 "퐁!" 이라고 답장합니다.
if (message.content === '핑') {
message.reply('퐁!');
}
// 사용자가 "안녕" 이라고 메시지를 보내면, 해당 유저를 언급하며 인사합니다.
// toLowerCase()를 사용하여 대소문자 구분 없이 처리합니다.
if (message.content.toLowerCase() === '안녕') {
message.channel.send(\`안녕하세요, \${message.author.toString()}님! 반가워요.\`);
}
});
// .env 파일에서 가져온 토큰을 사용하여 Discord에 로그인합니다.
client.login(token)
.then(() => {
console.log('봇이 Discord에 성공적으로 연결되었습니다.');
})
.catch((error) => {
console.error('봇 로그인 중 오류 발생:', error);
});
이 코드는 봇이 켜지면 콘솔에 로그를 남기고, 사용자가 "핑"이라고 치면 "퐁!"으로, "안녕"이라고 치면 반갑게 인사해주는 아주 간단한 녀석입니다. GatewayIntentBits.MessageContent
인텐트가 포함되어 있으니, Discord Developer Portal에서 해당 설정을 켜주는 것을 잊지 마세요!
봇 실행
드디어 봇을 실행시켜 볼 시간입니다. TypeScript로 코드를 작성했으니, ts-node
를 사용해서 별도의 컴파일 과정 없이 바로 실행할 수 있습니다. 터미널에 아래 명령어를 입력하세요.
npx ts-node src/index.ts
만약 tsconfig.json
에서 rootDir
을 ./src
로 설정했고, index.ts
파일이 src
폴더 안에 있다면 위 명령어가 잘 동작할 겁니다.
터미널에 로그인 성공! 봇이름#1234 (으)로 접속 완료!
와 봇이 준비되었습니다. 달려봅시다!
같은 메시지가 보이면 성공입니다! 이제 이 봇을 여러분의 디스코드 서버로 초대해서 테스트해볼 수 있습니다.
이제 초대된 서버에서 "핑"이나 "안녕"을 입력해서 봇이 잘 대답하는지 확인해보세요.
첫걸음을 떼며
여기까지 잘 따라오셨다면, 디스코드 봇 개발의 첫 단추를 성공적으로 끼운 겁니다. 아직은 아주 간단한 기능밖에 없지만, 이 기본 틀 위에서 앞으로 더 복잡하고 재미있는 기능들을 하나씩 붙여나갈 수 있을 거예요.
다음 글에서는 오늘 만든 이 프로젝트의 폴더 구조를 좀 더 깔끔하게 정리하고, 명령어를 좀 더 체계적으로 관리하는 방법에 대해 이야기해보겠습니다.
'DiscordJS 개발 튜토리얼' 카테고리의 다른 글
[DiscordJS 봇 개발 튜토리얼] 2. 명령어 구조 만들기: 슬래시 명령어를 위한 첫걸음 (1) | 2025.06.03 |
---|---|
[DiscordJS 봇 개발 튜토리얼] 1. 봇 상태 메시지 설정하기 (2) | 2025.06.02 |