Introduces a new cog to manage Ko-fi shop orders, reviews, and waitlists. Users can submit orders and reviews via interactive modals. Administrators can configure channels and add users to the waitlist.
176 lines
8.0 KiB
Python
176 lines
8.0 KiB
Python
import discord
|
|
from redbot.core import commands, Config
|
|
from redbot.core.bot import Red
|
|
from typing import Optional
|
|
|
|
# --- Modals for the Commands ---
|
|
|
|
class OrderModal(discord.ui.Modal, title="Commission/Shop Order"):
|
|
def __init__(self, cog: "KofiShop"):
|
|
super().__init__()
|
|
self.cog = cog
|
|
|
|
comm_type = discord.ui.TextInput(label="What type of commission/item is this?")
|
|
payment_status = discord.ui.TextInput(label="Is this free or paid?")
|
|
description = discord.ui.TextInput(label="Please describe your request.", style=discord.TextStyle.paragraph)
|
|
questions = discord.ui.TextInput(label="Any questions for the artist?", style=discord.TextStyle.paragraph, required=False)
|
|
|
|
async def on_submit(self, interaction: discord.Interaction):
|
|
if not interaction.guild:
|
|
return await interaction.response.send_message("This must be used in a server.", ephemeral=True)
|
|
|
|
order_channel_id = await self.cog.config.guild(interaction.guild).order_channel()
|
|
if not order_channel_id:
|
|
return await interaction.response.send_message("The order channel has not been set by an admin.", ephemeral=True)
|
|
|
|
order_channel = interaction.guild.get_channel(order_channel_id)
|
|
if not isinstance(order_channel, discord.TextChannel):
|
|
return await interaction.response.send_message("The configured order channel is invalid.", ephemeral=True)
|
|
|
|
embed = discord.Embed(
|
|
title="New Order Placed",
|
|
description=f"Submitted by {interaction.user.mention}",
|
|
color=0x00ff00 # Green for new orders
|
|
)
|
|
embed.add_field(name="Item/Commission Type", value=self.comm_type.value, inline=False)
|
|
embed.add_field(name="Payment Status", value=self.payment_status.value, inline=False)
|
|
embed.add_field(name="Description", value=self.description.value, inline=False)
|
|
if self.questions.value:
|
|
embed.add_field(name="Questions", value=self.questions.value, inline=False)
|
|
|
|
try:
|
|
await order_channel.send(embed=embed)
|
|
await interaction.response.send_message("Your order has been successfully submitted!", ephemeral=True)
|
|
except discord.Forbidden:
|
|
await interaction.response.send_message("I don't have permission to send messages in the order channel.", ephemeral=True)
|
|
|
|
class ReviewModal(discord.ui.Modal, title="Leave a Review"):
|
|
def __init__(self, cog: "KofiShop"):
|
|
super().__init__()
|
|
self.cog = cog
|
|
|
|
item_name = discord.ui.TextInput(label="What item/commission are you reviewing?")
|
|
rating = discord.ui.TextInput(label="Rating (e.g., 10/10)")
|
|
review_text = discord.ui.TextInput(label="Your Review", style=discord.TextStyle.paragraph)
|
|
|
|
async def on_submit(self, interaction: discord.Interaction):
|
|
if not interaction.guild:
|
|
return await interaction.response.send_message("This must be used in a server.", ephemeral=True)
|
|
|
|
review_channel_id = await self.cog.config.guild(interaction.guild).review_channel()
|
|
if not review_channel_id:
|
|
return await interaction.response.send_message("The review channel has not been set by an admin.", ephemeral=True)
|
|
|
|
review_channel = interaction.guild.get_channel(review_channel_id)
|
|
if not isinstance(review_channel, discord.TextChannel):
|
|
return await interaction.response.send_message("The configured review channel is invalid.", ephemeral=True)
|
|
|
|
embed = discord.Embed(
|
|
title=f"New Review for: {self.item_name.value}",
|
|
description=f"Submitted by {interaction.user.mention}",
|
|
color=0xadd8e6 # Pastel Blue
|
|
)
|
|
embed.add_field(name="Rating", value=self.rating.value, inline=False)
|
|
embed.add_field(name="Review", value=self.review_text.value, inline=False)
|
|
|
|
try:
|
|
await review_channel.send(embed=embed)
|
|
await interaction.response.send_message("Thank you! Your review has been submitted.", ephemeral=True)
|
|
except discord.Forbidden:
|
|
await interaction.response.send_message("I don't have permission to send messages in the review channel.", ephemeral=True)
|
|
|
|
|
|
class KofiShop(commands.Cog):
|
|
"""
|
|
A cog to manage Ko-fi shop orders and reviews.
|
|
"""
|
|
|
|
def __init__(self, bot: Red):
|
|
self.bot = bot
|
|
self.config = Config.get_conf(self, identifier=5566778899, force_registration=True)
|
|
|
|
default_guild = {
|
|
"order_channel": None,
|
|
"review_channel": None,
|
|
"waitlist_channel": None
|
|
}
|
|
self.config.register_guild(**default_guild)
|
|
|
|
# --- Commands ---
|
|
@commands.hybrid_command()
|
|
@commands.guild_only()
|
|
async def order(self, ctx: commands.Context):
|
|
"""Place an order for a shop or commission item."""
|
|
if not ctx.interaction:
|
|
return
|
|
# We pass `self` (the cog instance) to the modal
|
|
await ctx.interaction.response.send_modal(OrderModal(self))
|
|
|
|
@commands.hybrid_command()
|
|
@commands.guild_only()
|
|
async def review(self, ctx: commands.Context):
|
|
"""Leave a review for a completed shop or commission item."""
|
|
if not ctx.interaction:
|
|
return
|
|
await ctx.interaction.response.send_modal(ReviewModal(self))
|
|
|
|
@commands.hybrid_command() # type: ignore
|
|
@commands.guild_only()
|
|
@commands.admin_or_permissions(manage_guild=True)
|
|
async def waitlist(self, ctx: commands.Context, user: discord.Member, *, item: str):
|
|
"""Add a user and their requested item to the waitlist."""
|
|
if not ctx.guild or not isinstance(ctx.channel, discord.TextChannel):
|
|
return await ctx.send("This command must be used in a server's text channel.", ephemeral=True)
|
|
|
|
waitlist_channel_id = await self.config.guild(ctx.guild).waitlist_channel()
|
|
if not waitlist_channel_id:
|
|
return await ctx.send("The waitlist channel has not been set by an admin.", ephemeral=True)
|
|
|
|
waitlist_channel = ctx.guild.get_channel(waitlist_channel_id)
|
|
if not isinstance(waitlist_channel, discord.TextChannel):
|
|
return await ctx.send("The configured waitlist channel is invalid.", ephemeral=True)
|
|
|
|
message = f"**{item}** ིྀ {user.mention} ✧ in {ctx.channel.mention}"
|
|
|
|
try:
|
|
await waitlist_channel.send(message)
|
|
await ctx.send(f"{user.mention} has been added to the waitlist for '{item}'.", ephemeral=True)
|
|
except discord.Forbidden:
|
|
await ctx.send(f"I don't have permission to send messages in the waitlist channel.", ephemeral=True)
|
|
|
|
# --- Settings Commands ---
|
|
@commands.group(aliases=["kset"]) # type: ignore
|
|
@commands.guild_only()
|
|
@commands.admin_or_permissions(manage_guild=True)
|
|
async def kofiset(self, ctx: commands.Context):
|
|
"""
|
|
Configure the KofiShop settings.
|
|
"""
|
|
pass
|
|
|
|
@kofiset.command(name="orderchannel")
|
|
async def kofiset_order(self, ctx: commands.Context, channel: discord.TextChannel):
|
|
"""Set the channel where new orders will be sent."""
|
|
if not ctx.guild: return
|
|
await self.config.guild(ctx.guild).order_channel.set(channel.id)
|
|
await ctx.send(f"Order channel has been set to {channel.mention}.")
|
|
|
|
@kofiset.command(name="reviewchannel")
|
|
async def kofiset_review(self, ctx: commands.Context, channel: discord.TextChannel):
|
|
"""Set the channel where new reviews will be sent."""
|
|
if not ctx.guild: return
|
|
await self.config.guild(ctx.guild).review_channel.set(channel.id)
|
|
await ctx.send(f"Review channel has been set to {channel.mention}.")
|
|
|
|
@kofiset.command(name="waitlistchannel")
|
|
async def kofiset_waitlist(self, ctx: commands.Context, channel: discord.TextChannel):
|
|
"""Set the channel where waitlist notifications will be sent."""
|
|
if not ctx.guild: return
|
|
await self.config.guild(ctx.guild).waitlist_channel.set(channel.id)
|
|
await ctx.send(f"Waitlist channel has been set to {channel.mention}.")
|
|
|
|
|
|
async def setup(bot: Red):
|
|
await bot.add_cog(KofiShop(bot))
|
|
|