mir.pe (일반/밝은 화면)
최근 수정 시각 : 2024-03-17 04:44:12

discord.py

discord.py
파일:discord.py logo.png
<colbgcolor=#fff,#1f2023><colcolor=#4b50c9> 최신 버전 2.3.2
필요 파이썬 버전 3.8 이상
상태 개발 중
파일:홈페이지 아이콘.svg | 파일:GitHub 아이콘.svg 파일:GitHub 아이콘 화이트.svg | 파일:디스코드 아이콘.svg
1. 개요2. 개발 중단 선언과 복귀3. 제작
3.1. 제작 전3.2. discord.Client3.3. discord.ext.commands.Bot
3.3.1. discord.Client와 discord.ext.commands.Bot의 호환
3.4. 개발 중 및 유지
4. 업데이트
4.1. Discord.py 2.0
4.1.1. 기본 대화 및 출력

[clearfix]

1. 개요

공식 영문 문서 한국어 번역본

discord.py는 Python 디스코드 봇 API를 사용하기 위해 가장 많이 사용되는 라이브러리들 중 하나이다. 대부분의 함수가 코루틴을 사용하여 코드가 효율적으로 작동하게 해준다는 장점이 있다.

추가로 intents 기능은 discord 개발자 웹사이트에서 Bot 항목 제일 하단에서 활성화 할 수 있다. 만일 인증 봇이 될 경우 별도로 intents 사용 허가를 받아야 한다.

2. 개발 중단 선언과 복귀

2021년 8월 28일, discord.py의 개발을 중단했다. 해당 입장문 개발을 중단한 이유를 정리하자면 다음과 같다.
그러나 포크된 버전이 존재했기에 그쪽으로 넘어가는 사용자들도 있었다. Pycord nextcord
그러나 2022년 3월 6일, discord.py 개발을 다시 시작한다고 발표하며 discord.py 기반 봇들의 작동 중지 사태는 피하게 되었다. 해당 공지

3. 제작

3.1. 제작 전

먼저 Python을 설치해야 한다. 공식 웹사이트에서 가급적이면 최신 버전을 설치한다.[8]

설치가 완료 되었으면 Discord.py 라이브러리를 설치해야한다. #!syntax shell py -3 -m pip install -U discord.py[voice] 이 명령어를 윈도우 명령 프롬프트 혹은 Windows Terminal, 맥 OS 리눅스 터미널에 입력하여 설치한다.

설치가 완료되었다면, 이제 Discord.py를 사용할 수 있다.
#!syntax python import discord이 코드를 통해 불러올 수 있다.

3.2. discord.Client

2019년 정도만 해도, discord.py 강의는 1.0.0 이하의 버전[9]을 위주로 다루었다.

Client() 예제:
#!syntax python
import discord

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

@client.event
async def on_ready():
    print('Logged in as')
    print(client.user.name)
    print(client.user.id)
    print('------')

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

client.run('token')

3.3. discord.ext.commands.Bot

discord.Client를 사용하는 방법은 코드량이 많아질 수록 지저분해지고 세분 및 체계화가 어렵다. 이러한 점을 해결하기 위해 추가된게 discord.ext.commands.Bot이다.

github에 소개 되어있는 commands.Bot 예제:
#!syntax python
import discord
from discord.ext import commands

bot = commands.Bot(command_prefix='!')

@bot.event
async def on_ready():
    print('Logged in as')
    print(bot.user.name)
    print(bot.user.id)
    print('------')

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

bot.run('token')

API에 대해 이해도가 조금 쌓여있는 상태라면 commands.Bot이 훨씬 체계적이며 깔끔하고 유연하며, 쉽다는 것을 알 수 있다. 또한 cooldown, has_permission 등의 데코레이터가 만들어져 있어 개발 효율성도 좋으니 commands.Bot을 쓰는 것이 낫다.

3.3.1. discord.Client와 discord.ext.commands.Bot의 호환

discord.Client의 on_message에서 commands.Bot으로 마이그레이션할경우 원래의 on_message와 commands.Bot을 혼용 가능하다. 그러나 막상 코드를 합치고 실행시켜보면 on_message만 작동하며 나머지는 제대로 작동하지 않는 것을 발견할 수 있다[10]. 이는 `bot.process_commands(message)`를 on_message의 맨 마지막 줄에 붙여주면 잘 작동하는 것을 볼 수 있다.

3.4. 개발 중 및 유지

