[[분류:Discord/봇]] [include(틀:상위 문서, top1=Discord/봇)] [include(틀:Discord)] [목차] == 개요 == 다음은 디스코드 비공식 API로 봇을 만드는 방법, 예제를 나열한 것이다. 참고로 이 문서에 서술되어 있는 라이브러리는 전부가 아니다. Dart, elixir, swift, rust, lua, php 등등 정말 많은 라이브러리가 있으니 참고해보자.[[https://discordapp.com/developers/docs/topics/community-resources|#]] 여담으로 이러한 봇 외에도 자신만의 디스코드 클라이언트를 만들 수 있다.[* 다만 봇이 아닌 일반 계정으로 만든 봇에 로그인하는 것은 약관 위반이다.] == [[Python|파이썬]] ([[discord.py]]) == [[https://discordpy.readthedocs.io/en/latest/|공식 영문 문서]] 어떤 클래스, 메서드 등이 있는지는 [[https://github.com/Rapptz/discord.py|이 곳에서 볼 수 있다.]] 2021년 8월 28일, 개발 중단을 선언했으나([[https://gist.github.com/Rapptz/4a2f62751b9600a31a0d3c78100287f1|해당 공지]]), 2022년 3월 6일부로 discord.py의 개발이 재개되었다.[[https://gist.github.com/Rapptz/c4324f17a80c94776832430007ad40e6|#]] [[discord.py|이 문서에서]] 개요와 프로그래밍 방법을 더 자세히 볼 수 있다. 추가로 intents 기능은 [[https://discord.dev/|discord 개발자 웹사이트]]에서 Bot 항목 제일 하단에서 활성화 할 수 있다. 추추가로 intents 기능은 인증 봇이 되면 별도로 intents 사용 허가를 받아야 한다. 이 허가는 까다롭다 == [[Node.js]] ([[discord.js]]) == [[https://discord.js.org|디스코드 JS 패키지 문서]] [[https://discordjs.guide|영문 개발 가이드]] == [[Java]] ([[JDA]]) == JDA라는 라이브러리를 [[Maven]] 프로젝트 또는 [[Gradle]] 프로젝트에서 가져올 수 있다. 자세한 내용은 [[https://github.com/DV8FromTheWorld/JDA|여기]]를 참고하면 된다. 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(); } } } }}} == [[C##|C#]] (Discord.net) == [[https://github.com/discord-net/Discord.Net|Discord.net]]은 .Net Core 2.0 이상부터 지원한다. [[https://github.com/freyacodes/Lavalink|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 팀에서 [[https://github.com/discord-net/Discord.Net/tree/dev/samples|샘플]]하고 [[https://discord.foxbot.me/|문서]]를 제공하니 참고하자. == [[Go(프로그래밍 언어)|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!") } } }}} == Bot Designer For Discord == === 소개 === 디스코드 봇 제작/호스팅을 위한 해외 앱이다. Android/iOS 모두 사용 가능하다. 개발언어는 BDScript이며, 이름을 따온듯 한다. 웹버전도 있으며--(알파 버전이라서 불안정하고 기능이 없는건 함정)-- [[https://botdesignerdiscord.com/app/home]]에서 확인 가능하다. 공식 문서에서 다양한 코딩 단어 ( if, endif, 등등 ) 을 쓰는 방법과 설명을 해준다. 개발 언어로 위에서 소개한 Javascript도 지원하니 시도해볼 수 있다. 현재 한국어 번역이 어느정도 되었다. === 만드는 방법 === 우선 오른쪽의 "Create new bot'을 눌러 봇의 이름과 토큰을 입력한다. 우선 개발자 포털에서 앱을 만들어야 한다. 그렇게 봇이 제작되면 왼쪽 위 햄버거 메뉴를 누르고 Commands로 들어간다. 가운데 "Command creator"을 누르고 반응할 메세지를 입력한다.. === 코드 예시 === 아래는 직접 작성한 코드이다. $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 이군요! " 가 입력된다. == [[Discord/DiscordAPI|Discord API]] == 디스코드 공식 API를 직접 이용해 봇을 만들 수 있다. 위에 나와있는 비공식 라이브러리들을 안 쓰고 작동 기반을 직접 만든다고 보면 된다. 이걸로 라이브러리를 만들거나,[* 위에 있는 비공식 라이브러리는 이 공식 API를 이용해서 제작되었다.] 앱을 만들 수 있다. 하지만 공식 API특성상 초보들한텐 추천하지 않는다.[* 공식 API를 이용하려면 최소한 웹소켓, HTTP 통신을 알아야 한다.] 왜냐하면 디스코드 API는 많이 복잡하기 때문이다. 봇이 웹소켓 통신을 시작하면 JSON 데이터로 OP코드, 토큰, 라이브러리 등 정보를 보내야하고[* Identify를 전송하는 것이다.], 또 봇이 켜져있게 하고 웹소켓을 계속 연결하고 싶다면 일정한 주기로 Heartbeat를 보내야 하는데 또 이건 멀티 스레딩 또는 비동기를 모르는 사람에게는 불가능한 일이다. 심지어 디스코드에선 랜덤하게 Reconnect코드를 보내는데 이러면 아까 Identify 데이터에 최근 시퀀스 숫자까지 보내야 한다. 정말 프로그래밍 입문자라면 거들떠도 보지않는걸 추천한다.[* 이게 끝이 아니다. 디스코드에서 서버를 확인하려면 특정 엔드포인트에서 REST API로 GET메서드를 보내고 메시지는 /channels/{channel id}/messages에 POST를 하는 등 아주 복잡하다. 심지어는 음성을 전달할 때 '''Opus 코덱으로 직접 인코딩하여''' 웹소켓으로 보내야한다.(...)] 다만 바꿔말하자면 HTTP통신과 웹소켓, 비동기에 관한 공부만 끝마친다면 어느정도의 센스와 함께 시행착오를 거치며 도전할 수 있는 주제라는 것이다. 사실 웹사이트나 매크로 등(심지어는 어플 하나만 만들려고 해도 디버깅에 통신은 필수다...)에 조금만 손을 대봤다면 알듯이 통신 관련 기능에 접근하려면 기본적으로 저러한 개념들을 알아야 가능하다.[* 다만 API문서에 나와있는 간단한 GET / POST 요청 정도는 봇 토큰만 있어도 간단한 웹 요청 클라이언트로도 가능하다] 거기에 비동기는 거의 모든 프로그램들이 실용성을 가지게 만들어주는데 무조건적으로 필요한 개념일 정도. 각 프로그래밍 언어에서 기본 메서드나 함수만을 배운 사람들한테는 어려울 수 있어도, 어느정도 노하우를 갖춘 사람들과 모르는 것들을 직접 찾아보며 자신만의 기능을 가진 프로그램을 만들어보려 노력하는 사람들에게는 울고 웃으며 경험을 쌓을 수 있는 크나큰 기회다.[* 또한 디스코드에 새 기능이 추가되면 공식 API에는 거의 바로 반영되지만, 비공식 라이브러리는 반영되는 데 시간이 걸리는 점도 있다. 이러한 이유로 디스코드의 새로운 기능을 사용하고 싶고 HTTP request는 아는데 웹소켓 부분에서 막히는 경우 비공식 라이브러리에 없는 기능만 직접 API에 request를 보내서 사용하기도 한다.] 으레 그렇듯이 어려운 문제일수록 해결과정 동안 기초적인 개념부터 어려운 응용까지 깊이 이해할 수 있다는 장점을 가지므로 너무 떨지말고 한번 도전해보는 것도 추천한다. == 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를 사용하는것을 추천한다.[* 아무래도 자바스크립트나 다른 코딩 언어에 비해 뒤쳐지는 부분이 없지않아 있다.][* 또한 Discord Bot Maker는 유료지만 Node.js는 무료라는 점도 있다.] [[GitHub]]에 Discord bot maker 전용 모드가 있는데 그걸 적용하면 디스코드에서 노래봇도 만들 수 있다. [include(틀:문서 가져옴, this=문단, title=디스코드 봇 메이커, version=11)] == 봇 인증 == 디스코드 봇을 사용하는 서버가 기본 한도인 100서버를 넘어갈 경우 디스코드 개발팀의 인증을 요구한다. 개발자의 신원 확인, 제공하는 기능, 수집하는 개인정보, 이용약관 및 개인정보보호정책 제공 등의 설문에 답변 후 디스코드 개발팀의 검토를 받게된다. [[https://support.discord.com/hc/en-us/articles/360040720412-Bot-Verification-and-Data-Allowlisting]] 공식 인증된 봇은 더이상 봇 이름을 바꿀 수 없게된다. 만약 사용자 수가 빠른 시일내에 100명을 돌파하게된다면 의심스러운 성장으로 분류되어 한도가 250서버로 늘린 후 한 달 동안은 인증을 진행할 수 없게된다. 하지만 한 달 후에는 정상적으로 인증 과정을 진행할 수 있다. 디스코드 봇이 임의로 대량 생성한 서버 여러곳에 들어가는 등 비정상적인 방법으로 참여중인 서버를 늘리는 경우 비정상적 성장으로 간주되어 해당 봇의 인증 자격이 박탈된다. 봇이 디스코드의 운영정책을 위반하는 경우 봇 인증은 거절된다. 이미 인증을 거절당한 봇은 어떠한 경우에도 더 이상 인증을 받을 수 없게되며, 새로운 봇을 만드는 경우에만 인증 절차를 밟을 수 있다. 다만 인증 자격을 박탈당하거나 신청 후 거절 당하더라도 해당 봇의 서비스 종료가 이루어지는것은 아니다.[* 대신 인증을 받지 못했기때문에 100~250서버의 한도는 뚫지 못한다.] 봇이 [[유튜브]] 음악 재생 기능을 포함하는 경우 디스코드 운영정책 위반으로 간주되어 인증을 거절당한다. 이미 인증을 받은 봇들도 상당수가 유튜브 음악 재생 기능을 제거하거나 봇의 서비스를 종료하는중이다.