discord.py | |
<colbgcolor=#fff,#1f2023><colcolor=#4b50c9> 최신 버전 | 2.3.2 |
필요 파이썬 버전 | 3.8 이상 |
상태 | 개발 중 |
| | |
[clearfix]
1. 개요
공식 영문 문서 한국어 번역본discord.py는 Python용 디스코드 봇 API를 사용하기 위해 가장 많이 사용되는 라이브러리들 중 하나이다. 대부분의 함수가 코루틴을 사용하여 코드가 효율적으로 작동하게 해준다는 장점이 있다.
추가로 intents 기능은 discord 개발자 웹사이트에서 Bot 항목 제일 하단에서 활성화 할 수 있다. 만일 인증 봇이 될 경우 별도로 intents 사용 허가를 받아야 한다.
2. 개발 중단 선언과 복귀
2021년 8월 28일, discord.py의 개발을 중단했다. 해당 입장문 개발을 중단한 이유를 정리하자면 다음과 같다.- 디스코드가 공식 API 문서를 공개[1]하면서 수많은 기능과 지원을 약속받음.
- 하지만 약속은 제대로 지켜지지 않았고 디스코드 직원들은 향후 3년 동안 라이브러리 개발자들의 피드백을 소홀히 함.
- 디스코드 API 서버는 직원들과 라이브러리 개발자들이 변경 사항에 대해 논의할 수 있는 곳이었으나, 시간이 지나면서 대화는 점점 단절되어 감.
- 그러던 중, 디스코드 직원들은 디스코드 API 서버 대신 Discord Infrastructure[2]에만 변경 사항을 공유하기 시작했다. 하지만 라이브러리 개발자들이 해당 서버에 초대를 받지 못함. [3]
- 문제는 라이브러리에 큰 영향을 받는 변경 사항을 위 서버의 개발자들과만 논의하였다는 것. 대부분의 라이브러리 개발자들은 이를 탐탁지 않게 여김.
- 2020년 4월 7일, 디스코드 블로그에 미래에 대한 계획이 발표됨. 여기에는 수많은 기능[4]과 봇 인증[5]이 공개됨.
- 봇 인증을 받기 위해서는 국가에서 발행한 신분증을 사용해야 하는데 개발자들은 개인정보를 침해한다고 반발했으나 검토가 이뤄지지 않음.
- 2020년 7월과 8월경, Discord Infrastructure에 슬래시 커맨드[6]에 대하여 이야기함.
- 문제는 슬래시 명령어를 도입하면서 기존에 쓰고 있는 메시지형 명령어[7] 기능이 제한된다.
- 업데이트가 된다면 이를 모두 슬래시 명령어로 바꿔야 하는데 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_commands
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_commands.command(name="침공보스")
async def ping(self, ctx: commands.Context) -> None:
await ctx.send("리브라사막 허니문, 되돌린로크광산 비슈")
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가 문제가 되고 있다.