최근 수정 시각 : 2024-03-07 20:17:05

Discord/봇/제작법


파일:상위 문서 아이콘.svg   상위 문서: Discord/봇
1. 개요2. 파이썬 (discord.py, Pycord)3. Node.js (discord.js)4. Java (JDA)5. C# (Discord.net)6. Go (Discordgo)7. C++ (DPP)8. Bot Designer For Discord
8.1. 소개8.2. 만드는 방법8.3. 코드 예시
9. Discord API10. Discord Bot Maker11. 봇 인증12. 봇 호스팅

1. 개요

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

참고로 이 문서에 서술되어 있는 라이브러리는 전부가 아니다. Dart, elixir, Swift, Rust, Lua, PHP 등등 정말 많은 라이브러리가 있으니 참고해보자.#
여담으로 이러한 봇 외에도 자신만의 디스코드 클라이언트를 만들 수 있다.[1]

2. 파이썬 (discord.py, Pycord)

파일:상세 내용 아이콘.svg   자세한 내용은 discord.py 문서
번 문단을
부분을
참고하십시오.
파일:상세 내용 아이콘.svg   자세한 내용은 Pycord 문서
번 문단을
부분을
참고하십시오.

3. Node.js (discord.js)

파일:상세 내용 아이콘.svg   자세한 내용은 discord.js 문서
번 문단을
부분을
참고하십시오.

4. Java (JDA)

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

