본문 바로가기
discord.py

[Discord.py] 디스코드 봇을 직접 만들어보자 #4-1 (modal)

by 뉴아뉴큐 2023. 8. 20.
반응형

 

디스코드 봇 개발 #1 (사전 준비)

https://newanewq.tistory.com/3

디스코드 봇 개발 #2 (Slash)

https://newanewq.tistory.com/4

디스코드 봇 개발 #3 (Embed)

https://newanewq.tistory.com/5

디스코드 봇 개발 #4-1 (modal)

https://newanewq.tistory.com/7

디스코드 봇 개발 #4-1 (Select Menu)

https://newanewq.tistory.com/9

https://newanewq.tistory.com/5

 

이번 편에서는 디스코드에서 modal 이라는 기능을 이용해서 사용자의 이름(닉네임)과

입대일/전역일을 받아 올 수 있도록 만들어 볼것이다.

 

이번 편을 작성하며 참고한 사이트이다.

https://discordpy.readthedocs.io/en/stable/interactions/api.html?highlight=modal#modal 

 

modal의 완성 모습을 보자면 아래와 같다. 

이번 편에서 구현할 modal 기능이다.

 

Part # 3-0 / 추가 전

본격적으로 modal을 구현하기 전 @bot.event 부분을 아래와 같이 수정해주자 

새로 추가된 코드의 기능은 봇을 실행할때 활성화 된 Slash Command의 개수를 출력해주는 기능이다. 

이렇게 추가를 해두면 command를 추가했을때 코드가 잘못된것인지 봇에 업데이트가 안됀것인지 쉽게 알 수 있다.

@bot.event
async def on_ready():
    print("봇 실행")
    synced = await bot.tree.sync()
    print("Slash Command " + str(len(synced)))

봇 샐행시의 모습

 

Part # 3-1 / modal 띄우기

 

자 이제 본격적으로 modal, 텍스트 입력창을 만들어보자 

우선 modal은 하나의 Class에서 양식을 만든 뒤 다른 Slash 명령어를 이용하여 호출해야만 한다. 

Slash 명령어가 아닌 접두사 명령어의 경우 이러한 이유때문에 modal을 호출할 수 없는것으로 알고 있다.

 

import discord
from discord.ext import commands
from discord import ui

먼저 상단의 모듈을 불러오는 부분에서 from discord import ui 부분을 추가해준다.

 

class MyModal(ui.Modal, title = "test 제목 필드 입니다."):
    name = ui.TextInput(label="여기는 1-1번 필드", placeholder="여기는 1-2번 필드", style=discord.TextStyle.short)
    name2 = ui.TextInput(label="여기는 2-1번 필드", placeholder="여기는 2-2번 필드", style=discord.TextStyle.long)
    name3 = ui.TextInput(label="여기는 3-1번 필드", placeholder="여기는 3-2번 필드", style=discord.TextStyle.short)

@bot.tree.command(name="modal")
async def modal(interaction: discord.Interaction):
    await interaction.response.send_modal(MyModal())

이후 해당 코드를 자신의 코드 중간정도에 끼워 넣어준다. 

(코드가 점점 길어짐에 따라 전체 코드는 글 맨 아래에 올려두도록 하겠다.)

추가한 코드는 class MyModal을 만들고 그 안 필드의 양식, 표시할 내용들을 지정해주었다.

 

아래의 @bot.tree.command 는 modal 이라는 명령어와 함수를 생성해 /modal 명령어를 사용해 

class MyModal을 불러올 수 있도록 만들었다.

 

한번 실행 결과를 보자

modal 실행 결과

실행시 위와 같은 양식이 나오게 된다. 

위의 코드와 비교해서 어떤 부분이 어디에 적용되는지 한번 직접 봐보자 long과 short의 차이도 볼 수 있다.

 

하지만 아직 사용자가 입력한 내용을 처리하는 부분을 만들지 않았기 때문에

창만 뜰 뿐 무언가를 입력해서 전송을 누른다면 오류가 발생할 것이다. 

전송시 오류가 발생한 모습

Part # 3-2 / 데이터 처리하기

MyModal Class를 아래와 같이 수정해보자

 

