초기 편지 기능 구축

This commit is contained in:
tmddn3070 2023-11-26 13:27:34 +09:00
parent a6fcd2b1f6
commit 3ec23b9525
11 changed files with 148 additions and 51 deletions

View File

@ -1,7 +1,7 @@
from discord import Member, SlashCommandGroup, Option from discord import Member, SlashCommandGroup, Option
from discord.ext.commands import Cog, cooldown, BucketType, command, has_permissions, bot_has_permissions, Context, guild_only, bot_has_guild_permissions, check from discord.ext.commands import Cog, cooldown, BucketType, command, has_permissions, bot_has_permissions, Context, guild_only, bot_has_guild_permissions, check
from Christmas.UI.Modal import Send_Mail_Modal
class CMail(Cog): class CMail(Cog):
def __init__(self, bot): def __init__(self, bot):
@ -12,9 +12,9 @@ class CMail(Cog):
@MAIL.command(name="보내기", description="편지를 보냅니다.") @MAIL.command(name="보내기", description="편지를 보냅니다.")
@cooldown(1, 10, BucketType.user) @cooldown(1, 10, BucketType.user)
@guild_only() @guild_only()
async def _send(self, ctx: Context, member: Option(Member, name="member", description="편지를 받을 사람을 선택해주세요.", required=True)): async def _send(self, ctx: Context, member: Option(Member, name="보낼사람", description="편지를 받을 사람을 선택해주세요.", required=True)):
modal = Send_Mail_Modal(reciveuser=member, title="편지 보내기")
await ctx.send_modal(modal)
def setup(bot): def setup(bot):
bot.add_cog(CMail(bot)) bot.add_cog(CMail(bot))

View File

@ -0,0 +1,13 @@
from discord import Member, SlashCommandGroup, Option
from discord.ext.commands import Cog, cooldown, BucketType, command, has_permissions, bot_has_permissions, Context, guild_only, bot_has_guild_permissions, check
class CMusic(Cog):
def __init__(self, bot):
self.bot = bot
def setup(bot):
bot.add_cog(CMusic(bot))

View File

@ -1,18 +1,24 @@
from discord import ApplicationContext, DiscordException from discord import ApplicationContext, DiscordException, slash_command
from discord.ext.commands import Cog from discord.ext.commands import Cog, cooldown, BucketType, has_permissions, guild_only, Context
from Christmas.UI.Embed import Default_Embed
from Christmas.Database import database
class CUtil(Cog): class CUtil(Cog):
def __init__(self, bot): def __init__(self, bot):
self.bot = bot self.bot = bot
@guild_only()
@has_permissions(administrator=True)
@Cog.listener() @cooldown(1, 10, BucketType.user)
async def on_application_command_error(ctx: ApplicationContext, exception: DiscordException) -> None: @slash_command(name="서버가입", description="서버에 가입합니다.")
pass async def _join(self, ctx: Context):
try:
await database.register_guild(ctx.guild.id)
await ctx.respond(embed=Default_Embed.register_sucess())
except Exception as e:
await ctx.respond(embed=Default_Embed.register_failed())
def setup(bot): def setup(bot):

View File

@ -1,6 +1,10 @@
from discord import ApplicationContext, DiscordException, Game import random
from discord import ApplicationContext, DiscordException, Game, Guild
from discord.ext.commands import Cog from discord.ext.commands import Cog
from Christmas.UI.Embed import Default_Embed
class Event(Cog): class Event(Cog):
@ -9,14 +13,19 @@ class Event(Cog):
@Cog.listener() @Cog.listener()
async def on_application_command_error(ctx: ApplicationContext, exception: DiscordException) -> None: async def on_application_command_error(self, ctx: ApplicationContext, exception: DiscordException) -> None:
pass print(exception)
@Cog.listener() @Cog.listener()
async def on_ready(self): async def on_ready(self) -> None:
print("Ready!") print("Ready!")
await self.bot.change_presence(activity=Game(name="크리스마스에 함께!")) await self.bot.change_presence(activity=Game(name="크리스마스에 함께!"))
@Cog.listener()
async def on_guild_join(self, guild: Guild) -> None:
if guild.system_channel is not None:
await guild.system_channel.send(embed=Default_Embed.guild_join())
else:
await random.choice(guild.text_channels).send(embed=Default_Embed.guild_join())
def setup(bot): def setup(bot):
bot.add_cog(Event(bot)) bot.add_cog(Event(bot))

