Examples - Discord Guild 기본
https://github.com/Rapptz/discord.py/blob/master/examples/app_commands/basic.py
원본 코드는 위 페이지를 참조.
실행 전 설정 사항
1. dico_token.py 파일 내부에 길드 ID 정보 추가(서버 ID)
디스코드에서 Guild는 일반적으로 ‘서버’를 의미하며, 이 ID 값을 확인하기 위해서는 본인이 서버장 역할을 가지고 있는 서버의 아이콘 → 마우스 우클릭 → 서버 ID 복사하기를 통해 ID 정보를 확인 할 수 있다.
dico_token.py라는 이름으로 파일 생성 후 다음과 같이 작성하여 사용했다.
2. 채널 ID도 token에 함께 추가.
과정은 위와 동일하며, 본인이 서버장 역할을 가지고 있는 서버 → 채팅 채널 마우스 우클릭 → 채널 ID 복사
위 코드에 원하는 이름으로 만들고 동일하게 사용.
해당 코드에는 길드와 관련된 기본적인 여러 기능들이 들어 있다.
서버 내에서 메시지를 보내거나 신고 기능, 기본적인 응답 기능들을 포함하고 있으며 슬래시 커맨드(’/’), context menu를 활성화 하여 사용할 수 있는 코드도 포함하고 있다.
해당 코드는 길드 멤버 전체가 사용 가능하도록 처리했기 때문에 권한 별로 사용하기 위해서는 따로 코드를 수정하거나 권한을 수정해줘야 한다.
async def setup_hook(self):
# This copies the global commands over to your guild.
self.tree.copy_global_to(guild=MY_GUILD)
await self.tree.sync(guild=MY_GUILD)
- setup_hook에는 봇이 로그인 한 다음 비동기 설정을 수행할 코드를 작성한다.
login() 에서 한 번만 호출되고, 다른 이벤트들이 전달되기 전에 호출되기 때문에 on_ready() 에서 설정하는 것보다 더 나은 솔루션이 될 수 있다. - copy_global_to 명령어를 통해 해당 길드에서 Global Commands를 사용할 수 있도록 설정한다.
- @client.tree.command() 어노테이션을 통해 해당 커맨드를 슬래시 커맨드로 사용할 수 있도록 설정한다.
- 여기서 MY_GUILD는 discord.object 로 위에서 작성한 guild_id 값을 호출하여 사용한다.
- 디스코드에서 / 를 입력하면 사진과 같이 커맨드가 표시된다.
Context Menu 기능
# This context menu command only works on members
@client.tree.context_menu(name='Show Join Date')
async def show_join_date(interaction: discord.Interaction, member: discord.Member):
# The format_dt function formats the date time into a human readable representation in the official client
await interaction.response.send_message(f'{member} joined at {discord.utils.format_dt(member.joined_at)}')
- context_menu 어노테이션이 붙어있는 경우 봇이 실행 중인 동안 서버 내 유저를 우클릭 → 앱 → [작성한 기능 이름]을 클릭하여 확인할 수 있다.
- 위 코드는 해당 유저가 언제 서버에 들어왔는지를 표시하는 기능 코드.
- 서버 내 유저 우클릭 → 앱 선택 시 표시되는 context menu에서 확인 가능하다.
- 해당 메뉴 클릭 시 언제 서버에 들어왔는지 메시지로 출력.
Context Menu - Message
# This context menu command only works on messages
# 해당 메뉴는 메시지를 우클릭 했을 때만 보여지는 기능.
# 길드에 권한을 가진 유저가 메시지를 신고하면, 해당 메시지가 설정한 채널에 embed 형식으로 전달됨.
@client.tree.context_menu(name='Report to Moderators')
async def report_message(interaction: discord.Interaction, message: discord.Message):
# We're sending this response message with ephemeral=True, so only the command executor can see it
await interaction.response.send_message(
f'Thanks for reporting this message by {message.author.mention} to our moderators.', ephemeral=True
)
# Handle report by sending it into a log channel
# 사용자가 설정한 channel ID에 해당하는 채널로 신고 리포트 메시지가 전송된다.
log_channel = interaction.guild.get_channel(channel3_id) # replace with your channel id
embed = discord.Embed(title='Reported Message')
if message.content:
embed.description = message.content
embed.set_author(name=message.author.display_name, icon_url=message.author.display_avatar.url)
embed.timestamp = message.created_at
url_view = discord.ui.View()
url_view.add_item(discord.ui.Button(label='Go to Message', style=discord.ButtonStyle.url, url=message.jump_url))
await log_channel.send(embed=embed, view=url_view)
- 사용자가 설정한 channel ID에 해당하는 채널로 신고 메시지 전송. (본인은 여러 채널을 만들어서 하나의 채널에 메시지가 가도록 설정)
- 위에 설명한 내용은 유저 클릭 → 메시지 → 앱 클릭 시 나타나는 Context Menu.
- report 클릭 시 접수되었다는 안내 메시지가 출력 되고, 설정해둔 채널에 메시지 전달
- Go to Message 클릭 시 해당 메시지가 있던 위치로 이동.
웹 개발 시 볼 수 있는 앵커와 같은 기능을 한다고 생각하면 된다.
전체 코드
from typing import Optional
import discord
from discord import app_commands
from dico_token import Token, guild_id, channel3_id
# Guild = 디스코드의 서버를 의미
# @client.tree.command() 함수를 이용하면 디스코드 슬래시 커맨드에 등록하여 사용할 수 있도록 처리
MY_GUILD = discord.Object(id=guild_id) # replace with your guild id
class MyClient(discord.Client):
def __init__(self, *, intents: discord.Intents):
super().__init__(intents=intents)
# A CommandTree is a special type that holds all the application command
# state required to make it work. This is a separate class because it
# allows all the extra state to be opt-in.
# Whenever you want to work with application commands, your tree is used
# to store and work with them.
# Note: When using commands.Bot instead of discord.Client, the bot will
# maintain its own tree instead.
self.tree = app_commands.CommandTree(self)
# In this basic example, we just synchronize the app commands to one guild.
# Instead of specifying a guild to every command, we copy over our global commands instead.
# By doing so, we don't have to wait up to an hour until they are shown to the end-user.
async def setup_hook(self):
# This copies the global commands over to your guild.
self.tree.copy_global_to(guild=MY_GUILD)
await self.tree.sync(guild=MY_GUILD)
intents = discord.Intents.default()
client = MyClient(intents=intents)
@client.event
async def on_ready():
print(f'Logged in as {client.user} (ID: {client.user.id})')
print('------')
@client.tree.command()
async def hello(interaction: discord.Interaction):
"""Says hello!"""
await interaction.response.send_message(f'Hi, {interaction.user.mention}')
@client.tree.command()
@app_commands.describe(
first_value='The first value you want to add something to',
second_value='The value you want to add to the first value',
)
async def add(interaction: discord.Interaction, first_value: int, second_value: int):
"""Adds two numbers together."""
await interaction.response.send_message(f'{first_value} + {second_value} = {first_value + second_value}')
# The rename decorator allows us to change the display of the parameter on Discord.
# In this example, even though we use `text_to_send` in the code, the client will use `text` instead.
# Note that other decorators will still refer to it as `text_to_send` in the code.
@client.tree.command()
@app_commands.rename(text_to_send='text') # 파라미터 설명 부분에 표시되는 텍스트를 해당 이름으로 표시한다.
@app_commands.describe(text_to_send='Text to send in the current channel')
async def send(interaction: discord.Interaction, text_to_send: str):
"""Sends the text into the current channel."""
await interaction.response.send_message(text_to_send)
# To make an argument optional, you can either give it a supported default argument
# or you can mark it as Optional from the typing standard library. This example does both.
# 해당 멤버가 언제 서버에 들어왔는지를 명령어를 이용하여 보여준다.
@client.tree.command()
@app_commands.describe(member='The member you want to get the joined date from; defaults to the user who uses the command')
async def joined(interaction: discord.Interaction, member: Optional[discord.Member] = None):
"""Says when a member joined."""
# If no member is explicitly provided then we use the command user here
member = member or interaction.user
# The format_dt function formats the date time into a human readable representation in the official client
await interaction.response.send_message(f'{member} joined {discord.utils.format_dt(member.joined_at)}')
# A Context Menu command is an app command that can be run on a member or on a message by
# accessing a menu within the client, usually via right clicking.
# It always takes an interaction as its first parameter and a Member or Message as its second parameter.
# 아래에 작성한 코드들은 메뉴에 표시하도록 처리한 코드들.
# 메시지 또는 서버 내의 멤버를 마우스로 우클릭 했을 때 표시되는 context menu에서 확인 가능
# This context menu command only works on members
@client.tree.context_menu(name='Show Join Date')
async def show_join_date(interaction: discord.Interaction, member: discord.Member):
# The format_dt function formats the date time into a human readable representation in the official client
await interaction.response.send_message(f'{member} joined at {discord.utils.format_dt(member.joined_at)}')
# This context menu command only works on messages
# 해당 메뉴는 메시지를 우클릭 했을 때만 보여지는 기능.
# 길드에 권한을 가진 유저가 메시지를 신고하면, 해당 메시지가 설정한 채널에 embed 형식으로 전달됨.
@client.tree.context_menu(name='Report to Moderators')
async def report_message(interaction: discord.Interaction, message: discord.Message):
# We're sending this response message with ephemeral=True, so only the command executor can see it
await interaction.response.send_message(
f'Thanks for reporting this message by {message.author.mention} to our moderators.', ephemeral=True
)
# Handle report by sending it into a log channel
# 사용자가 설정한 channel ID에 해당하는 채널로 신고 리포트 메시지가 전송된다.
log_channel = interaction.guild.get_channel(channel3_id) # replace with your channel id
embed = discord.Embed(title='Reported Message')
if message.content:
embed.description = message.content
embed.set_author(name=message.author.display_name, icon_url=message.author.display_avatar.url)
embed.timestamp = message.created_at
url_view = discord.ui.View()
url_view.add_item(discord.ui.Button(label='Go to Message', style=discord.ButtonStyle.url, url=message.jump_url))
await log_channel.send(embed=embed, view=url_view)
client.run(Token)
반응형
'Discord > Discord Bot Python' 카테고리의 다른 글
디스코드 봇 - 유튜브 음악 재생 봇 설정 및 실행 방법 (1) | 2024.06.05 |
---|---|
Examples - Ephemeral, Confirm (0) | 2023.07.20 |
Discord 봇 만들기 - Link and Search (0) | 2023.06.21 |
Discord 봇 만들기 - Dropdown (0) | 2023.06.16 |
디스코드 봇 개발 시 Error 관련 (2) | 2023.05.30 |