문서:Discord/봇/제작법

역사 raw
대문 랜덤 문서 최근 토론




1. 개요2. [[Python|파이썬]] ([[discord.py]])3. [[Node.js]] ([[discord.js]])4. [[Java]] ([[JDA]])5. [[C##|C#]] (Discord.net)6. [[Go(프로그래밍 언어)|Go]] (Discordgo)7. Bot Designer For Discord
7.1. 소개7.2. 만드는 방법7.3. 코드 예시
8. [[https://discordapp.com/developers/docs/intro|Discord API]]9. Discord Bot Maker

1. 개요

다음은 디스코드 비공식 API로 봇을 만드는 방법, 예제를 나열한 것이다.

참고로 이 문서에 서술되어 있는 라이브러리는 전부가 아니다. Dart, elixir, swift, rust, lua, php 등등 정말 많은 라이브러리가 있으니 참고해보자.#

여담으로 이러한 봇 외에도 자신만의 디스코드 클라이언트를 만들 수 있다.[1]

2. 파이썬 (discord.py)

공식 영문 문서

어떤 클래스, 메서드 등이 있는지는 이 곳에서 볼 수 있다.

패키지 설치:

# 리눅스 또는 macOS
python3 -m pip install -U discord 또는 pip3 install discord

# 윈도우
pip install -U discord 또는 python -m pip install -U discord


예시(ext 사용):
import discord
from discord.ext.commands import Bot

intents=discord.Intents.default()
bot = Bot(command_prefix='!', intents=intents)

@bot.event
async def on_ready():
    print(f'{bot.user} 에 로그인하였습니다!')

@bot.command()
async def ping(ctx):
    await ctx.send('pong!')

@bot.command()
async def hello(ctx):
    await ctx.reply('hello!')

bot.run('토큰')


예시(Client 사용):
import discord

intents=discord.Intents.default()
client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f'{client.user} 에 로그인하였습니다!')

@client.event
async def on_message(message):
    if message.content.startswith('!ping'):
      await message.channel.send('pong!')

    if message.content.startswith('!hello'):
      await message.reply('pong!')

client.run('토큰')


이 문서에서 개요와 프로그래밍 방법을 더 자세히 볼 수 있다.

추가로 intents 기능은 discord 개발자 웹사이트에서 Bot 항목 제일 하단에서 활성화 할 수 있다.

3. Node.js (discord.js)

디스코드 JS 패키지 문서
영문 개발 가이드

다음은 discord.js 웹페이지에 나와있는 예시 코드이다. 가장 기본적이다
const Discord = require('discord.js'); // 모듈을 가져온 뒤,
const client = new Discord.Client(); // Discord.Client 객체 생성.

client.on('ready', () => { // 이벤트 리스너 (ready 이벤트)
  console.log(`Logged in as ${client.user.tag}!`);
});

client.on('message', (msg) => { // 이벤트 리스너 (message 이벤트)
  if (msg.content === 'ping') { // discord.Message.content 속성이 'ping'과 같을 떄
    msg.reply('Pong!'); // discord.Message.reply 메서드로 'Pong!'을 전송
  }
});

client.login('token'); // token으로 discord API에 Identify 전송



그리고 공식 문서에는 없지만 주로 쓰이는 메세지 이벤트 리스너를 Array(배열)로 처리하는 방식이 있다.
const Discord = require("discord.js"); // 모듈을 가져온 뒤,
const client = new Discord.Client(); // Discord.Client 객체 생성.
const prefix = '!'; // 접두사

client.on("message", async message => { // 이벤트 리스너 (message 이벤트)
  if (message.content.startsWith(prefix)) {
    const args = message.content.slice(prefix.length).split(" "); // 메세지에서 프리픽스의 글자 수만큼 잘라내고, String.split 메서드를 이용하여 Array로 바꾼다.
    const command = args.shift().toLowerCase(); // Array의 첫번 째 값을 없애고 반환하는 Array.shift 메서드에 String.toLowerCase 메서드로 소문자화한다.

    if (command === "ping") { // discord.Message.content 속성이 'ping'과 같을 떄
        message.reply("pong"); // discord.Message.reply 메서드로 'pong'을 전송
        // 정말 ping (지연시간) 을 전송하고 싶다면 client.ws 객체의 ping 속성을 이용하자.
        // message.reply(Math.round(client.ws.ping));
    }
  }
});

client.login("token");


이 코드들 말고도 파일을 나누어 핸들링하는 방법도 있고, 또 이미 만들어진 Commando[2]를 이용하는 방법도 있다. 자세한 내용은 문서를 참고하자.

4. Java (JDA)

JDA라는 라이브러리를 MAVEN 프로젝트 또는 Gradle 프로젝트에서 가져올 수 있다. 자세한 내용은 여기를 참고하면 된다.
Java 라이브러리 특성상 Kotlin과의 연동 역시 가능하다.

아래는 위키에 나와있는 간단한 예시 코드이다.
public class NamuWikiBot extends ListenerAdapter {

    public static void main(String[] args) throws LoginException {

        // 기본 jda를 만들고
        JDA jda = JDABuilder.createDefault("토큰").build();

        // jda에 이벤트를 감지하는 리스너를 넣는다.
        jda.addEventListener(new NamuWikiBot());
    }

    @Override
    public void onMessageReceived(MessageReceivedEvent event) {

        // 받은 메세지 내용이 ping이라면
        if (event.getMessage().getContentRaw().equals("!ping")) {
            // pong라는 내용을 보낸다.
            event.getChannel().sendMessage("pong!").queue();
        }
    }
}

5. C# (Discord.net)

Discord.net은 .Net Core 2.0 이상부터 지원한다.
|Lavalink 라이브러리를 이용하여 간단하게 음악 봇을 만들 수 있다.

아래 코드는 간단한 ping 예시 코드이다.
using System;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;

namespace namu_wiki_discord_sample_CSharp_Disocrd_net
{
    class Program
    {
        private readonly DiscordSocketClient _client;
        static void Main(string[] args)
        {
            new Program().MainAsync().GetAwaiter().GetResult();
        }

        public Program()
        {
            _client = new DiscordSocketClient();

            _client.Log += Log;
            _client.Ready += Ready;
            _client.MessageReceived += MessageReceivedAsync;
        }

        public async Task MainAsync()
        {
            await _client.LoginAsync(TokenType.Bot, "토큰");
            await _client.StartAsync();

            await Task.Delay(-1);
        }

        private Task Log(LogMessage log)
        {
            Console.WriteLine(log.ToString());
            return Task.CompletedTask;
        }

        private Task Ready()
        {
            Console.WriteLine(quot;{_client.CurrentUser} 연결됨!");

            return Task.CompletedTask;
        }

        private async Task MessageReceivedAsync(SocketMessage message)
        {
            if (message.Author.Id == _client.CurrentUser.Id)
                return;

            if (message.Content == "!ping")
                await message.Channel.SendMessageAsync("pong!");
        }
    }
}


Discord.net 팀에서 샘플하고 문서를 제공하니 참고하자.

6. Go (Discordgo)

package main

import (
	"flag"
	"fmt"
	"os"
	"os/signal"
	"syscall"

	"github.com/bwmarrin/discordgo"
)

var (
	Token string
)

func init() {

	flag.StringVar(&Token, "t", "", "Bot Token")
	flag.Parse()
}

func main() {
	dg, err := discordgo.New("Bot " + Token)
	if err != nil {
		fmt.Println("error creating Discord session,", err)
		return
	}
	dg.AddHandler(messageCreate)
	err = dg.Open()
	if err != nil {
		fmt.Println("error opening connection,", err)
		return
	}
	fmt.Println("Bot is now running.  Press CTRL-C to exit.")
	sc := make(chan os.Signal, 1)
	signal.Notify(sc, syscall.SIGINT, syscall.SIGTERM, os.Interrupt, os.Kill)
	<-sc
	dg.Close()
}
func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) {
	if m.Author.ID == s.State.User.ID {
		return
	}
	if m.Content == "ping" {
		s.ChannelMessageSend(m.ChannelID, "Pong!")
	}
	if m.Content == "pong" {
		s.ChannelMessageSend(m.ChannelID, "Ping!")
	}
}


7. Bot Designer For Discord

7.1. 소개

디스코드 봇 제작/호스팅을 위한 해외 앱이다. Android/iOS 모두 사용 가능하며 한국어 번역은 지원하지 않는다.
개발언어는 BDScript이며, 이름을 따온듯 한다.
웹버전도 있으며(알파 버전이라서 불안정하고 기능이 없는건 함정) https://botdesignerdiscord.com/app/home에서 확인 가능하다. 공식 문서도 당연히 영어이며 정말로 많은 기능들이 있다.
개발 언어로 위에서 소개한 Javascript도 지원하니 시도해볼 수 있다.

7.2. 만드는 방법

우선 오른쪽의 "Create new bot'을 눌러 봇의 이름과 토큰을 입력한다. 우선 개발자 포털에서 앱을 만들어야 한다.
그렇게 봇이 제작되면 왼쪽 위 햄버거 메뉴를 누르고 Commands로 들어간다. 가운데 "Command creator"을 누르고 반응할 메세지를 입력한다.

7.3. 코드 예시

아래는 직접 작성한 코드이다.

$nomention

$randomText[안녕하세요 $username님!;$username님 안녕하세요!]

예를들어 사용자명이 namuwiki#0001이라면 안녕하세요 namuwiki#0001님! 또는 namuwiki#0001님 안녕하세요! 중에 하나를 랜덤으로 반응한다.

위에서도 말했듯이 영어이기 때문에 우선 영어를 공부한 후 본 앱을 접하는 것을 강력히 추천한다.


8. Discord API

디스코드 공식 API를 직접 이용해 봇을 만들 수 있다. 위에 나와있는 비공식 라이브러리들을 안 쓰고 작동 기반을 직접 만든다고 보면 된다.
이걸로 라이브러리를 만들거나,[3] 앱을 만들 수 있다. 하지만 공식 API특성상 초보들한텐 추천하지 않는다.[4]
왜냐하면 디스코드 API는 많이 복잡하기 때문이다. 봇이 웹소켓 통신을 시작하면 JSON 데이터로 OP코드, 토큰, 라이브러리 등 정보를 보내야하고[5], 또 봇이 켜져있게 하고 웹소켓을 계속 연결하고 싶다면 일정한 주기로 Heartbeat를 보내야 하는데 또 이건 멀티 스레딩 또는 비동기를 모르는 사람에게는 불가능한 일이다. 심지어 디스코드에선 랜덤하게 Reconnect코드를 보내는데 이러면 아까 Identify 데이터에 최근 시퀀스 숫자까지 보내야 한다. 정말 프로그래밍 입문자라면 거들떠도 보지않는걸 추천한다.[6]

다만 바꿔말하자면 HTTP통신과 웹소켓, 비동기에 관한 공부만 끝마친다면 어느정도의 센스와 함께 시행착오를 거치며 도전할 수 있는 주제라는 것이다. 사실 웹사이트나 매크로 등(심지어는 어플 하나만 만들려고 해도 디버깅에 통신은 필수다...)에 조금만 손을 대봤다면 알듯이 통신 관련 기능에 접근하려면 기본적으로 저러한 개념들을 알아야 가능하다. 거기에 비동기는 거의 모든 프로그램들이 실용성을 가지게 만들어주는데 무조건적으로 필요한 개념일 정도. 각 프로그래밍 언어에서 기본 메서드나 함수만을 배운 사람들한테는 어려울 수 있어도, 어느정도 노하우를 갖춘 사람들과 모르는 것들을 직접 찾아보며 자신만의 기능을 가진 프로그램을 만들어보려 노력하는 사람들에게는 울고 웃으며 경험을 쌓을 수 있는 크나큰 기회다.[7] 으레 그렇듯이 어려운 문제일수록 해결과정 동안 기초적인 개념부터 어려운 응용까지 깊이 이해할 수 있다는 장점을 가지므로 너무 떨지말고 한번 도전해보는 것도 추천한다.

9. Discord Bot Maker

DiscordBotMaker는 게이머들을 위한 #1 텍스트 및 음성 채팅 서비스를 위한 강력한 봇 개발 도구입니다.
이 도구를 통해 여러분과 여러분의 팀원들은 여러분의 사회적 경험을 한 단계 끌어올릴 수 있습니다!

이름 그대로 Discord의 BOT을 자바스크립트 등등이 필요없이 간편하게 만들수 있는 Node.js 기반 프로그램이다.

스팀에서 9.99$(10,500원)에 판매중이며 깨끗한 UI와 초보자가 봇에 쉽게 입문할 수 있지만 좀 쓰다보면 거르고 자바스크립트로 갈아타는 경향이 있으니 괜히 이거 쓰다가 내돈 아까워 하지 말고 걍 처음부터 위에 있는 Node.js를 사용하는것을 추천한다.[8][9]

GitHub에 Discord bot maker 전용 모드가 있는데 그걸 적용하면 디스코드에서 노래봇도 만들 수 있다.

[1] 다만 봇이 아닌 일반 계정으로 만든 봇에 로그인하는 것은 약관 위반이다.[2] discord.ext와 비슷한 개념이다. 자동화된 기능이 있다.[3] 위에 있는 비공식 라이브러리는 이 공식 API를 이용해서 제작되었다.[4] 공식 API를 이용하려면 최소한 웹소켓, HTTP 통신을 알아야 한다.[5] Identify를 전송하는 것이다.[6] 이게 끝이 아니다. 디스코드에서 서버를 확인하려면 특정 엔드포인트에서 REST API로 GET메서드를 보내고 메시지는 /channels/{channel id}/messages에 POST를 하는 등 아주 복잡하다. 심지어는 음성을 전달할 때 Opus 코덱으로 직접 인코딩하여 웹소켓으로 보내야한다.(...)[7] 또한 디스코드에 새 기능이 추가되면 공식 API에는 거의 바로 반영되지만, 비공식 라이브러리는 반영되는 데 시간이 걸리는 점도 있다. 이러한 이유로 디스코드의 새로운 기능을 사용하고 싶고 HTTP request는 아는데 웹소켓 부분에서 막히는 경우 비공식 라이브러리에 없는 기능만 직접 API에 request를 보내서 사용하기도 한다.[8] 아무래도 자바스크립트나 다른 코딩 언어에 비해 뒤쳐지는 부분이 없지않아 있다.[9] 또한 Discord Bot Maker는 유료지만 Node.js는 무료라는 점도 있다.