아래는 위키에 나와있는 간단한 예시 코드이다.
#!syntax java
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 예시 코드이다.
#!syntax csharp
using System;
using System.Threading.Tasks;
using Discord;
using Discord.WebSocket;

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

        public Program()
        {
            var config = new DiscordSocketConfig()
            {
                GatewayIntents = GatewayIntents.All
            };
            _client = new DiscordSocketClient(config);

            _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($"{_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)

#!syntax go
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. C++ (DPP)

#!syntax cpp
#include <dpp/dpp.h>
#include <cstdlib>

int main() {
	dpp::cluster bot(std::getenv("BOT_TOKEN"));

	bot.on_slashcommand([](auto event) {
		if (event.command.get_command_name() == "ping") {
			event.reply("Pong!");
		}
	});

	bot.on_ready([&bot](auto event) {
		if (dpp::run_once<struct register_bot_commands>()) {
			bot.global_command_create(
				dpp::slashcommand("ping", "Ping pong!", bot.me.id)
			);
		}
	});

	bot.start(dpp::st_wait);
	return 0;
}

이곳에서 더 많은 샘플을 찾아볼 수 있다.

8. Bot Designer For Discord

8.1. 소개

디스코드 봇 제작/호스팅을 위한 해외 앱이다. Android/iOS 모두 사용 가능하다. 개발언어는 BDScript이며, 이름을 따온듯 한다.

웹버전도 있으며 https://botdesignerdiscord.com/app/home에서 확인 가능하다.

개발 언어로 위에서 소개한 Javascript도 지원하니 시도해볼 수 있다.

8.2. 만드는 방법

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

8.3. 코드 예시

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

$nomention

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

예를들어 사용자명이 namuwiki이라면 안녕하세요 namuwiki님! 또는 namuwiki님 안녕하세요! 중에 하나를 랜덤으로 반응한다, 태그는 따로 입력하는 코드가 있지만 $username만 쓰면 이름만 입력된다, Discord 새로운 사용자명 업데이트로 지금은 태그 코드를 사용하면 태그가 0으로 나온다.

$nomention

$title[안녕하세요! 임베드입니다!]
$description[$username님의 유저 ID는 $authorID 이군요!]
$color[ffffff]

이렇게 코드를 작성하면 임베드 타이틀은 $title이, 설명에는 $description이 들어가게 되고 임베드의 색상은 하얀색 ( hexcode #ffffff ) 가 나온다. $description을 디스코드에서 보게되고 만약에 유저 ID가 0001이라면, " namuwiki님의 유저 ID는 0001 이군요! " 가 입력된다.

9. Discord API

디스코드 공식 API를 직접 이용해 봇을 만들 수 있다. 위에 나와있는 비공식 라이브러리들을 안 쓰고 작동 기반을 직접 만든다고 보면 된다.

이걸로 라이브러리를 만들거나[2] 앱을 만들 수 있다. 하지만 공식 API특성상 초보들한텐 추천하지 않는다.[3]

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

다만 바꿔말하자면 HTTP통신과 웹소켓, 비동기에 관한 공부만 끝마친다면 어느정도의 센스와 함께 시행착오를 거치며 도전할 수 있는 주제라는 것이다. 사실 웹사이트나 매크로 등(심지어는 어플 하나만 만들려고 해도 디버깅에 통신은 필수다...)에 조금만 손을 대봤다면 알듯이 통신 관련 기능에 접근하려면 기본적으로 저러한 개념들을 알아야 가능하다.[6] 거기에 비동기는 거의 모든 프로그램들이 실용성을 가지게 만들어주는데 무조건적으로 필요한 개념일 정도.

각 프로그래밍 언어에서 기본 메서드나 함수만을 배운 사람들한테는 어려울 수 있어도, 어느정도 노하우를 갖춘 사람들과 모르는 것들을 직접 찾아보며 자신만의 기능을 가진 프로그램을 만들어보려 노력하는 사람들에게는 울고 웃으며 경험을 쌓을 수 있는 크나큰 기회다.[7] 으레 그렇듯이 어려운 문제일수록 해결과정 동안 기초적인 개념부터 어려운 응용까지 깊이 이해할 수 있다는 장점을 가지므로 너무 떨지말고 한번 도전해보는 것도 추천한다.

10. Discord Bot Maker

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

https://store.steampowered.com/app/682130/Discord_Bot_Maker/

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

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

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



파일:CC-white.svg 이 문단의 내용 중 전체 또는 일부는 문서의 r11에서 가져왔습니다. 이전 역사 보러 가기
파일:CC-white.svg 이 문단의 내용 중 전체 또는 일부는 다른 문서에서 가져왔습니다.
[ 펼치기 · 접기 ]
문서의 r11 (이전 역사)
문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

문서의 r (이전 역사)

11. 봇 인증

디스코드 봇을 사용하는 서버가 기본 한도인 100서버를 넘어갈 경우 디스코드 개발팀의 인증을 요구한다. 개발자의 신원 확인, 제공하는 기능, 수집하는 개인정보, 이용약관 및 개인정보보호정책 제공 등의 설문에 답변 후 디스코드 개발팀의 검토를 받게된다.
https://support.discord.com/hc/en-us/articles/360040720412-Bot-Verification-and-Data-Allowlisting

공식 인증된 봇은 더이상 봇 이름을 바꿀 수 없게된다. 만약 사용자 수가 빠른 시일내에 100명을 돌파하게된다면 의심스러운 성장으로 분류되어 한도가 250서버로 늘린 후 한 달 동안은 인증을 진행할 수 없게된다. 하지만 한 달 후에는 정상적으로 인증 과정을 진행할 수 있다. 디스코드 봇이 임의로 대량 생성한 서버 여러곳에 들어가는 등 비정상적인 방법으로 참여중인 서버를 늘리는 경우 비정상적 성장으로 간주되어 해당 봇의 인증 자격이 박탈된다.

봇이 디스코드의 운영정책을 위반하는 경우 봇 인증은 거절된다. 이미 인증을 거절당한 봇은 어떠한 경우에도 더 이상 인증을 받을 수 없게되며, 새로운 봇을 만드는 경우에만 인증 절차를 밟을 수 있다. 다만 인증 자격을 박탈당하거나 신청 후 거절 당하더라도 해당 봇의 서비스 종료가 이루어지는것은 아니다.[10] 봇이 유튜브 음악 재생 기능을 포함하는 경우 디스코드 운영정책 위반으로 간주되어 인증을 거절당한다. 이미 인증을 받은 봇들도 상당수가 유튜브 음악 재생 기능을 제거하거나 봇의 서비스를 종료하는중이다.

12. 봇 호스팅

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

분류