class MyModal(ui.Modal, title = "test 제목 필드 입니다."):
    name = ui.TextInput(label="여기는 1-1번 필드", placeholder="여기는 1-2번 필드", style=discord.TextStyle.short)
    name2 = ui.TextInput(label="여기는 2-1번 필드", placeholder="여기는 2-2번 필드", style=discord.TextStyle.long)
    name3 = ui.TextInput(label="여기는 3-1번 필드", placeholder="여기는 3-2번 필드", style=discord.TextStyle.short)

    async def on_submit(self, interaction: discord.Interaction):
        await interaction.response.send_message(f"1번 필드에는{self.name} 2번 필드에는{self.name2} 3번 필드에는{self.name3}")

추가한 부분은 단순하게 우리가 적어 전송한 값을 메세지로 출력해주는 코드이다. 

해당 부분을 응용하면 embed를 이용해 우리가 적은 값을 출력할 수 있을 것이니 한번 할 수 있다면 해보도록 하자.

 

위와 같이 입력 후 전송하면
이처럼 표시된다!

이제 받아온 값을 이용하여 여러가지를 할 수 있다. 

discord.py 사이트

위의 기능들을 보면 오늘 사용하지 않은 기능을 제외하고도 여러 기능들이 있다. 

모든 것을 이 블로그에서 설명하기는 어렵지만 오류가 났을때 처리하는 함수, 시간초과일때 처리하는 방법등을 코드에 넣는다면, 봇의 안정성이 올라갈 것이다.

 

이번 편에서는 modal을 이용해 값을 받아오고 함수로 값을 활용할 수 있는 방법까지 알아보았다.

다음 편에서는 json 파일을 생성해 user id와 받아온 값을 통해 저장하는 기능을 만들어 보도록 하겠다.

 

 

아래는 지금까지의 전체 코드이다.

#!/usr/bin/env python

import discord
from discord.ext import commands
from discord import ui
from discord.interactions import Interaction

bot = commands.Bot(command_prefix='|',intents=discord.Intents.all())

@bot.event
async def on_ready():
    print("봇 실행")
    synced = await bot.tree.sync()
    print("Slash Command " + str(len(synced))) 

@bot.tree.command(name="test1", description="test2")
async def test3(interaction: discord.Interaction):
    embed = discord.Embed(title="봇 정보", color=0x0000ff)
    embed.set_thumbnail(url="https://cdn.discordapp.com/attachments/1142466333401960660/1142480550146351326/image.png")
    embed.add_field(name="제작자", value="newAnewQ", inline=False)
    embed.set_author(name="여기는 1번 글", url="https://cdn.discordapp.com/attachments/1142466333401960660/1142480550146351326/image.png", icon_url="https://cdn.discordapp.com/attachments/1142466333401960660/1142480550146351326/image.png")
    embed.set_footer(text="여기는 2번 글")
    await interaction.response.send_message(embed=embed)


class MyModal(ui.Modal, title = "test 제목 필드 입니다."):
    name = ui.TextInput(label="여기는 1-1번 필드", placeholder="여기는 1-2번 필드", style=discord.TextStyle.short)
    name2 = ui.TextInput(label="여기는 2-1번 필드", placeholder="여기는 2-2번 필드", style=discord.TextStyle.long)
    name3 = ui.TextInput(label="여기는 3-1번 필드", placeholder="여기는 3-2번 필드", style=discord.TextStyle.short)

    async def on_submit(self, interaction: discord.Interaction):
        await interaction.response.send_message(f"1번 필드에는{self.name} 2번 필드에는{self.name2} 3번 필드에는{self.name3}")

@bot.tree.command(name="modal")
async def modal(interaction: discord.Interaction):
    await interaction.response.send_modal(MyModal())



bot.run('봇 토큰')

 

 

디스코드 봇 개발 #1 (사전 준비)

https://newanewq.tistory.com/3

디스코드 봇 개발 #2 (Slash)

https://newanewq.tistory.com/4

디스코드 봇 개발 #3 (Embed)

https://newanewq.tistory.com/5

디스코드 봇 개발 #4-1 (modal)

https://newanewq.tistory.com/7

디스코드 봇 개발 #4-1 (Select Menu)

https://newanewq.tistory.com/9

반응형

댓글