이전글보기
[정보/Discord Bot] - [discord.py 2.0] 04. discord.py 라이브러리 설치하기
[정보/Discord Bot] - [discord.py 2.0] 05. 봇 기본설정하기
[정보/Discord Bot] - [discord.py 2.0] 06. 봇 명령어 추가하기
[정보/Discord Bot] - [discord.py 2.0] 07. 대화에 Embed 추가하기
[정보/Discord Bot] - [discord.py 2.0] 08. Embed 꾸미기
이번엔 Cogs를 통해 소스코드를 기능별로 나누어 관리하기 용이하도록 할겁니다.
Main.py 소스코드가 있는 폴더에 Cogs 폴더를 생성합니다
현재 작성된 코드의 동작이 ping 명령어 밖에 없지만.. ping이라도 분리해서 관리할 수 있도록 나눠보겠습니다.
Cogs 파일의 기본 구조는 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
|
import discord
from discord.ext import commands
class Ping(commands.Cog):
def __init__(self, app):
self.app = app
async def setup(app):
await app.add_cog(Ping(app))
|
cs |
5~7 : Main에서 호출할 클래스를 정의합니다.
10~11 : Main에서 호출 할 수 있도록 setup 메소드를 작성합니다.
그럼 위 기본 구조를 토대로 Ping기능이 포함된 Ping.py를 Cogs 폴더 아래에 생성해줍니다.
폴더구조는 다음과 같습니다
main.py가 있는 위치에 Cogs 폴더가 있고, 그 아래에 ping.py 를 생성하였습니다.
그리고 위에 입력한 기본 Cogs 코드와 Main에 있는 ping 명령어들을 ping.py 로 옮겨줍니다.
그럼 완성된 ping.py는 다음과 같습니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
import discord
from discord.ext import commands
class Ping(commands.Cog):
def __init__(self, app):
self.app = app
@commands.command()
async def ping(self, ctx):
await ctx.send('pong')
@commands.command(name="핑")
async def ping2(self, ctx):
embed = discord.Embed(title="ping pong", description="핑퐁", colour=0xffffff)
embed.set_author(name='Author name', icon_url="https://han.gl/XBMeC")
embed.set_footer(text="footer", icon_url="https://han.gl/XBMeC")
embed.set_image(url="https://han.gl/XBMeC")
embed.set_thumbnail(url="https://han.gl/XBMeC")
embed.add_field(name="필드1", value="inline false 필드1 내용", inline=False)
embed.add_field(name="필드2", value="inline false 필드2 내용", inline=False)
embed.add_field(name="필드3", value="inline True 필드3 내용", inline=True)
embed.add_field(name="필드4", value="inline True 필드4 내용", inline=True)
await ctx.reply('퐁', embed=embed)
async def setup(app):
await app.add_cog(Ping(app))
|
cs |
사용된 코드 설명
class Ping(commands.Cog):
def __init__(self, app):
self.app = app
5~7 : Ping 클래스를 선언합니다. 클래스의 이름은 본인 마음대로 변경하셔도 상관없습니다.
@commands.command()
async def ping(self, ctx):
await ctx.send('pong')
9 : @app.command() 에서 @commands.command() 로 변경되었습니다
10 : 기존엔 전역 메소드였으나, Ping 클래스의 메소드로 포함되었으므로, self 인자가 추가되었습니다.
@commands.command(name="핑")
async def ping2(self, ctx):
13 : @app.command(name="핑") 에서 @command.command(name="핑") 으로 변경되었습니다
14 : 함수명이 ping 이었으나 "async def ping(ctx)" 클래스 내에 동일한 이름의 메소드가 존재할 경우 정상적으로 동작하지 않아 메소드 이름을 변경하였습니다 "async def ping2(self, ctx). / 그외 self가 추가된 이유는 10 line과 같습니다
27~28 : Main에서 호출 할 수 있도록 정해진 메소드 setup 을 구현합니다.
이렇게 작성하면 ping.py 작성 및 준비는 끝났습니다.
Cogs의 요소를 작성했으니, 이제 Main에서 작성한 코드를 불러와야겠지요?
Main에서 app.start를 해주기 전에 cogs들을 로드 할 수 있도록 다음 동작을 추가합니다.
await app.load_extension(f"Cogs.ping")
그럼 main 메소드는 다음과 같이 되겠죠 !
async def main():
async with app:
await app.load_extension(f"Cogs.ping")
file = open("discord_token.txt")
bot_token = file.readline()
file.close()
await app.start(bot_token)
위 처럼 해주시면, 분리되어있는 ping.py 를 포함하여 Bot 이 동작하는것을 확인하실 수 있습니다.
Bot에 넣고싶은 기능이 한두가지가 아닌데, 하나씩 추가할때마다 일일히 넣긴 귀찮잖아요?
Cogs들을 알아서 불러올 수 있도록 소스코드를 추가해봅시다.
1
2
3
4
|
async def load_extensions():
for filename in os.listdir("Cogs"):
if filename.endswith(".py"):
await app.load_extension(f"Cogs.{filename[:-3]}")
|
cs |
async def load_extensions():
Cogs들을 load 하는 메소드를 하나 생성해줍니다.
for filename in os.listdir("Cogs"):
Cogs 디렉터리 안에 있는 모든 파일 내용을 읽어오는 반복문 입니다.
if filename.endswith(".py"):
# cut off the .py from the file name
await app.load_extension(f"Cogs.{filename[:-3]}")
.py로 끝나는 파일들을 모두 load_extension을 통해 호출합니다
완성된 main 소스코드는 다음과 같습니다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
import asyncio
import os
import discord
from discord.ext import commands
intents = discord.Intents.all()
app = commands.Bot(command_prefix='!', intents=intents)
async def load_extensions():
for filename in os.listdir("Cogs"):
if filename.endswith(".py"):
await app.load_extension(f"Cogs.{filename[:-3]}")
# cog 하나씩 불러오기
# activate_list = ["ping"]
# for name in activate_list:
# await app.load_extension(f"Cogs.{name}")
async def main():
async with app:
await load_extensions()
file = open("discord_token.txt")
bot_token = file.readline()
file.close()
await app.start(bot_token)
asyncio.run(main())
|
cs |
포스팅에 사용된 모든 소스코드는 아래 Github에서 확인하실 수 있습니다.
https://github.com/aochfl/ChoRi_TestBot
참고자료
https://discord.com/developers/docs/reference - ( Discord Developer API )
https://discordpy.readthedocs.io/en/latest/index.html - ( discord.py library 문서 )
'정보 > Discord Bot' 카테고리의 다른 글
[discord.py 2.0] 11. 메세지에 버튼 추가하기 (0) | 2022.09.10 |
---|---|
[discord.py 2.0] 10. Bot을 종료하지 않고 Cogs reload 하기 (0) | 2022.09.10 |
[discord.py 2.0] 08. Embed 꾸미기 (0) | 2022.09.07 |
[discord.py 2.0] 07. 대화에 Embed 추가하기 (0) | 2022.09.07 |
[discord.py 2.0] 06. 봇 명령어 추가하기 (0) | 2022.09.04 |