View File

@ -2,11 +2,39 @@ from motor.motor_asyncio import AsyncIOMotorClient
from Christmas.config import ChristmasConfig from Christmas.config import ChristmasConfig
class MongoDBClient:
class database(AsyncIOMotorClient):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.config = ChristmasConfig() self.config = ChristmasConfig()
self.db = self( self.config.DATABASE["HOST"], self.config.DATABASE["PORT"], username=self.config.DATABASE["USERNAME"], password=self.config.DATABASE["PASSWORD"])[self.config.DATABASE["DATABASE"]] self.client = AsyncIOMotorClient(self.config.DATABASE["HOST"], int(self.config.DATABASE["PORT"]), username=self.config.DATABASE["USERNAME"], password=self.config.DATABASE["PASSWORD"])[self.config.DATABASE["DATABASE"]]
async def connect(self):
return self.client
class database:
async def get_guild(guild_id: int) -> dict:
conn = await MongoDBClient().connect()
return await conn.guild.find_one({"_id": guild_id})
async def register_guild(guild_id: int) -> None:
conn = await MongoDBClient().connect()
await conn.guild.insert_one({"_id": guild_id})
async def insert_mail(send_user_id: int, user_id: int, mail_title: str, mail_content: str):
try:
conn = await MongoDBClient().connect()
mail_title = f"""{mail_title}"""
mail_content = f"""{mail_content}"""
if await conn.mail.find_one({"_id": user_id}) == None:
await conn.mail.insert_one({"_id": user_id, "mails": [{"userid": send_user_id, "title": mail_title, "content": mail_content}]})
else:
await conn.db.mail.update_one({"_id": user_id}, {"$push": {"mails": {"userid": send_user_id, "title": mail_title, "content": mail_content}}})
except Exception as e:
print(e)
async def get_mail(user_id: int) -> dict:
conn = await MongoDBClient().connect()
return await conn.mail.find_one({"_id": user_id})

View File

@ -1,14 +1,28 @@
from discord.ui import View, button from discord.ui import View, button
from discord import Interaction, ButtonStyle, Embed, Color, TextChannel, Forbidden, Message, Member, User, File, HTTPException from discord import Interaction, ButtonStyle, Embed, Color, TextChannel, Forbidden, Message, Member, User, File, HTTPException
from Christmas.UI.Embed import Mail_Embed
from Christmas.Database import database
class Mail_Confirm_Button(View): class Mail_Confirm_Button(View):
def __init__(self, recive_user: Member, *args, **kwargs): def __init__(self, recive_user: Member, title: str, description: str, *args, **kwargs):
self.recive_user = recive_user self.recive_user = recive_user
self.title = title
self.description = description
super().__init__(timeout=None) super().__init__(timeout=None)
@button(label="전송", style=ButtonStyle.green, custom_id="mail_send") @button(label="전송", style=ButtonStyle.green, custom_id="mail_send")
async def send(self, button, interaction: Interaction): async def send(self, button, interaction: Interaction):
await interaction.response.defer() await interaction.response.defer()
if await database.get_guild(interaction.guild.id) == None:
await interaction.edit_original_response(embed=Embed(title="❌ 에러!", description="서버가 가입되어있지 않아요! 서버에 가입해주세요!"), view=None)
return
else:
await database.insert_mail(interaction.user.id, self.recive_user.id, self.title, self.description)
await interaction.edit_original_response(embed=Mail_Embed.mail_sended(receive_user=self.recive_user), view=None)
@button(label="취소", style=ButtonStyle.red, custom_id="mail_cancel")
async def cancel(self, button, interaction: Interaction):
await interaction.response.defer()
await interaction.edit_original_response(embed=Embed(title="✅ 전송취소!", description="편지 전송을 취소했어요!"), view=None)

