Heimdallr/commands/bot_messages.py

190 lines
5.6 KiB
Python
Raw Normal View History

from copy import deepcopy
import json
from json.decoder import JSONDecodeError
import logging
from naff import (
Client,
Extension,
slash_command,
slash_option,
InteractionContext,
Modal,
ParagraphText,
ModalContext,
context_menu,
Permissions,
CommandTypes,
Message,
)
from database import BotMessages as BotMessagesModel
message_creation_modal = Modal(
custom_id="bot-message-create",
title=f"Create a message as the bot",
components=[
ParagraphText(
custom_id="embeds",
label="Embeds",
placeholder="Embeds as JSON",
required=False,
),
ParagraphText(
custom_id="content",
label="Text",
placeholder="Lorem ipsum dolor sit amet and so on",
required=False,
),
]
)
class BotMessages(Extension):
def __init__(self, client: Client) -> None:
self.client = client
@slash_command(
name="bot-message-create",
description="Create a message as the bot.",
dm_permission=False,
default_member_permissions=Permissions.MANAGE_GUILD,
)
async def bot_message_create_command(self, ctx: InteractionContext):
await ctx.send_modal(message_creation_modal)
modal_ctx: ModalContext = await self.client.wait_for_modal(message_creation_modal, author=ctx.author)
if modal_ctx.custom_id != "bot-message-create":
return
embeds_string: str = modal_ctx.responses["embeds"]
content_string: str = modal_ctx.responses["content"]
if (
(embeds_string is None or embeds_string == "")
and (content_string is None or content_string == "")
):
await modal_ctx.send(
"You must provide either an embed or text.",
ephemeral=True,
)
return
embed: dict | None = None
embeds: list | None = None
try:
if embeds_string:
embeds_temp = json.loads(embeds_string)
if isinstance(embeds_temp, list):
embeds = embeds_temp
elif isinstance(embeds_temp, dict):
embed = embeds_temp
except JSONDecodeError:
await modal_ctx.send(
"The embeds were not valid JSON.",
ephemeral=True,
)
return
msg = await ctx.channel.send(
content=content_string if content_string else None,
embed=embed,
embeds=embeds,
)
BotMessagesModel.create(
guild_id=msg.guild.id,
channel_id=msg.channel.id,
message_id=msg.id,
)
await modal_ctx.send(
"Message created!",
ephemeral=True,
)
@context_menu(
name="Edit bot message",
context_type=CommandTypes.MESSAGE,
dm_permission=False,
default_member_permissions=Permissions.MANAGE_GUILD,
)
async def edit_bot_message_context_menu(self, ctx: InteractionContext):
message: Message = ctx.target
if message.author.id != self.client.user.id:
await ctx.send(
"This is not a bot message.",
ephemeral=True,
)
return
bot_message: BotMessagesModel | None = BotMessagesModel.get(
BotMessagesModel.guild_id == message.channel.guild.id,
BotMessagesModel.channel_id == message.channel.id,
BotMessagesModel.message_id == message.id,
)
if bot_message is None:
await ctx.send(
"This is not an editable bot message.",
ephemeral=True,
)
return
modal = deepcopy(message_creation_modal)
modal.title = "Edit bot message"
modal.components[0].value = json.dumps(
[e.to_dict() for e in message.embeds] if message.embeds else "",
indent=4,
)
modal.components[1].value = message.content
await ctx.send_modal(modal)
modal_ctx: ModalContext = await self.client.wait_for_modal(modal, author=ctx.author)
if modal_ctx.custom_id != "bot-message-create":
return
embeds_string: str = modal_ctx.responses["embeds"]
content_string: str = modal_ctx.responses["content"]
if (
(embeds_string is None or embeds_string == "")
and (content_string is None or content_string == "")
):
await modal_ctx.send(
"You must provide either an embed or text.",
ephemeral=True,
)
return
embed: dict | None = None
embeds: list | None = None
try:
if embeds_string:
embeds_temp = json.loads(embeds_string)
if isinstance(embeds_temp, list):
embeds = embeds_temp
elif isinstance(embeds_temp, dict):
embed = embeds_temp
except JSONDecodeError:
await modal_ctx.send(
"The embeds were not valid JSON.",
ephemeral=True,
)
return
await message.edit(
content=content_string if content_string else None,
embed=embed,
embeds=embeds,
)
await modal_ctx.send(
"Message edited!",
ephemeral=True,
)
def setup(client: Client):
BotMessagesModel.create_table()
BotMessages(client)
logging.info("BotMessages extension loaded")