2.파이썬을 이용한 디스코드 봇 만들기: discord.py API
discord.py API에 대해
지난 글에 이어서 이번에는 저희가 만들었던 코드에 대해 자세하게 알아보기 위해 discord.py
의 API에 대해 알아보겠습니다.
1. Bot 클래스
import discord
from discord.ext import commands
bot = commands.Bot(command_prefix='!')
먼저 discord.ext 라이브러리에 들어가보시면 아래와 같이 commands.Bot
클래스가 가지는 속성 값들이 매우 다양하게 존재하는것을 알 수 있습니다.
각각의 속성들은 사용자의 편의에 따라 설정해줄 수 있으므로 자신이 원하는 기능을 구현하고 싶을 경우 그 부분에 대해 알아보는것이 매우 중요합니다.
이때 저희가 알아볼것은 status
, activity
, help_command
입니다.
-
status
먼저status
는 말그대로 봇의 상태를 의미합니다. 이는 디스코드 사용자가 자신의 현재 상태를 설정하는 것과 동일한 기능입니다.
이처럼 디스코드에서의 상태는 4가지로 구분됩니다. 이때 상태는discord.Status
클래스이며 각각의 상태값은 아래와 같이 표현이 가능합니다.온라인
-> online자리 비움
-> idle다른 용무 중
-> dnd / do_not_disturb오프라인 표시
-> invisible오프라인
-> offline
봇의 상태를 적용하는것은 간단합니다. 저희가 설정하고 싶은 것은 봇의
status
이므로 봇의 인스턴스를 생성할 때discord.Status
클래스를 이용하여 설정해줄 수 있습니다.bot = commands.Bot(status=discord.Status.dnd) # 다른 용무 중
이때 오프라인 표시 인
invisible
의 경우 봇에게 적용하려면 기존의 방법과는 다르게 commands.Bot.change_presence 함수를 이용해야 합니다. 자세한 내용은 API를 참조하세요. -
activity
디스코드에서는 사용자가 어떤 활동을 하고있는지를 인식하여 다른 사용자들에게 표현할 수 있습니다. 이는 대부분하는 중
,듣는 중
,방송 중
과 같습니다.
모든 활동은discord.Activity
,discord.Game
또는discord.Streaming
클래스로 표현합니다.
여기서 저희는discord.Game
클래스로 현재 봇의 활동을 표현해보겠습니다.bot_activity = discord.Game(name='블로그 작성') bot = commands.Bot(activity=bot_activity)
-
help_command
discord.py 라이브러리에서는 봇의 명령어에 대한 help 명령어를 자동으로 지원합니다. 이는 간단히 어떤 명령어들이 사용 가능한지를 확인할 수 있을 뿐만 아니라 해당 명령어에 필요한 세부 조건들을 쉽게 알아볼 수도 있습니다. 간단하게help
또는help (명령어)
로 확인할 수 있습니다.하지만 봇을 개발하면서 직접 도움말 명령어를 자신의 입맛에 맞게 표현하고 싶을 경우에는
discord.py
에서 제공하는help
기능을 사용하지 않을 수 있습니다.bot = commands.Bot(help_command=None)
commands.HelpCommand
클래스를 통하여 discord.py에서 기본으로 제공하는 help 명령어를 수정하는것도 가능합니다. 관심있으신 분은 해당 API 문서를 참고하시기 바랍니다!
Context 클래스
두번째로 Context
에 대해 알아봅시다!
저희가 작성했던 봇의 명령어를 잠깐 보시면
@bot.command()
async def 안녕(ctx):
await ctx.send("반갑습니다")
이와 같이 봇의 명령어를 통해 ctx
라는 변수를 매개변수로 받는것을 알 수 있습니다. 이때의 ctx
가 바로 Context
를 의미합니다. commands.Context
클래스는 여러가지 값들을 가지고있기 때문에 이를 응용하여 여러 표현이 가능합니다.
@bot.command()
async def 안녕(ctx):
await ctx.send("{}이라고 하셨군요, 반갑습니다 {}님!".format(
ctx.message.content, ctx.author.name))
Context
가 중요한 이유는 모든 봇의 명령어들은 ctx
와 *args
를 매개변수로 받을 수 있기 때문입니다. 따라서 봇은 사용자의 ctx
를 통해 답장을 보낼 수 있는 것입니다!
3. Guild 클래스
다음으로 알아볼 것은 discord.Guild
클래스 입니다. 디스코드에서 길드는 디스코드의 서버를 의미합니다! 따라서 개인이 만든 각각의 디스코드 서버들을 길드로 표현한다고 생각하시면 됩니다.
discord.Guild
를 통해 디스코드 서버에 대한 다양한 데이터들에 접근이 가능합니다. 저희는 간단하게 현재 봇이 접속해있는 서버의 정보에 대해 알아보겠습니다.
@bot.command()
async def 정보(ctx):
members = [member.name for member in ctx.guild.members]
await ctx.send(
"{} 서버는 {} 서버이며 구성원은 {} 이고 총 {} 명입니다.".format(
ctx.guild.name,
ctx.guild.region,
members,
ctx.guild.member_count
)
)
이와 같이 디스코드 서버와 관련된 여러 정보들을 얻을 수 있으며 해당 API 문서에서 더 많은 정보를 찾으실 수 있습니다!
그러면 앞서 배운 discord.py
라이브러리의 여러 클래스들과 디스코드에서 제공하는 @bot.event
를 응용하여 봇에게 간단한 기능을 추가해보고 마무리 하겠습니다. 감사합니다!
@bot.event
async def on_voice_state_update(member, before, after):
if before.channel is None and after.channel is not None:
await member.guild.system_channel.send(
"{}님이 보이스 채널에 접속했습니다.".format(member.name)
)
부록.
1. 디스코드의 name
과 nick
의 차이
디스코드의 사용자들은 자신의 이름과 별개로 각각의 서버마다 자신의 별명을 설정할 수 있습니다. 따라서 디스코드 봇을 개발할때도 내가 유저의 이름을 표현할 것인지 별명을 표현할 것인지 구분지어야 합니다. 이는 discord.Member.name
또는 discord.Member.nick
으로 접근 가능합니다.
@bot.command()
async def 이름(ctx):
await ctx.send("이름: {}, 별명: {}".format(
ctx.author.name, ctx.author.nick))
만약 해당 사용자가 별명이 없는경우는
None
을 리턴합니다.
2. Intents의 필요성
앞서 코드를 예로 들겠습니다.
@bot.command()
async def 어드민(ctx):
await ctx.send("서버의 어드민은 {} 입니다.".format(
ctx.guild.owner
))
이 명령어는 해당 디스코드 서버의 주인이 누군지 출력하는 간단한 명령어입니다.
discord.Guild
클래스의 속성인 owner
를 통해 값에 접근하는것이지요.
하지만 기본적으로 이 속성값은 None을 리턴합니다. 이유가 무엇일까요?
discord.py
1.5 버전부터는 디스코드 봇에 대한 Intents(의도)를 명시해야 합니다. 하지만 이는 필수적인 것은 아니고 대부분의 경우는 Intents를 코딩하지 않아도 잘 작동합니다. 이것은 나의 봇이 어떤 행동을 할 것이고, 어떤 행동을 하지 않을 것인지를 문서화하는 것입니다.
하지만 이와 다르게 반드시 Intents를 명시해야 하는, Privileged Intents
가 존재합니다. 앞서 예로 든 코드처럼 discord.Guild.owner
와 같이 Privileged Intents
에는 두가지 경우가 있습니다.
PRESENCE INTENT
SERVER MEMBERS INTENT
Intents
를 명시하는 방법은 해당 API 문서에서 자세히 볼 수 있습니다. 간단하게 코드로 설명하자면
intents = discord.Intents.default()
intents.members = True
bot = commands.Bot(intents=intents)
이와 같이 코드를 통해 Intents
를 설정한후에 Discord Developer Portal에 접속하여 Bot에 자신이 사용할 Privileged Intents
를 체크해주면 됩니다.
댓글남기기