from datetime import datetime, timezone from typing import Literal, Optional import discord from discord.ext import tasks from red_commons.logging import getLogger from redbot.core import Config, checks, commands from redbot.core.i18n import Translator, cog_i18n from redbot.core.utils.chat_formatting import humanize_list from .events import Events from .menus import IMAGE_LINKS, BaseMenu, EventType, WelcomePages default_greeting = "Welcome {0.name} to {1.name}!" default_goodbye = "See you later {0.name}!" default_bot_msg = "Hello {0.name}, fellow bot!" default_settings = { "GREETING": [default_greeting], "ON": False, "LEAVE_ON": False, "LEAVE_CHANNEL": None, "GROUPED": False, "GOODBYE": [default_goodbye], "CHANNEL": None, "WHISPER": False, "BOTS_MSG": default_bot_msg, "BOTS_GOODBYE_MSG": "Goodbye {0.name}, fellow bot!", "BOTS_ROLE": None, "EMBED": False, "JOINED_TODAY": False, "MINIMUM_DAYS": 0, "DELETE_PREVIOUS_GREETING": False, "DELETE_AFTER_GREETING": None, "DELETE_PREVIOUS_GOODBYE": False, "DELETE_AFTER_GOODBYE": None, "LAST_GREETING": None, "FILTER_SETTING": None, "LAST_GOODBYE": None, "MENTIONS": {"users": True, "roles": False, "everyone": False}, "GOODBYE_MENTIONS": {"users": True, "roles": False, "everyone": False}, "EMBED_DATA": { "title": None, "colour": 0, "colour_goodbye": 0, "footer": None, "thumbnail": "avatar", "image": None, "image_goodbye": None, "icon_url": None, "author": True, "timestamp": True, "mention": False, }, } _ = Translator("Welcome", __file__) log = getLogger("red.trusty-cogs.Welcome") @cog_i18n(_) class Welcome(Events, commands.Cog): """Welcomes new members and goodbye those who leave to the guild in the default channel rewritten for V3 from https://github.com/irdumbs/Dumb-Cogs/blob/master/welcome/welcome.py""" __author__ = ["irdumb", "TrustyJAID"] __version__ = "2.5.3" def __init__(self, bot): self.bot = bot self.config = Config.get_conf(self, 144465786453, force_registration=True) self.config.register_guild(**default_settings) self.joined = {} self.today_count = {"now": datetime.now(timezone.utc)} self.group_welcome.start() def format_help_for_context(self, ctx: commands.Context) -> str: """ Thanks Sinbad! """ pre_processed = super().format_help_for_context(ctx) return f"{pre_processed}\n\nCog Version: {self.__version__}" async def red_delete_data_for_user(self, **kwargs): """ Nothing to delete """ return @tasks.loop(seconds=10) async def group_welcome(self) -> None: # log.debug("Checking for new welcomes") clear_guilds = [] for guild_id, members in self.joined.items(): if members: last_time_id = await self.config.guild_from_id(guild_id).LAST_GREETING() if last_time_id is not None: last_time = ( datetime.now(timezone.utc) - discord.utils.snowflake_time(last_time_id) ).total_seconds() if len(members) > 1 and last_time <= 30.0: continue try: await self.send_member_join(members, self.bot.get_guild(guild_id)) clear_guilds.append(guild_id) except Exception: log.exception("Error in group welcome:") for guild_id in clear_guilds: try: del self.joined[guild_id] except KeyError: pass @group_welcome.before_loop async def before_group_welcome(self): await self.bot.wait_until_red_ready() @commands.group() @checks.admin_or_permissions(manage_channels=True) @commands.guild_only() async def welcomeset(self, ctx: commands.Context) -> None: """Sets welcome module settings""" pass @welcomeset.command(name="settings") async def welcome_settings(self, ctx: commands.Context) -> None: """ Show the servers welcome settings """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).get_raw() setting_names = { "GREETING": _("Random Greeting "), "GOODBYE": _("Random Goodbye "), "GROUPED": _("Grouped greetings "), "ON": _("Greetings enabled "), "CHANNEL": _("Greeting Channel "), "LEAVE_ON": _("Goodbyes enabled "), "LEAVE_CHANNEL": _("Goodbye Channel "), "DELETE_PREVIOUS_GREETING": _("Previous greeting deleted "), "DELETE_PREVIOUS_GOODBYE": _("Previous goodbye deleted "), "DELETE_AFTER_GREETING": _("Greeting deleted after "), "DELETE_AFTER_GOODBYE": _("Goodbye deleted after "), "MINIMUM_DAYS": _("Minimum days old to greet "), "WHISPER": _("Whisper "), "BOTS_MSG": _("Bots message "), "BOTS_ROLE": _("Bots role "), "EMBED": _("Embeds "), } msg = "" if ctx.channel.permissions_for(ctx.me).embed_links: embed = discord.Embed(colour=await ctx.embed_colour()) embed.set_author(name=_("Welcome settings for ") + guild.name) # embed.description = "\n".join(g for g in guild_settings["GREETING"]) for attr, name in setting_names.items(): if attr in ["GREETING", "GOODBYE"]: embed.add_field( name=name, value="\n".join(g for g in guild_settings[attr])[:1024], inline=False, ) continue if attr in ["CHANNEL", "LEAVE_CHANNEL"]: chan = guild.get_channel(guild_settings[attr]) if chan is not None: msg += f"**{name}**: {chan.mention}\n" else: msg += f"**{name}**:" + _(" None") + "\n" continue if attr == "BOTS_ROLE": role = guild.get_role(guild_settings["BOTS_ROLE"]) if role is not None: msg += f"**{name}**: {role.mention}\n" else: msg += f"**{name}**:" + _(" None") + "\n" continue else: msg += f"**{name}**: {guild_settings[attr]}\n" embed.description = msg await ctx.send(embed=embed) else: msg = "```\n" for attr, name in setting_names.items(): msg += name + str(guild_settings[attr]) + "\n" msg += "```" await ctx.send(msg) @welcomeset.group(name="greeting", aliases=["welcome"]) async def welcomeset_greeting(self, ctx: commands.Context) -> None: """ Manage welcome messages """ pass @welcomeset_greeting.command() @checks.mod_or_permissions(mention_everyone=True) @checks.bot_has_permissions(mention_everyone=True) async def allowedmentions( self, ctx: commands.Context, set_to: bool, *allowed: Literal["users", "roles", "everyone"] ) -> None: """ Determine the bots allowed mentions for greetings `` What to set the allowed mentions to either `True` or `False`. `[allowed...]` must be either `everyone`, `users`, or `roles` and can include more than one. Note: This will only function on Red 3.4.0 or higher. """ if not allowed: await ctx.send(_("You must provide either `users`, `roles` or `everyone`.")) return for i in set(allowed): if i not in ["everyone", "users", "roles"]: await ctx.send(_("You must provide either `users`, `roles` or `everyone`.")) return if ( "everyone" in set(allowed) or "roles" in set(allowed) and not ctx.guild.me.guild_permissions.mention_everyone ): await ctx.send( _( "I don't have mention everyone permissions so these settings may not work properly." ) ) async with self.config.guild(ctx.guild).MENTIONS() as mention_settings: for setting in set(allowed): mention_settings[setting] = set_to await ctx.send( _("Mention settings have been set to {set_to} for {settings}").format( set_to=str(set_to), settings=humanize_list(list(set(allowed))) ) ) @welcomeset_greeting.command(name="grouped") async def welcomeset_greeting_grouped(self, ctx: commands.Context, grouped: bool) -> None: """Set whether to group greeting messages This is useful if you have a high frequency of member joins. """ await self.config.guild(ctx.guild).GROUPED.set(grouped) if grouped: await ctx.send(_("I will now group greetings.")) else: await ctx.send(_("I will no longer group greetings.")) @welcomeset_greeting.command(name="add") async def welcomeset_greeting_add(self, ctx: commands.Context, *, format_msg: str) -> None: """ Adds a greeting message format for the guild to be chosen at random {0} is member {1} is guild {count} can be used to display number of users who have joined today. Default is set to: Welcome {0.name} to {1.name}! Example formats: {0.mention}.. What are you doing here? {1.name} has a new member! {0.name} - {0.id} Someone new joined! Who is it?! D: IS HE HERE TO HURT US?! [Available attributes for member](https://discordpy.readthedocs.io/en/latest/api.html#member) [Available attributes for guild](https://discordpy.readthedocs.io/en/latest/api.html#guild) """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).GREETING() guild_settings.append(format_msg) await self.config.guild(guild).GREETING.set(guild_settings) await ctx.send(_("Greeting message added for the guild.")) @welcomeset_greeting.command(name="list", aliases=["edit", "delete", "del"]) async def welcomeset_greeting_list(self, ctx: commands.Context, raw: bool = False) -> None: """ Lists the greeting messages of this guild and allows editing the settings. - `[raw=False]` Whether to show the raw text. This can be toggled afterwards. """ guild_settings = await self.config.guild(ctx.guild).GREETING() if not guild_settings: await ctx.send(_("You have no saved greetings.")) return source = WelcomePages(guild_settings) menu = BaseMenu(source, self, raw=raw) log.debug({c.custom_id for c in menu.children}) await menu.start(ctx) @welcomeset_greeting.command(name="toggle") async def welcomeset_greeting_toggle(self, ctx: commands.Context) -> None: """ Turns on/off welcoming new users to the guild. """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).ON() guild_settings = not guild_settings if guild_settings: await ctx.send(_("I will now greet new users to the guild.")) else: await ctx.send(_("I will no longer greet new users.")) await self.config.guild(guild).ON.set(guild_settings) @welcomeset_greeting.command(name="deleteprevious") async def welcomeset_greeting_delete_previous(self, ctx: commands.Context) -> None: """ Turns on/off deleting the previous greeting message when a user joins. """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).DELETE_PREVIOUS_GREETING() guild_settings = not guild_settings if guild_settings: await ctx.send( _("I will now delete the previous greeting message when a new user joins.") ) else: await ctx.send( _("I will stop deleting the previous greeting message when a new user joins.") ) await self.config.guild(guild).DELETE_PREVIOUS_GREETING.set(guild_settings) @welcomeset_greeting.command(name="count") async def welcomeset_greeting_count(self, ctx: commands.Context) -> None: """ Turns on/off showing how many users join each day. This resets 24 hours after the cog was loaded. """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).JOINED_TODAY() guild_settings = not guild_settings if guild_settings: await ctx.send(_("I will now show how many people join the server each day.")) else: await ctx.send(_("I will stop showing how many people join the server each day.")) await self.config.guild(guild).JOINED_TODAY.set(guild_settings) @welcomeset_greeting.command(name="minimumage", aliases=["age"]) async def welcomeset_greeting_minimum_days(self, ctx: commands.Context, days: int) -> None: """ Set the minimum number of days a user account must be to show up in the greeting message. - `` number of days old the account must be, set to 0 to not require this. """ guild = ctx.message.guild if days < 0: days = 0 await self.config.guild(guild).MINIMUM_DAYS.set(days) await ctx.send( _("I will now show users joining who are {days} days old.").format(days=days) ) @welcomeset_greeting.command(name="filter") async def welcomeset_greeting_filter( self, ctx: commands.Context, replacement: Optional[str] = None ) -> None: """ Set what to do when a username matches the bots filter. - `[replacement]` replaces usernames that are found by cores filter with this word. If left blank this will replace bad words with [Redacted] on grouped messages. """ await self.config.guild(ctx.guild).FILTER_SETTING.set(replacement) if replacement: await ctx.send( _( "I will now replace usernames matching cores filter with `{replacement}`" ).format(replacement=replacement) ) else: await ctx.send( _("I will not post greeting messages for usernames that match cores filter.") ) if not self.bot.get_cog("Filter"): await ctx.send( _( "Filter is not loaded, run `{prefix}load filter` and add " "some words to filter for this to work" ).format(prefix=ctx.clean_prefix) ) @welcomeset_greeting.command(name="deleteafter") async def welcomeset_greeting_delete_after( self, ctx: commands.Context, delete_after: Optional[int] = None ) -> None: """ Set the time after which a greeting message is deleted in seconds. Providing no input will set the bot to not delete after any time. """ if delete_after: await ctx.send( _("I will now delete greeting messages after {time} seconds.").format( time=delete_after ) ) else: await ctx.send(_("I will not delete greeting messages after a set time.")) await self.config.guild(ctx.guild).DELETE_AFTER_GREETING.set(delete_after) @welcomeset_greeting.command(name="channel") async def welcomeset_greeting_channel( self, ctx: commands.Context, channel: discord.TextChannel ) -> None: """ Sets the channel to send the greeting message. If channel isn"t specified, the guild's default channel will be used """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).CHANNEL() if channel is None: channel = ctx.message.channel if not channel.permissions_for(ctx.me).send_messages: msg = _("I do not have permissions to send messages to {channel}").format( channel=channel.mention ) await ctx.send(msg) return guild_settings = channel.id await self.config.guild(guild).CHANNEL.set(guild_settings) msg = _("I will now send greeting messages to {channel}").format(channel=channel.mention) await ctx.send(msg) @welcomeset_greeting.command() async def test(self, ctx: commands.Context) -> None: """Test the greeting message deleted after 60 seconds.""" await self.send_testing_msg(ctx) @welcomeset.group(name="goodbye", aliases=["leave"]) async def welcomeset_goodbye(self, ctx: commands.Context) -> None: """ Manage goodbye messages. """ pass @welcomeset_goodbye.command(name="allowedmentions") @checks.mod_or_permissions(mention_everyone=True) async def goodbye_allowedmentions( self, ctx: commands.Context, set_to: bool, *allowed: Literal["users", "roles", "everyone"] ) -> None: """ Determine the bots allowed mentions for greetings `` What to set the allowed mentions to either `True` or `False`. `[allowed...]` must be either `everyone`, `users`, or `roles` and can include more than one. Note: This will only function on Red 3.4.0 or higher. """ if not allowed: await ctx.send(_("You must provide either `users`, `roles` or `everyone`.")) return for i in set(allowed): if i not in ["everyone", "users", "roles"]: await ctx.send(_("You must provide either `users`, `roles` or `everyone`.")) return if ( "everyone" in set(allowed) or "roles" in set(allowed) and not ctx.guild.me.guild_permissions.mention_everyone ): await ctx.send( _( "I don't have mention everyone permissions so these settings may not work properly." ) ) async with self.config.guild(ctx.guild).GOODBYE_MENTIONS() as mention_settings: for setting in set(allowed): mention_settings[setting] = set_to await ctx.send( _("Mention settings have been set to {set_to} for {settings}").format( set_to=str(set_to), settings=humanize_list(list(set(allowed))) ) ) @welcomeset_goodbye.command(name="add") async def welcomeset_goodbye_add(self, ctx: commands.Context, *, format_msg: str) -> None: """ Adds a goodbye message format for the guild to be chosen at random {0} is member {1} is guild Default is set to: See you later {0.name}! Example formats: {0.mention}.. well, bye. {1.name} has lost a member. {0.name} - {0.id} Someone has quit the server! Who is it?! D: [Available attributes for member](https://discordpy.readthedocs.io/en/latest/api.html#member) [Available attributes for guild](https://discordpy.readthedocs.io/en/latest/api.html#guild) """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).GOODBYE() guild_settings.append(format_msg) await self.config.guild(guild).GOODBYE.set(guild_settings) await ctx.send(_("Goodbye message added for the guild.")) @welcomeset_goodbye.command(name="list", aliases=["edit", "delete", "del"]) async def welcomeset_goodbye_list(self, ctx: commands.Context, raw: bool = False) -> None: """ Lists the goodbye messages of this guild and allows editing the settings. - `[raw=False]` Whether to show the raw text. This can be toggled afterwards. """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).GOODBYE() if not guild_settings: await ctx.send(_("You have no saved goodbyes.")) return source = WelcomePages(guild_settings) menu = BaseMenu(source, self, raw=raw, event_type=EventType.goodbye) log.debug({c.custom_id for c in menu.children}) await menu.start(ctx) @welcomeset_goodbye.command(name="toggle") async def welcomeset_goodbye_toggle(self, ctx: commands.Context) -> None: """ Turns on/off sending goodbye messages to users who leave to the guild. """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).LEAVE_ON() guild_settings = not guild_settings if guild_settings: await ctx.send(_("I will now say goodbye when a member leaves the server.")) else: await ctx.send(_("I will no longer say goodbye to members leaving the server.")) await self.config.guild(guild).LEAVE_ON.set(guild_settings) @welcomeset_goodbye.command(name="channel") async def welcomeset_goodbye_channel( self, ctx: commands.Context, channel: discord.TextChannel ) -> None: """ Sets the channel to send the goodbye message. """ guild = ctx.message.guild if not channel.permissions_for(ctx.me).send_messages: msg = _("I do not have permissions to send messages to {channel}").format( channel=channel.mention ) await ctx.send(msg) return await self.config.guild(guild).LEAVE_CHANNEL.set(channel.id) msg = _("I will now send goodbye messages to {channel}").format(channel=channel.mention) await ctx.send(msg) @welcomeset_goodbye.command(name="deleteprevious") async def welcomeset_goodbye_delete_previous(self, ctx: commands.Context) -> None: """ Turns on/off deleting the previous greeting message when a user joins. """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).DELETE_PREVIOUS_GOODBYE() guild_settings = not guild_settings if guild_settings: await ctx.send(_("I will now delete the previous goodbye message when user leaves.")) else: await ctx.send( _("I will stop deleting the previous goodbye message when a user leaves.") ) await self.config.guild(guild).DELETE_PREVIOUS_GOODBYE.set(guild_settings) @welcomeset_goodbye.command(name="deleteafter") async def welcomeset_goodbye_delete_after( self, ctx: commands.Context, delete_after: Optional[int] = None ) -> None: """ Set the time after which a greeting message is deleted in seconds. Providing no input will set the bot to not delete after any time. """ if delete_after: await ctx.send( _("I will now delete goodbye messages after {time} seconds.").format( time=delete_after ) ) else: await ctx.send(_("I will not delete greeting messages after a set time.")) await self.config.guild(ctx.guild).DELETE_AFTER_GOODBYE.set(delete_after) @welcomeset_goodbye.command(name="test") async def welcomeset_goodbye_test(self, ctx: commands.Context) -> None: """Test the goodbye message deleted after 60 seconds""" await self.send_testing_msg(ctx, leave=True) @welcomeset.group(name="bot") async def welcomeset_bot(self, ctx: commands.Context) -> None: """ Special greeting for bots. """ pass @welcomeset_bot.command(name="test") async def welcomeset_bot_test(self, ctx: commands.Context) -> None: """Test the bot joining message""" await self.send_testing_msg(ctx, bot=True) @welcomeset_bot.command(name="msg") async def welcomeset_bot_msg( self, ctx: commands.Context, *, format_msg: Optional[str] = None ) -> None: """Set the greeting msg for bots. Leave blank to reset to regular user greeting""" guild = ctx.message.guild guild_settings = await self.config.guild(guild).BOTS_MSG() guild_settings = format_msg await self.config.guild(guild).BOTS_MSG.set(guild_settings) if format_msg is None: msg = _("Bot message reset. Bots will now be greeted as regular users.") await ctx.send(msg) else: await ctx.send(_("Bot greeting message set for the guild.")) @welcomeset_bot.command(name="goodbyemsg", aliases=["goodbyemessage"]) async def welcomeset_bot_goodbye_msg( self, ctx: commands.Context, *, format_msg: Optional[str] = None ) -> None: """Set the goodbye msg for bots. Leave blank to reset to regular user goodbye""" guild = ctx.message.guild guild_settings = await self.config.guild(guild).BOTS_GOODBYE_MSG() guild_settings = format_msg await self.config.guild(guild).BOTS_GOODBYE_MSG.set(guild_settings) if format_msg is None: msg = _("Bot goodbye message reset. Bots will now leave as regular users.") await ctx.send(msg) else: await ctx.send(_("Bot goodbye message set for the guild.")) @welcomeset_bot.command(name="role") @commands.bot_has_permissions(manage_roles=True) async def welcomeset_bot_role( self, ctx: commands.Context, *, role: Optional[discord.Role] = None ) -> None: """ Set the role to put bots in when they join. Leave blank to not give them a role. """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).BOTS_ROLE() guild_settings = role.id if role is not None else role if role is not None and role >= guild.me.top_role: await ctx.send(_("I cannot assign roles higher than my own.")) return await self.config.guild(guild).BOTS_ROLE.set(guild_settings) if role: msg = _("Bots that join this guild will be given ") + role.name else: msg = _("Bots that join this guild will not be given a role.") await ctx.send(msg) @welcomeset.command() async def whisper(self, ctx: commands.Context, choice: Optional[str] = None) -> None: """Sets whether or not a DM is sent to the new user Options: off - turns off DMs to users only - only send a DM to the user, don"t send a greeting to the channel both - send a message to both the user and the channel If Option isn't specified, toggles between "off" and "only" DMs will not be sent to bots""" options = {"off": False, "only": True, "both": "BOTH"} guild = ctx.message.guild guild_settings = await self.config.guild(guild).WHISPER() if choice is None: guild_settings = not guild_settings elif choice.lower() not in options: await ctx.send(_("You must select either `off`, `only`, or `both`.")) return else: guild_settings = options[choice.lower()] await self.config.guild(guild).WHISPER.set(guild_settings) if not guild_settings: await ctx.send(_("I will no longer send DMs to new users")) elif guild_settings == "BOTH": channel = guild.get_channel(await self.config.guild(guild).CHANNEL()) msg = _( "I will now send greeting messages to {channel} as well as to the new user in a DM" ).format(channel=channel) await ctx.send(msg) else: msg = _("I will now only send greeting messages to the new user as a DM") await ctx.send(msg) await self.send_testing_msg(ctx) @welcomeset.group(name="embed") async def _embed(self, ctx: commands.Context) -> None: """ Set various embed options. """ pass @_embed.command() async def toggle(self, ctx: commands.Context) -> None: """ Toggle embed messages. """ guild = ctx.message.guild guild_settings = await self.config.guild(guild).EMBED() await self.config.guild(guild).EMBED.set(not guild_settings) if guild_settings: verb = _("off") else: verb = _("on") await ctx.send(_("Greeting embeds turned {verb}").format(verb=verb)) @_embed.command(aliases=["color"]) @commands.bot_has_permissions(embed_links=True) async def colour(self, ctx: commands.Context, colour: discord.Colour) -> None: """ Set the embed colour. This accepts hex codes and integer value colours. """ await self.config.guild(ctx.guild).EMBED_DATA.colour.set(colour.value) em = discord.Embed( colour=colour, description=_("Welcome colour set to `{colour}`").format(colour=colour) ) await ctx.send(embed=em) @_embed.command(aliases=["gcolor", "goodbyecolor", "gcolour"]) @commands.bot_has_permissions(embed_links=True) async def goodbyecolour(self, ctx: commands.Context, colour: discord.Colour) -> None: """ Set the embed colour. This accepts hex codes and integer value colours. """ await self.config.guild(ctx.guild).EMBED_DATA.colour_goodbye.set(colour.value) em = discord.Embed( colour=colour, description=_("Goodbye colour set to `{colour}`").format(colour=colour) ) await ctx.send(embed=em) @_embed.command() async def title(self, ctx: commands.Context, *, title: str = "") -> None: """ Set the embed title. {0} is member. {1} is guild. {count} can be used to display number of users who have joined today. [Available attributes for member](https://discordpy.readthedocs.io/en/latest/api.html#member) [Available attributes for guild](https://discordpy.readthedocs.io/en/latest/api.html#guild) """ await self.config.guild(ctx.guild).EMBED_DATA.title.set(title[:256]) await ctx.tick() @_embed.command() async def footer(self, ctx: commands.Context, *, footer: str = "") -> None: """ Set the embed footer. {0} is member. {1} is guild. {count} can be used to display number of users who have joined today. [Available attributes for member](https://discordpy.readthedocs.io/en/latest/api.html#member) [Available attributes for guild](https://discordpy.readthedocs.io/en/latest/api.html#guild) """ await self.config.guild(ctx.guild).EMBED_DATA.footer.set(footer[:256]) await ctx.tick() @_embed.command() async def thumbnail(self, ctx: commands.Context, link: Optional[str] = None) -> None: """ Set the embed thumbnail image. `[link]` must be a valid image link. You may also specify: - `member`, `user` or `avatar` to use the members avatar. - `server` or `guild` to use the servers icon. - `splash` to use the servers splash image if available. if nothing is provided the defaults are used. """ if link is not None: link_search = IMAGE_LINKS.search(link) if link_search: await self.config.guild(ctx.guild).EMBED_DATA.thumbnail.set(link_search.group(0)) await ctx.tick() elif link in ["member", "user", "avatar"]: await self.config.guild(ctx.guild).EMBED_DATA.thumbnail.set("avatar") await ctx.tick() elif link in ["server", "guild"]: await self.config.guild(ctx.guild).EMBED_DATA.thumbnail.set("guild") await ctx.tick() elif link == "splash": await self.config.guild(ctx.guild).EMBED_DATA.thumbnail.set("splash") await ctx.tick() else: await ctx.send( _("That's not a valid option. You must provide a link, `avatar` or `server`.") ) else: await self.config.guild(ctx.guild).EMBED_DATA.thumbnail.set(None) await ctx.send(_("Thumbnail cleared.")) @_embed.command() async def icon(self, ctx: commands.Context, link: Optional[str] = None) -> None: """ Set the embed icon image. `[link]` must be a valid image link. You may also specify: - `member`, `user` or `avatar` to use the members avatar. - `server` or `guild` to use the servers icon. - `splash` to use the servers splash image if available. if nothing is provided the defaults are used. """ if link is not None: link_search = IMAGE_LINKS.search(link) if link_search: await self.config.guild(ctx.guild).EMBED_DATA.icon_url.set(link_search.group(0)) await ctx.tick() elif link in ["author", "avatar"]: await self.config.guild(ctx.guild).EMBED_DATA.icon_url.set("avatar") await ctx.tick() elif link in ["server", "guild"]: await self.config.guild(ctx.guild).EMBED_DATA.icon_url.set("guild") await ctx.tick() elif link == "splash": await self.config.guild(ctx.guild).EMBED_DATA.icon_url.set("splash") await ctx.tick() else: await ctx.send( _("That's not a valid option. You must provide a link, `avatar` or `server`.") ) else: await self.config.guild(ctx.guild).EMBED_DATA.icon_url.set(None) await ctx.send(_("Icon cleared.")) @_embed.group(name="image") async def _image(self, ctx: commands.Context) -> None: """ Set embed image options. """ pass @_image.command(name="greeting") async def image_greeting(self, ctx: commands.Context, link: Optional[str] = None) -> None: """ Set the embed image link for greetings. `[link]` must be a valid image link. You may also specify: - `member`, `user` or `avatar` to use the members avatar. - `server` or `guild` to use the servers icon. - `splash` to use the servers splash image if available. if nothing is provided the defaults are used. """ if link is not None: link_search = IMAGE_LINKS.search(link) if link_search: await self.config.guild(ctx.guild).EMBED_DATA.image.set(link_search.group(0)) await ctx.tick() elif link in ["author", "avatar"]: await self.config.guild(ctx.guild).EMBED_DATA.image.set("avatar") await ctx.tick() elif link in ["server", "guild"]: await self.config.guild(ctx.guild).EMBED_DATA.image.set("guild") await ctx.tick() elif link == "splash": await self.config.guild(ctx.guild).EMBED_DATA.image.set("splash") await ctx.tick() else: await ctx.send( _("That's not a valid option. You must provide a link, `avatar` or `server`.") ) else: await self.config.guild(ctx.guild).EMBED_DATA.image.set(None) await ctx.send(_("Greeting image cleared.")) @_image.command(name="goodbye") async def image_goodbye(self, ctx: commands.Context, link: Optional[str] = None) -> None: """ Set the embed image link for goodbyes. `[link]` must be a valid image link. You may also specify: - `member`, `user` or `avatar` to use the members avatar. - `server` or `guild` to use the servers icon. - `splash` to use the servers splash image if available. if nothing is provided the defaults are used. """ if link is not None: link_search = IMAGE_LINKS.search(link) if link_search: await self.config.guild(ctx.guild).EMBED_DATA.image_goodbye.set( link_search.group(0) ) await ctx.tick() elif link in ["author", "avatar"]: await self.config.guild(ctx.guild).EMBED_DATA.image_goodbye.set("avatar") await ctx.tick() elif link in ["server", "guild"]: await self.config.guild(ctx.guild).EMBED_DATA.image_goodbye.set("guild") await ctx.tick() elif link == "splash": await self.config.guild(ctx.guild).EMBED_DATA.image_goodbye.set("splash") await ctx.tick() else: await ctx.send( _("That's not a valid option. You must provide a link, `avatar` or `server`.") ) else: await self.config.guild(ctx.guild).EMBED_DATA.image_goodbye.set(None) await ctx.send(_("Goodbye image cleared.")) @_embed.command() async def timestamp(self, ctx: commands.Context) -> None: """ Toggle the timestamp in embeds. """ cur_setting = await self.config.guild(ctx.guild).EMBED_DATA.timestamp() await self.config.guild(ctx.guild).EMBED_DATA.timestamp.set(not cur_setting) if cur_setting: verb = _("off") else: verb = _("on") await ctx.send(_("Timestamps turned {verb}").format(verb=verb)) @_embed.command() async def author(self, ctx: commands.Context) -> None: """ Toggle the author field being filled in the embed. Note: This will override the icon image if it is set. """ cur_setting = await self.config.guild(ctx.guild).EMBED_DATA.author() await self.config.guild(ctx.guild).EMBED_DATA.author.set(not cur_setting) if cur_setting: verb = _("off") else: verb = _("on") await ctx.send(_("Author field turned {verb}").format(verb=verb)) @_embed.command() async def mention(self, ctx: commands.Context) -> None: """ Toggle mentioning the user when they join. This will add a mention outside the embed so they actually get the mention. """ cur_setting = await self.config.guild(ctx.guild).EMBED_DATA.mention() await self.config.guild(ctx.guild).EMBED_DATA.mention.set(not cur_setting) if cur_setting: verb = _("off") else: verb = _("on") await ctx.send(_("Mentioning the user turned {verb}").format(verb=verb)) async def cog_unload(self): # self.group_check.cancel() self.group_welcome.cancel()