만약 정상적으로 작동했던 봇이 어느날 정상 작동이 되지 않는다면, discord.py의 버전을 체크해봐야한다. 업데이트되어 호환이 안되거나 구버전 및 상위 버전 함수를 사용해 오류가 날 가능성도 있다. 해결법은 전에 사용하던 버전으로 재설치하면 된다.

이건 discord.py를 사용하는 봇 외에 모두 공통으로 적용되는 점이지만, 봇 토큰을 타인에게 절대 노출하면 안된다. 봇 토큰은 각 봇들의 신분증처럼 연결중인 봇이 어떤 봇인가 증명하는 수단이다. 노출되어 문제가 발생한다면 누군가 내 껍데기를 뒤집어 씌고 본인인 것 마냥 행세하는 격의 일이 벌어질 수 있다.

개발을 시작할때부터 테스트를 염두에 두고 개발하는 것이 좋다. 봇 호스팅과 자신의 코드가 같이 실행될경우 개발 중 버그가 제3자에게 노출되어 문제가 생길수도 있으며 또한 호스팅에 바로 올려서 테스트하는경우 코드가 유실될 수 있기 때문이다[11].

commands.Bot에 어느 정도 익숙해진 경우, 유지보수를 위해 코드가 아주 간단한[12] 경우를 제외하면 Cog를 사용하는것을 매우 강력히 추천한다.

python 3.9 업데이트 관련해서 문제가 생겼다.
pip install discord.py
명령어를 입력하면, Falied to build yarl multidict라는 문구와 함께 다운로드에 실패한다. https://github.com/Rapptz/discord.py/discussions/5898
이는 파이썬이 3.9 버전으로 업데이트 하면서 생긴 wheels 제공 관련 문제로, [13] python 3.8로 다운그레이드하거나 MS visual c++ build tools 2015 이상을 설치하면 대부분 된다.

4. 업데이트

discord.py는 깃허브에서 개발되고 있으며, 릴리즈가 나올 때마다 pypl에 업데이트가 되는 식이다. 이에 따라 아직 정식 릴리즈에 추가 되지 않은 기능들을 미리 사용하려면 깃허브에서 git을 이용해 업데이트를 해야 한다.
업데이트 방법:
pip install -U git+https://github.com/Rapptz/discord.py.git
깃허브에 올라온 모듈을 그대로 업데이트시키는 명령이므로 (정식 릴리즈 판에 비해) 버그, 오류가 있을 수 있지만 아직 테스트 중인 기능들을 미리 사용해 볼 수 있다.

4.1. Discord.py 2.0

4.1.1. 기본 대화 및 출력

#!syntax python
import discord
from discord import app_command

intents = discord.Intents.default()
intents.message_content = True

class MyBot(commands.Bot):
    def __init__(self):
        super().__init__(
            command_prefix="!",
            intents=intents.all(),
            sync_command=True,
            application_id= #디스코드 봇의 application id를 입력한다.
        )
        
    async def setup_hook(self):
        await bot.tree.sync()

    async def on_ready(self):
        print("ready!")
        
        activity = discord.Game("상태 메세지")
        await self.change_presence(status=discord.Status.online, activity=activity)

    @app_command.command(name="ping")
    async def ping(self, ctx: commands.Context) -> None:
        await ctx.send("pong!")

bot = MyBot()
bot.run("token")

[1] 공개되지 않았을 때는 다른 개발자들과 함께 API를 리버스 엔지니어링하여 라이브러리를 작성하였다. [2] 해당 서버는 대형 봇 개발자들에게 인프라 상태를 공유하는 개인 서버였지만 곧 봇 개발자들과 소통하는 사실상 반공식 서버가 되었다. [3] 그나마 대형 봇 개발을 도운 2명의 라이브러리 개발자들이 초대받았다 [4] context 메뉴, 버튼, 임시 메시지 등 [5] 봇이 초대된 서버가 75개가 넘을 경우 봇 인증을 받을 수 있다. 인증되지 않은 봇은 최대 100개의 서버에만 초대할 수 있다. [6] /로 시작하는 명령어 시스템 [7] !ban >ban 과 같은 접두사 메시지 [8] 아니면 호환성을 위해 3.11 이하의 버전을 설치하는 게 좋다. [9] discord.Client만을 사용 [10] on_message의 무한반복이 commands의 실행을 막기 때문 [11] 유실은 깃허브로 해결이 가능하긴 하지만 그러지 않는 편이 좋다. [12] 명령어가 1~2개로 매우 적은 상황 등 [13] 의존성 라이브러리인 aiohttp, yarl, multidict가 문제가 되고 있다.