Merge pull request 'feat: add welcome modes including solstira support' (#12) from welcomer into main
Reviewed-on: #12
This commit is contained in:
@@ -1,195 +1,121 @@
|
|||||||
# welcomer.py
|
|
||||||
|
|
||||||
import discord
|
import discord
|
||||||
from redbot.core import commands, Config
|
from redbot.core import commands, Config
|
||||||
from redbot.core.bot import Red
|
from redbot.core.bot import Red
|
||||||
|
from typing import Literal
|
||||||
|
|
||||||
class Welcomer(commands.Cog):
|
class Welcomer(commands.Cog):
|
||||||
"""
|
"""
|
||||||
A configurable cog to welcome new users to a server.
|
A configurable cog to automatically welcome new users with multiple modes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, bot: Red):
|
def __init__(self, bot: Red):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
# Initialize Red's Config system. This will store our settings.
|
|
||||||
# The "GUILD" identifier means settings will be saved on a per-server basis.
|
|
||||||
self.config = Config.get_conf(self, identifier=1234567890, force_registration=True)
|
self.config = Config.get_conf(self, identifier=1234567890, force_registration=True)
|
||||||
|
|
||||||
# Define the default settings for each server.
|
|
||||||
default_guild = {
|
default_guild = {
|
||||||
"welcome_channel": None, # The ID of the channel to send welcomes to
|
"welcome_channel": None,
|
||||||
"welcome_message": "Welcome to the server, {user.mention}!", # Default message
|
"welcome_message": "Welcome to the server, {user.mention}!",
|
||||||
"enabled": False # Whether the system is on or off
|
"enabled": False,
|
||||||
|
"welcome_mode": "normal" # 'normal' or 'solstira'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Register the default settings.
|
|
||||||
self.config.register_guild(**default_guild)
|
self.config.register_guild(**default_guild)
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_member_join(self, member: discord.Member):
|
async def on_member_join(self, member: discord.Member):
|
||||||
"""
|
|
||||||
The event listener that runs when a new member joins.
|
|
||||||
"""
|
|
||||||
guild = member.guild
|
guild = member.guild
|
||||||
|
|
||||||
# Check if the welcomer is enabled for this server.
|
|
||||||
if not await self.config.guild(guild).enabled():
|
if not await self.config.guild(guild).enabled():
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get the welcome channel ID from our saved settings.
|
mode = await self.config.guild(guild).welcome_mode()
|
||||||
channel_id = await self.config.guild(guild).welcome_channel()
|
|
||||||
if not channel_id:
|
|
||||||
return # If no channel is set, do nothing.
|
|
||||||
|
|
||||||
# Try to find the channel object in the server.
|
|
||||||
channel = guild.get_channel(channel_id)
|
|
||||||
if not channel:
|
|
||||||
# The channel might have been deleted.
|
|
||||||
return
|
|
||||||
|
|
||||||
# Explicitly check if the channel is a TextChannel before trying to send a message.
|
|
||||||
if not isinstance(channel, discord.TextChannel):
|
|
||||||
print(f"Welcomer: Configured channel '{channel.name}' in {guild.name} is not a text channel.")
|
|
||||||
return
|
|
||||||
|
|
||||||
# Get the custom welcome message from our settings.
|
|
||||||
message_template = await self.config.guild(guild).welcome_message()
|
|
||||||
|
|
||||||
# Format the message with the new member's info.
|
|
||||||
# .format() is a safe way to replace placeholders.
|
|
||||||
formatted_message = message_template.format(
|
|
||||||
user=member,
|
|
||||||
user_mention=member.mention,
|
|
||||||
user_name=member.name,
|
|
||||||
server_name=guild.name
|
|
||||||
)
|
|
||||||
|
|
||||||
# Check if we have permission to send messages in the channel.
|
if mode == "solstira":
|
||||||
if not channel.permissions_for(guild.me).send_messages:
|
# Hardcoded Solstira welcome event
|
||||||
# We can't send a message, so we'll just log this internally.
|
channel_id = 1409965732669948024
|
||||||
print(f"Welcomer: No permission to send messages in {channel.name} in {guild.name}.")
|
else: # Normal mode
|
||||||
|
channel_id = await self.config.guild(guild).welcome_channel()
|
||||||
|
|
||||||
|
if not channel_id:
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
channel = guild.get_channel(channel_id)
|
||||||
await channel.send(formatted_message)
|
if not isinstance(channel, discord.TextChannel):
|
||||||
except discord.Forbidden:
|
return
|
||||||
# This is a final safety check in case permissions change suddenly.
|
|
||||||
pass
|
if not channel.permissions_for(guild.me).send_messages:
|
||||||
except discord.HTTPException as e:
|
return
|
||||||
# This can happen if the message is too long or there's a Discord API error.
|
|
||||||
print(f"Welcomer: Failed to send welcome message in {guild.name}: {e}")
|
if mode == "solstira":
|
||||||
|
content = (
|
||||||
|
f"{member.mention}\n"
|
||||||
|
f"- `guide` <https://discord.com/channels/1409939326382651/140993936542124073>\n"
|
||||||
|
f"- <a:f_purpleflower:1409967049561524859> `roles` <@&1409937150>\n"
|
||||||
|
f"(<https://discord.com/channels/1409939326382651/140996735493797150>)\n"
|
||||||
|
f"- `psa` (<https://discord.com/channels/1409939326382651/140996779492440732>)"
|
||||||
|
)
|
||||||
|
embed = discord.Embed(description="--", color=0x8b9ed7)
|
||||||
|
try:
|
||||||
|
await channel.send(content, embed=embed)
|
||||||
|
except discord.HTTPException:
|
||||||
|
pass
|
||||||
|
else: # Normal mode
|
||||||
|
message_template = await self.config.guild(guild).welcome_message()
|
||||||
|
formatted_message = message_template.format(
|
||||||
|
user=member,
|
||||||
|
user_mention=member.mention,
|
||||||
|
user_name=member.name,
|
||||||
|
server_name=guild.name
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
await channel.send(formatted_message)
|
||||||
|
except discord.HTTPException:
|
||||||
|
pass
|
||||||
|
|
||||||
# Create a command group for all our settings commands.
|
|
||||||
@commands.group(aliases=["wset"]) # type: ignore
|
@commands.group(aliases=["wset"]) # type: ignore
|
||||||
@commands.guild_only() # Ensures this command and its subcommands can only be run in a server
|
@commands.guild_only()
|
||||||
@commands.admin_or_permissions(manage_guild=True)
|
@commands.admin_or_permissions(manage_guild=True)
|
||||||
async def welcomeset(self, ctx: commands.Context):
|
async def welcomeset(self, ctx: commands.Context):
|
||||||
"""
|
"""Commands for configuring the welcome system."""
|
||||||
Configure the welcomer settings for this server.
|
|
||||||
"""
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@welcomeset.command(name="channel", aliases=["chnl"])
|
@welcomeset.command(name="mode")
|
||||||
async def welcomeset_channel(self, ctx: commands.Context, channel: discord.TextChannel):
|
async def set_welcome_mode(self, ctx: commands.Context, mode: Literal["normal", "solstira"]):
|
||||||
"""
|
"""Set the welcome mode for this server.
|
||||||
Set the channel where welcome messages will be sent.
|
|
||||||
|
|
||||||
Example:
|
Modes:
|
||||||
[p]welcomeset channel #welcome
|
- `normal`: A simple, configurable welcome message.
|
||||||
|
- `solstira`: The special, complex welcome event.
|
||||||
"""
|
"""
|
||||||
if not ctx.guild:
|
if not ctx.guild:
|
||||||
return # This check satisfies the type checker
|
return
|
||||||
|
await self.config.guild(ctx.guild).welcome_mode.set(mode.lower())
|
||||||
|
await ctx.send(f"Welcome mode has been set to **{mode.lower()}**.")
|
||||||
|
|
||||||
|
@welcomeset.command(name="channel")
|
||||||
|
async def set_welcome_channel(self, ctx: commands.Context, channel: discord.TextChannel):
|
||||||
|
"""(Normal Mode) Set the channel for welcome messages."""
|
||||||
|
if not ctx.guild:
|
||||||
|
return
|
||||||
await self.config.guild(ctx.guild).welcome_channel.set(channel.id)
|
await self.config.guild(ctx.guild).welcome_channel.set(channel.id)
|
||||||
await ctx.send(f"The welcome channel has been set to {channel.mention}.")
|
await ctx.send(f"Welcome channel set to {channel.mention}")
|
||||||
|
|
||||||
@welcomeset.command(name="message", aliases=["msg"])
|
@welcomeset.command(name="message")
|
||||||
async def welcomeset_message(self, ctx: commands.Context, *, message: str):
|
async def set_welcome_message(self, ctx: commands.Context, *, message: str):
|
||||||
"""
|
"""(Normal Mode) Set the welcome message. Use placeholders like {user.mention}."""
|
||||||
Set the custom welcome message.
|
|
||||||
|
|
||||||
You can use these placeholders:
|
|
||||||
{user} - The user object.
|
|
||||||
{user_mention} - Pings the user.
|
|
||||||
{user_name} - The user's name.
|
|
||||||
{server_name} - The name of this server.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
[p]welcomeset message Hello {user_mention}, welcome to {server_name}!
|
|
||||||
"""
|
|
||||||
if not ctx.guild:
|
if not ctx.guild:
|
||||||
return
|
return
|
||||||
await self.config.guild(ctx.guild).welcome_message.set(message)
|
await self.config.guild(ctx.guild).welcome_message.set(message)
|
||||||
await ctx.send(f"The welcome message has been updated.")
|
await ctx.send("Welcome message updated.")
|
||||||
# Send a preview of the new message.
|
|
||||||
preview = message.format(
|
|
||||||
user=ctx.author,
|
|
||||||
user_mention=ctx.author.mention,
|
|
||||||
user_name=ctx.author.name,
|
|
||||||
server_name=ctx.guild.name
|
|
||||||
)
|
|
||||||
await ctx.send(f"**Preview:**\n{preview}")
|
|
||||||
|
|
||||||
@welcomeset.command(name="toggle", aliases=["on", "off"])
|
@welcomeset.command(name="toggle")
|
||||||
async def welcomeset_toggle(self, ctx: commands.Context):
|
async def toggle_welcome(self, ctx: commands.Context):
|
||||||
"""
|
"""Toggle the welcome system on or off."""
|
||||||
Enable or disable the welcomer system on this server.
|
|
||||||
"""
|
|
||||||
if not ctx.guild:
|
if not ctx.guild:
|
||||||
return
|
return
|
||||||
current_status = await self.config.guild(ctx.guild).enabled()
|
current_status = await self.config.guild(ctx.guild).enabled()
|
||||||
new_status = not current_status
|
new_status = not current_status
|
||||||
await self.config.guild(ctx.guild).enabled.set(new_status)
|
await self.config.guild(ctx.guild).enabled.set(new_status)
|
||||||
status_text = "enabled" if new_status else "disabled"
|
status_text = "enabled" if new_status else "disabled"
|
||||||
await ctx.send(f"The welcomer system has been {status_text}.")
|
await ctx.send(f"Welcome system has been {status_text}.")
|
||||||
|
|
||||||
@welcomeset.command(name="settings", aliases=["show", "status"])
|
|
||||||
async def welcomeset_settings(self, ctx: commands.Context):
|
|
||||||
"""
|
|
||||||
Show the current welcomer settings for this server.
|
|
||||||
"""
|
|
||||||
if not ctx.guild:
|
|
||||||
return
|
|
||||||
settings = await self.config.guild(ctx.guild).all()
|
|
||||||
channel_id = settings['welcome_channel']
|
|
||||||
channel = ctx.guild.get_channel(channel_id) if channel_id else None
|
|
||||||
message = settings['welcome_message']
|
|
||||||
enabled = "Enabled" if settings['enabled'] else "Disabled"
|
|
||||||
|
|
||||||
embed = discord.Embed(title="Welcomer Settings", color=await ctx.embed_color())
|
|
||||||
embed.add_field(name="Status", value=enabled, inline=False)
|
|
||||||
embed.add_field(name="Channel", value=channel.mention if isinstance(channel, discord.TextChannel) else "Not Set", inline=False)
|
|
||||||
embed.add_field(name="Message", value=f"```{message}```", inline=False)
|
|
||||||
|
|
||||||
await ctx.send(embed=embed)
|
|
||||||
|
|
||||||
@welcomeset.command(name="test")
|
|
||||||
async def welcomeset_test(self, ctx: commands.Context):
|
|
||||||
"""
|
|
||||||
Test the welcome message by sending a preview to this channel.
|
|
||||||
"""
|
|
||||||
if not ctx.guild:
|
|
||||||
return
|
|
||||||
message_template = await self.config.guild(ctx.guild).welcome_message()
|
|
||||||
preview = message_template.format(
|
|
||||||
user=ctx.author,
|
|
||||||
user_mention=ctx.author.mention,
|
|
||||||
user_name=ctx.author.name,
|
|
||||||
server_name=ctx.guild.name
|
|
||||||
)
|
|
||||||
await ctx.send(f"**Welcome Message Preview**:\n{preview}")
|
|
||||||
|
|
||||||
@welcomeset.command(name="reset")
|
|
||||||
async def welcomeset_reset(self, ctx: commands.Context):
|
|
||||||
"""
|
|
||||||
Reset all welcomer settings to their defaults.
|
|
||||||
"""
|
|
||||||
if not ctx.guild:
|
|
||||||
return
|
|
||||||
await self.config.guild(ctx.guild).clear()
|
|
||||||
await ctx.send("The welcomer settings have been reset to their defaults.")
|
|
||||||
|
|
||||||
|
|
||||||
# This function allows Red to load the cog.
|
|
||||||
# It is required in every cog file.
|
|
||||||
async def setup(bot: Red):
|
async def setup(bot: Red):
|
||||||
await bot.add_cog(Welcomer(bot))
|
await bot.add_cog(Welcomer(bot))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user