View File

@ -21,25 +21,53 @@ class ChristmasEmbed(Embed):
timestamp=timestamp, timestamp=timestamp,
) )
def set_footer(self, *, text: Any | None = "크돌이", icon_url: Any | None = None) -> None: def set_footer(self, *, text: Any | None = "크돌이", icon_url: Any | None = "https://discord.com/assets/6dbfff5aae6b1de2b83f.svg") -> None:
super().set_footer(text=text, icon_url=icon_url) super().set_footer(text=text, icon_url=icon_url)
class Default_Embed:
@staticmethod
def default_join_embed():
embed = ChristmasEmbed(title="🎉 크돌이를 추가해주셔서 감사해요!", description="봇을 사용하기 전에 이 서버의 관리자라면 다음의 절차를 따라주세요!")
embed.add_field(name="1. 약관 동의", value="다음의 약관을 읽고 ``/서버 가입``명령어를 실행해주세요", inline=False)
embed.add_field(name="2. 설정", value="``/설정`` 명령어를 통해 크돌이의 여러 기능을 설정할수 있어요!", inline=False)
embed.add_field(name="3. 도움말", value="``/도움말`` 명령어를 통해 크돌이의 명령어를 확인할 수 있어요!", inline=False)
embed.set_footer()
return embed
@staticmethod
def register_sucess():
embed = ChristmasEmbed(title="🎉 가입 성공!", description="서버가입을 성공했어요!")
embed.add_field(name="안내", value="이제 크돌이를 즐겨보세요!", inline=False)
embed.set_footer()
return embed
@staticmethod
def register_failed():
embed = ChristmasEmbed(title="❌ 가입 실패!", description="서버가입을 실패했어요!")
embed.add_field(name="안내", value="알수없는 오류로 인해 가입에 실패했어요! 이 현상이 지속된다면 서비스 서버에 문의해주세요!", inline=False)
embed.set_footer()
return embed
class Mail_Embed: class Mail_Embed:
@staticmethod @staticmethod
def mail_confirm(title: str, description: str) -> Embed: def mail_confirm(title: str, description: str, receive_user: Member) -> Embed:
embed = ChristmasEmbed(title="⚠️|전송전 확인", description="메일을 정말로 전송하시겠습니까?") embed = ChristmasEmbed(title="⚠️ 전송전 확인", description="편지를 정말로 전송하시겠습니까?")
embed.add_field(name="⚠️ 주의사항 ⚠️", value="메일은 한 번 전송하면 취소할 수 없어요!\n 내용을 잘 읽고 ``전송``버튼을 눌러주세요!") embed.add_field(name="⚠️ 주의사항 ⚠️", value="편지는 한 번 전송하면 취소할 수 없어요!\n 내용을 잘 읽고 ``전송``버튼을 눌러주세요!", inline=False)
embed.add_field(name="받는이", value="크돌이 ⛄") embed.add_field(name="받는이", value=f"{receive_user.mention}", inline=False)
embed.add_field(name="제목", value=title) embed.add_field(name="제목", value=title, inline=False)
embed.add_field(name="내용", value=description) embed.add_field(name="내용", value=description, inline=False)
embed.set_footer() embed.set_footer()
return embed return embed
@staticmethod @staticmethod
def mail_sended(receive_user: Member) -> Embed: def mail_sended(receive_user: Member) -> Embed:
embed = ChristmasEmbed(title="✅|전송완료!", description="메일을 전송을 완료했어요!") embed = ChristmasEmbed(title="✅ 전송완료!", description="편지 전송을 완료했어요!")
embed.add_field(name="안내", value="보낸 메일은 2023년 12월 25일부터 열람 가능해요") embed.add_field(name="안내", value="보낸 편지는 2023년 12월 25일부터 열람 가능해요", inline=False)
embed.add_field(name="받는이", value=f"{receive_user.mention}") embed.add_field(name="받는이", value=f"{receive_user.mention}", inline=False)
return embed return embed

