디스코드 봇을 사용해본 경험이 있다면, 유튜브 혹은 사운드 클라우드 등의 앱에서 음악을 재생해주는 봇을 사용해 봤을 수 있다.
여기서는 그러한 음악 재생 봇들의 기본이 될 수 있는 방법인 "봇을 음성 채널에 입장시키는 방법"을 설명해보려 한다.
** 음성 채널 입장의 기본 코드는 discord.py 깃허브를 참조했다.
https://github.com/Rapptz/discord.py/tree/master/examples
Basic - 음성 채널
- 음성 채널에 입장하는 봇을 사용하기 전, PyNaCl 설치 필요
- discord voice 확장 모듈도 설치 pip install discord.py[voice]
pip install PyNaCl
pip install discord.py[voice]
💡 만약 PyNaCl 오류가 발생하거나 설치가 되지 않는다면?
- CMD 관리자 권한으로 실행 → py -3 -m pip install -U discord.py[voice]
음성 채널 확인
print(ctx.author.voice)
- 해당 명령어는 명령어를 사용한 유저가 위치한 채널의 정보를 가져온다.
- 해당 채널의 이름, 아이디, 위치, 비트레이트, 사용자 수 제한 등의 정보를 가져 오고, 없다면 None을 반환한다.
print(ctx.author.voice.channel)
- 명령어를 사용한 유저가 위치한 채널의 이름을 가져온다.
- 해당 채널의 이름이 존재하지 않거나 없다면 아무것도 반환하지 않는다.
음성 채널 입장
@bot.command()
async def join(ctx):
if ctx.author.voice and ctx.author.voice.channel:
channel = ctx.author.voice.channel
await channel.connect()
else:
await ctx.send("음성 채널이 존재하지 않습니다.")
음성 채널 퇴장
@bot.command()
async def out(ctx):
await bot.voice_clients[0].disconnect()
소스 코드
import discord, asyncio
from discord.ext import commands
from dico_token import Token
# 수정. 2024.02.22
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(
command_prefix=commands.when_mentioned_or("!"),
description='디스코드 입장을 위한 테스트 코드',
intents=intents,
)
@bot.event
async def on_ready():
print('{0.user} 봇을 실행합니다.'.format(bot))
# 2024.08.24 수정.
@bot.command(aliases=['입장'])
async def join(ctx):
channel = ctx.author.voice.channel
if ctx.author.voice is None:
await ctx.send("사용자가 존재하는 음성 채널을 찾지 못했습니다. 음성 채널에 입장해주세요.")
raise commands.CommandInvokeError("사용자가 존재하는 음성 채널을 찾지 못했습니다.")
if ctx.voice_client is not None:
await ctx.send("봇이 사용자가 있는 채널에 입장합니다.")
print("음성 채널 정보: {0.author.voice}".format(ctx))
print("음성 채널 이름: {0.author.voice.channel}".format(ctx))
return await ctx.voice_client.move_to(channel)
await channel.connect()
# if ctx.author.voice and ctx.author.voice.channel:
# channel = ctx.author.voice.channel
# await ctx.send("봇이 {0.author.voice.channel} 채널에 입장합니다.".format(ctx))
# await channel.connect()
# print("음성 채널 정보: {0.author.voice}".format(ctx))
# print("음성 채널 이름: {0.author.voice.channel}".format(ctx))
# else:
# await ctx.send("음성 채널에 유저가 존재하지 않습니다. 1명 이상 입장해 주세요.")
@bot.command(aliases=['나가기'])
async def out(ctx):
# await bot.voice_clients[0].disconnect()
try:
await ctx.voice_client.disconnect()
await ctx.send("봇을 {0.author.voice.channel} 에서 내보냈습니다.".format(ctx))
except IndexError as error_message:
print(f"에러 발생: {error_message}")
await ctx.send("{0.author.voice.channel}에 유저가 존재하지 않거나 봇이 존재하지 않습니다.\\n다시 입장후 퇴장시켜주세요.".format(ctx))
except AttributeError as not_found_channel:
print(f"에러 발생: {not_found_channel}")
await ctx.send("봇이 존재하는 채널을 찾는 데 실패했습니다.")
bot.run(Token)
- 입장 명령어: !입장, !join
퇴장 명령어: !나가기, !out - 음성 채널에 유저가 존재하는 경우에만 봇을 불러올 수 있음.
- 코드 실행 종료 후에도 봇이 채널에 남아있는 경우 코드를 다시 실행할 때 봇을 찾지 못하는 에러가 발생.
- 해당 경우에는 봇을 재 입장 후 퇴장시키면 해결.
결과
Embed를 이용한 디스코드 봇 음성채널 구성
Embed
- discord python에서 제공하는 API
- 디스코드 메시지나 공지가 박스 형태로 표시되거나 이모지를 이용해 반응을 표시하는 등의 봇들을 본 경험이 있을 것.
- 다양한 색상, 제목, 내용 꾸미기, 인라인 기능 등을 제공한다.
소스 코드
import discord, asyncio
from discord.ext import commands
from dico_token import Token
# 수정. 2024.02.22
intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(
command_prefix=commands.when_mentioned_or("!"),
description='디스코드 입장을 위한 테스트 코드',
intents=intents,
)
@bot.event
async def on_ready():
print('{0.user} 봇을 실행합니다.'.format(bot))
# 2024 08 24 수정
@bot.command(aliases=['입장'])
async def join(ctx):
embed = discord.Embed(title = "디스코드 봇 도우미(개발용)", description = "음성 채널 개발용 디스코드 봇",color=0x00ff56)
channel = ctx.author.voice.channel
if ctx.author.voice is None:
embed.add_field(name=':exclamation:', value="음성 채널에 유저가 존재하지 않습니다. 1명 이상 입장해주세요.")
await ctx.send(embed=embed)
raise commands.CommandInvokeError("사용자가 존재하는 음성 채널을 찾지 못했습니다.")
if ctx.voice_client is not None:
embed.add_field(name=":robot:",value="사용자가 있는 채널로 이동합니다.", inline=False)
await ctx.send(embed=embed)
print("음성 채널 정보: {0.author.voice}".format(ctx))
print("음성 채널 이름: {0.author.voice.channel}".format(ctx))
return await ctx.voice_client.move_to(channel)
await channel.connect()
@bot.command(aliases=['나가기'])
async def out(ctx):
try:
embed = discord.Embed(color=0x00ff56)
embed.add_field(name=":regional_indicator_b::regional_indicator_y::regional_indicator_e:",value=" {0.author.voice.channel}에서 내보냈습니다.".format(ctx),inline=False)
await bot.voice_clients[0].disconnect()
await ctx.send(embed=embed)
except IndexError as error_message:
print(f"에러 발생: {error_message}")
embed = discord.Embed(color=0xf66c24)
embed.add_field(name=":grey_question:",value="{0.author.voice.channel}에 유저가 존재하지 않거나 봇이 존재하지 않습니다.\\n다시 입장후 퇴장시켜주세요.".format(ctx),inline=False)
await ctx.send(embed=embed)
except AttributeError as not_found_channel:
print(f"에러 발생: {not_found_channel}")
embed = discord.Embed(color=0xf66c24)
embed.add_field(name=":x:",value="봇이 존재하는 채널을 찾는 데 실패했습니다.")
await ctx.send(embed=embed)
bot.run(Token)
- 위의 메시지로 구성한 소스 코드를 Embed로 재 작성한 코드
- Embed의 Title, description을 설정해주지 않아도 Embed로 구성 가능
하지만 add_filed의 Name, value는 빈 값을 가질 수 없도록 구성되어 있다.
결과
반응형
'Discord > Discord Bot Python' 카테고리의 다른 글
Discord 봇 만들기 - Link and Search (0) | 2023.06.21 |
---|---|
Discord 봇 만들기 - Dropdown (0) | 2023.06.16 |
디스코드 봇 개발 시 Error 관련 (2) | 2023.05.30 |
Discord Bot 만들기 - 유튜브 음악 재생 봇 (16) | 2023.05.18 |
Discord Bot 만들기 - 초기 설정하기 및 API, 명령어 리스트 (0) | 2023.05.11 |