안녕하세요. 파이썬으로 discord.py 모듈을 사용해서 디스코드 봇을 개발하는 방법을 공유합니다. 사용자의 입력에 따라 행동하는 커맨드와 정해진 시간에 정기적으로 작동하는 기능을 가진 봇입니다.
혹시 글에서 잘못된 내용이 있거나 궁금하신 점이 있다면 말씀해 주세요!
Discord Developer Portal에 가입해서 애플리케이션 만들기
디스코드 봇을 개발하기 위해서는 우선 디스코드 개발자 포탈에 가입해서 애플리케이션(봇)을 만들고, 해당 애플리케이션의 토큰을 발급받아야 합니다. 아래의 사진과 같이, 해당 앱의 설정 - 봇 메뉴에서 Reset Token을 실행해서 토큰을 얻습니다. 이 토큰은 공유하지 마시고 노출되었다면 Reset Token으로 갱신해 주세요.
디스코드 봇을 내 채널에 초대하기
초대할 앱의 설정 - OAuth2 - URL Generator 메뉴에서 bot을 선택합니다. 개발할 bot에 필요한 기능들을 체크하고, 화면 하단에 보이는 GENERATED URL을 복사해서 브라우저에서 실행합니다. 그러면 봇을 초대할 디스코드 서버를 선택할 수 있습니다.
봇 명령어 개발하기
main.py
기본적인 봇의 실행과 관련된 main.py입니다.
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)
@bot.event
async def on_ready():
await bot.add_cog(HelloCommand(bot))
bot.run('YOUR_BOT_TOKEN')
4~5: intents는 bot이 사용할 기능과 관련된 옵션입니다. 사용자 입력에 따라 작동하는 기능을 개발하기 위해서 message_content를 True로 설정합니다.
6: bot의 명령어의 prefix를 정합니다. 만약 hello 명령어를 만들고 호출하려고 한다면, !hello를 입력하면 봇이 응답하게 됩니다.
8~10: bot이 실행되고 준비가 끝나면 실행되는 이벤트입니다. bot.add_cog 메서드로 명령어를 객체지향적으로 개발할 수 있습니다.
12: bot을 실행시키는 코드입니다. YOUR_BOT_TOKEN에 인자로 봇의 토큰을 입력해 주세요.
hello_command.py
봇의 hello 명령어와 관련된 hello_command.py입니다. 아래의 코드는 단일 명령어와 그룹 명령어 예제입니다.
class HelloCommand(commands.Cog):
def __init__(self, bot):
self.bot = bot
@commands.group(name='hello') # 그룹 명령어는 단독으로 호출할 수 없습니다.
async def hello_group(self, ctx: discord.ext.commands.Context):
if ctx.invoked_subcommand is None:
await ctx.send('그룹 명령어는 단독으로 실행될 수 없습니다.')
@hello_group.command(name='korean')
async def hello_korean(self, ctx):
# !hello korean 명령어에 대한 응답을 처리합니다.
await ctx.send('안녕하세요.')
@hello_korean.error
async def hello_korean_error(self, ctx, error):
# 이곳에서 hello_korean 명령어의 오류를 처리합니다.
await ctx.send(error)
@hello_group.command(name='english')
async def hello_english(self, ctx):
# !hello english 명령어에 대한 응답을 처리합니다.
await ctx.send('hello')
@commands.command(name='hi') # 단일 명령어는 단독으로 호출합니다.
async def hi(self, ctx):
# !hi 명령어에 대한 응답을 처리합니다.
await ctx.send('hi')
@commands.command(name='hii') # 명령어 외에 인자를 받을 수 있습니다.
async def hi_args(self, ctx, *args):
# args는 튜플 형태로 받습니다.
위의 코드와 같이 봇이 응답할 메시지는 ctx.send 메서드로 보낼 수 있습니다. 명령어는 그룹 명령어와 단일 명령어가 있는데, 그룹 명령어는 명령어를 조합해서 사용할 수 있고, 단일 명령어는 단독으로 사용할 수 있습니다. 그리고 명령어와 함께 추가 인자를 받고 싶다면 *args 가변 인자로 인자를 받아서 원하는 기능을 구현할 수 있습니다.
봇 정해진 시간에 작동시키기
my_task.py
매 시 40분과 45분에 원하는 일을 하고, 서버의 채널에 메시지를 보냅니다. asyncio.sleep의 인자는 초 단위이므로 현재는 1분마다 실행되는 함수입니다. 원하는 작업에 맞게 시간을 바꾸시면 됩니다.
async def my_task(bot: discord.ext.commands.Bot):
while True:
now = dt.now(datetime.timezone.utc)
if now.minute == 45 or now.minute == 40:
# 원하는 일을 합니다.
# 채널 객체 받아오기
test_channel = bot.get_channel('YOUR_CHANNEL_ID') # 채널ID는 int형으로 입력합니다.
await test_channel.send('정해진 시간에 작동합니다.')
await asyncio.sleep(60)
main.py
위의 main.py와 달라진 점은 bot.loop.create_task(my_task(bot)) 메서드를 실행하는 것입니다. 이 메서드로 task를 bot에 등록합니다.
import discord
from discord.ext import commands
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)
@bot.event
async def on_ready():
await bot.add_cog(HelloCommand(bot))
bot.loop.create_task(my_task(bot)) # task를 추가합니다.
bot.run('YOUR_BOT_TOKEN')
봇 24시간 작동시키기
저는 오라클 클라우드의 프리 티어 인스턴스를 사용해서 배포했습니다. 다만, 오라클 리눅스 8에서 파이썬 3.10 설치하는 방법을 찾을 수 없어서 3.9로 설치했습니다.
프리 티어 인스턴스를 생성하고, ssh로 접속합니다. 인스턴스에 파이썬을 설치하고 필요한 파이썬 모듈을 설치한 후에, scp로 작성한 봇 코드가 있는 폴더를 인스턴스로 복사했습니다. 아래는 파이썬 3.9 설치, ssh로 인스턴스에 접속하는 방법과 scp로 파일을 복사하는 방법입니다.
ssh와 scp로 인스턴스 접근하고 파일 복사하기
ssh -i key_file 유저이름@ip주소 # ssh 사용방법
scp -i key_file -r ../봇_코드_폴더 유저이름@ip주소:인스턴스_복사_경로 # scp 사용방법
파이썬 3.9 설치
# python 3.9 설치방법
sudo dnf update
sudo dnf install epel-release
sudo dnf install python39
sudo alternatives --set python /usr/bin/python3.9
python --version # 3.9가 나온다면 성공입니다
nohup으로 봇 백그라운드 프로세스로 실행하기
마지막으로 nohup을 사용해서 봇 코드를 백그라운드 프로세스로 실행합니다. 이러면 인스턴스와 세션이 끊어져도 인스턴스가 실행 중이라면 봇은 계속 실행됩니다. 아래의 명령어에서 파이썬 버전은 본인의 버전으로 입력해 주세요.
nohup python3.9 your_script.py &
이상으로 글을 마칩니다. 읽어주셔서 감사합니다. 다들 즐겁게 디스코드 봇 개발 하시길 바랍니다!