View File

@ -1,7 +1,7 @@
from discord import InputTextStyle, Interaction, Member from discord import InputTextStyle, Interaction, Member
from discord.ui import Modal, InputText from discord.ui import Modal, InputText
from Christmas.Module import check_curse #from Christmas.Module import check_curse
from Christmas.UI.Embed import Mail_Embed from Christmas.UI.Embed import Mail_Embed
from Christmas.UI.Buttons import Mail_Confirm_Button from Christmas.UI.Buttons import Mail_Confirm_Button
@ -10,11 +10,10 @@ class Send_Mail_Modal(Modal):
self.reciveuser = reciveuser self.reciveuser = reciveuser
super().__init__(timeout=None, *args, **kwargs) super().__init__(timeout=None, *args, **kwargs)
self.add_item(InputText("제목", placeholder="제목을 입력해주세요.", style=InputTextStyle.short, required=True, custom_id="mail_title")) self.add_item(InputText(label="제목", placeholder="제목을 입력해주세요.", style=InputTextStyle.short, required=True, custom_id="mail_title"))
self.add_item(InputText("내용", placeholder="내용을 입력해주세요.", style=InputTextStyle.long, required=True, custom_id="mail_content")) self.add_item(InputText(label="내용", placeholder="내용을 입력해주세요.", style=InputTextStyle.long, required=True, custom_id="mail_content"))
async def callback(self, interaction: Interaction): async def callback(self, interaction: Interaction):
await interaction.response.defer() await interaction.response.send_message(embed=Mail_Embed.mail_confirm(self.children[0].value, self.children[1].value, self.reciveuser), view=Mail_Confirm_Button(self.reciveuser, title=self.children[0].value, description=self.children[1].value),ephemeral=True)
await interaction.edit_original_message(embed=Mail_Embed.mail_confirm(self.items[0].value, self.items[1].value), view=Mail_Confirm_Button(self.reciveuser))

View File

@ -0,0 +1,4 @@

View File

@ -11,10 +11,7 @@ if __name__ == "__main__":
bot = Christmas( bot = Christmas(
command_prefix=commands.when_mentioned_or("c!"), command_prefix=commands.when_mentioned_or("c!"),
case_insensitive=True, case_insensitive=True,
allowed_mentions=commands.AllowedMentions( intents=Intents.all()
everyone=False, users=True, roles=False, replied_user=True
),
intents=Intents.all(),
) )
load_cogs(bot) load_cogs(bot)
apply_uvloop() apply_uvloop()

View File

@ -12,11 +12,10 @@ class Christmas(AutoShardedBot):
def __init__(self, *args: Any, **kwargs: Any): def __init__(self, *args: Any, **kwargs: Any):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.config = ChristmasConfig() self.config = ChristmasConfig()
self.debug_guilds = [1090621667778244638,1015236495910649926,957142859629342790,1125370139165081612,1170310470503247993]
def run(self, *args: Any, **kwargs: Any) -> None: def run(self, *args: Any, **kwargs: Any) -> None:
kwargs.update({"token": self.ctx.config.TOKEN}) kwargs.update({"token": self.config.TOKEN})
if self.config.MODE == "dev":
kwargs.update({"debug_guilds": [1090621667778244638,1015236495910649926,957142859629342790,1125370139165081612,1170310470503247993]})
super().run(*args, **kwargs) super().run(*args, **kwargs)
@ -25,7 +24,7 @@ def load_cogs(bot) -> None:
if filename == "__pycache__": if filename == "__pycache__":
continue continue
if filename.endswith(".py"): if filename.endswith(".py"):
bot.load_extension(f"Christmas.cogs.{filename[:-3]}") bot.load_extension(f"Christmas.Cogs.{filename[:-3]}")
def apply_uvloop() -> None: def apply_uvloop() -> None: