async def __get_channel(self, guild: discord.Guild, event: str) -> discord.TextChannel: """Gets the best text channel to use for event notices. Order of priority: 1. User-defined channel 2. Guild's system channel (if bot can speak in it) 3. First channel that the bot can speak in """ channel = None if event == "default": channel_id: int = await self.config.guild(guild).channel() else: channel_id = await self.config.guild(guild).get_attr(event ).channel() if channel_id is not None: channel = guild.get_channel(channel_id) if channel is None or not Welcome.__can_speak_in(channel): channel = guild.get_channel(await self.config.guild(guild).channel()) if channel is None or not Welcome.__can_speak_in(channel): channel = guild.system_channel if channel is None or not Welcome.__can_speak_in(channel): for ch in guild.text_channels: if Welcome.__can_speak_in(ch): channel = ch break return channel
async def assignGuild(self, guild: discord.Guild) -> str: print(f'The guild "{guild}" is being assigned to {self.name}.') print(f'There are {len(self.players)} players in this tournament!\n') self.guild = guild self.guildID = guild.id self.hostGuildName = guild.name self.pairingsChannel = guild.get_channel(self.pairingsChannelID) infoChannel = None if isinstance(self.infoMessageChannelID, int): infoChannel = self.guild.get_channel(self.infoMessageChannelID) if (not infoChannel is None) and isinstance(self.infoMessageID, int): self.infoMessage = await infoChannel.fetch_message( self.infoMessageID) if self.pairingsChannel is None: self.pairingsChannel = discord.utils.get(guild.channels, name="match-pairings") if self.roleID != "": self.role = guild.get_role(self.roleID) for player in self.players: ID = self.players[player].discordID if ID != "": self.players[player].addDiscordUser(self.guild.get_member(ID)) for mtch in self.matches: if mtch.roleID != "": mtch.addMatchRole(guild.get_role(mtch.roleID)) if mtch.VC_ID != "": mtch.addMatchVC(guild.get_channel(mtch.VC_ID))
async def set_name(name: str, guild: Guild, private_room: PrivateRoom) -> None: """ Set the name for the private room :param name: New name of the private room :param guild: Guild of private room :param private_room: Private room to change name """ pr_channel: VoiceChannel = guild.get_channel(private_room.room_channel_id) text_channel: TextChannel = guild.get_channel(private_room.text_channel_id) owner: Member = guild.get_member(private_room.owner_id) name.replace('<owner>', owner.mention) if not pr_channel: # Ignore if channel does not exist anymore return if pr_channel.name == name: # Ignore if the name has not changed return # Try to change the names of the room and channel try: await pr_channel.edit(name=name) except NotFound: pass if text_channel: try: await text_channel.edit(name=name) except NotFound: pass
async def delete_all_infochannels(self, guild: discord.Guild): self.stop_guild_queues(guild.id) # Stop processing edits # Delete regular channels for channel_type in self.default_channel_names.keys(): channel_id = await self.config.guild(guild).channel_ids.get_raw( channel_type) if channel_id is not None: channel = guild.get_channel(channel_id) if channel is not None: await channel.delete(reason="InfoChannel delete") await self.config.guild(guild).channel_ids.clear_raw( channel_type) # Delete role channels for role in guild.roles: channel_id = await self.config.role(role).channel_id() if channel_id is not None: channel = guild.get_channel(channel_id) if channel is not None: await channel.delete(reason="InfoChannel delete") await self.config.role(role).channel_id.clear() # Delete the category last category_id = await self.config.guild(guild).category_id() if category_id is not None: category = guild.get_channel(category_id) if category is not None: await category.delete(reason="InfoChannel delete")
async def unlock(guild: Guild, private_room: PrivateRoom) -> None: """ Unlock the private room :param guild: Guild of private room :param private_room: Private room to unlock """ pr_channel: VoiceChannel = guild.get_channel(private_room.room_channel_id) default_role: Role = guild.default_role if not private_room.locked: # Ignore if the private room is already unlocked return # Set permission in pr_channel if pr_channel: overwrite: PermissionOverwrite = pr_channel.overwrites_for( default_role) overwrite.update(connect=True) try: await pr_channel.set_permissions(default_role, overwrite=overwrite) except NotFound: pass # Remove move channel move_channel: VoiceChannel = guild.get_channel( private_room.move_channel_id) if move_channel: await move_channel.delete(reason='Unlocked private room') # Update database update.pr_locked(private_room.room_id, value=False) update.pr_move_channel_id(private_room.room_id, value=None)
def get_fyi_helper(self, guild: discord.Guild, fyi_info): """ Helper that produces a dictionary summarizing an FYI given a raw database result. :param guild: :param fyi_info: :return: """ # Check if this is the command or the relay. if "creator_id" not in fyi_info: response = self.table.get_item( Key={ "guild_id": guild.id, "config_channel_message": channel_message_template.format( fyi_info["chat_channel_id"], fyi_info["command_message_id"]) }) fyi_info = response.get("Item") chat_channel = guild.get_channel( int( re.match(channel_message_pattern, fyi_info["config_channel_message"]).group(1))) command_message_id = int( re.match(channel_message_pattern, fyi_info["config_channel_message"]).group(2)) relay_channel = guild.get_channel(fyi_info["relay_channel_id"]) relay_message_id = fyi_info["relay_message_id"] timestamp = dateutil.parser.parse(fyi_info["timestamp"]) expiry = dateutil.parser.parse(fyi_info["expiry"]) # If the creator is a current guild member, return the member; otherwise, return the raw ID. creator = guild.get_member(fyi_info["creator_id"]) if creator is None: creator = fyi_info["creator_id"] # Likewise for interested members. interested = [] for x in fyi_info["interested"]: curr_interested = guild.get_member(x) if curr_interested is None: curr_interested = x interested.append(curr_interested) return { "chat_channel": chat_channel, "command_message_id": command_message_id, "relay_channel": relay_channel, "relay_message_id": relay_message_id, "chat_relay_message_id": fyi_info["chat_relay_message_id"], "timestamp": timestamp, "expiry": expiry, "creator": creator, "edit_history": fyi_info["edit_history"], "interested": interested, "active": fyi_info["active"] }
async def on_guild_ready(self, guild: discord.Guild): log.info("The guild cache is ready!") self._summary_channel = guild.get_channel( settings.guild.summary_channel) self._admin_channel = guild.get_channel(365960823622991872) self._fallback_emoji = await guild.fetch_emoji(FALLBACK_EMOJI_ID) self._emoji_confirm = await guild.fetch_emoji(CONFIRM_EMOJI_ID) self._emoji_deny = await guild.fetch_emoji(DENY_EMOJI_ID)
def parse_channel_mention( mention: str, server: discord.Guild) -> Optional[discord.TextChannel]: match = re.fullmatch("<#(\\d+)>", mention) if match: return server.get_channel(int(match.group(1))) try: return server.get_channel(int(mention)) except ValueError: return None
async def make_infochannel(self, guild: discord.Guild): botcount = await self.config.guild(guild).bot_count() onlinecount = await self.config.guild(guild).online_count() overwrites = { guild.default_role: discord.PermissionOverwrite(connect=False), guild.me: discord.PermissionOverwrite(manage_channels=True, connect=True), } # Remove the old info channel first channel_id = await self.config.guild(guild).channel_id() if channel_id is not None: channel: discord.VoiceChannel = guild.get_channel(channel_id) if channel: await channel.delete(reason="InfoChannel delete") # Then create the new one channel = await guild.create_voice_channel("Total Humans:", reason="InfoChannel make", overwrites=overwrites) await self.config.guild(guild).channel_id.set(channel.id) if botcount: # Remove the old bot channel first botchannel_id = await self.config.guild(guild).botchannel_id() if channel_id is not None: botchannel: discord.VoiceChannel = guild.get_channel( botchannel_id) if botchannel: await botchannel.delete(reason="InfoChannel delete") # Then create the new one botchannel = await guild.create_voice_channel( "Bots:", reason="InfoChannel botcount", overwrites=overwrites) await self.config.guild(guild).botchannel_id.set(botchannel.id) if onlinecount: # Remove the old online channel first onlinechannel_id = await self.config.guild(guild ).onlinechannel_id() if channel_id is not None: onlinechannel: discord.VoiceChannel = guild.get_channel( onlinechannel_id) if onlinechannel: await onlinechannel.delete(reason="InfoChannel delete") # Then create the new one onlinechannel = await guild.create_voice_channel( "Online:", reason="InfoChannel onlinecount", overwrites=overwrites) await self.config.guild(guild).onlinechannel_id.set( onlinechannel.id) await self.update_infochannel(guild)
async def update_infochannel(self, guild: discord.Guild): guild_data = await self.config.guild(guild).all() botcount = guild_data["bot_count"] onlinecount = guild_data["online_count"] # Gets count of bots # bots = lambda x: x.bot # def bots(x): return x.bot bot_num = len([m for m in guild.members if m.bot]) # bot_msg = f"Bots: {num}" # Gets count of online users members = guild.member_count offline = len( list( filter(lambda m: m.status is discord.Status.offline, guild.members))) online_num = members - offline # online_msg = f"Online: {num}" # Gets count of actual users total = lambda x: not x.bot human_num = len([m for m in guild.members if total(m)]) # human_msg = f"Total Humans: {num}" channel_id = guild_data["channel_id"] if channel_id is None: return False botchannel_id = guild_data["botchannel_id"] onlinechannel_id = guild_data["onlinechannel_id"] channel_id = guild_data["channel_id"] channel: discord.VoiceChannel = guild.get_channel(channel_id) botchannel: discord.VoiceChannel = guild.get_channel(botchannel_id) onlinechannel: discord.VoiceChannel = guild.get_channel( onlinechannel_id) if guild_data["member_count"]: name = f"{channel.name.split(':')[0]}: {human_num}" await channel.edit(reason="InfoChannel update", name=name) if botcount: name = f"{botchannel.name.split(':')[0]}: {bot_num}" await botchannel.edit(reason="InfoChannel update", name=name) if onlinecount: name = f"{onlinechannel.name.split(':')[0]}: {online_num}" await onlinechannel.edit(reason="InfoChannel update", name=name)
async def fetch_guild_rules(self, guild: discord.Guild, member: discord.Member): permcog = self.bot.get_cog("Permissions") # Basically a copy and paste of perms._yaml_get_guild, except doesn't save to a yaml file and instead returns JSON data, and tinkers with the data guild_rules = {} for category in ("COG", "COMMAND"): guild_rules.setdefault(category, {}) rules_dict = await permcog.config.custom(category).all() for cmd_name, cmd_rules in rules_dict.items(): model_rules = cmd_rules.get(str(guild.id)) if model_rules is not None: for target, rule in model_rules.items(): if cmd_name not in guild_rules[category]: guild_rules[category][cmd_name] = [] if target != "default": if rule is None: continue target = int(target) obj = None name = "" objtype = "" if (obj := guild.get_channel(target)): objtype = "Channel" name = obj.name elif (obj := guild.get_role(target)): objtype = "Role" name = obj.name elif (obj := guild.get_member(target)): objtype = "User" name = f"{obj.display_name}#{obj.discriminator}" else: continue saving = { "type": objtype, "name": name, "id": str(target), "permission": "allowed" if rule else "denied", } else: if rule is None: continue saving = { "type": "Default", "permission": "allowed" if rule else "denied", } guild_rules[category][cmd_name].append(saving)
async def delete_all_infochannels(self, guild: discord.Guild): guild_data = await self.config.guild(guild).all() botchannel_id = guild_data["botchannel_id"] onlinechannel_id = guild_data["onlinechannel_id"] botchannel: discord.VoiceChannel = guild.get_channel(botchannel_id) onlinechannel: discord.VoiceChannel = guild.get_channel(onlinechannel_id) channel_id = guild_data["channel_id"] channel: discord.VoiceChannel = guild.get_channel(channel_id) await channel.delete(reason="InfoChannel delete") if botchannel_id is not None: await botchannel.delete(reason="InfoChannel delete") if onlinechannel_id is not None: await onlinechannel.delete(reason="InfoChannel delete") await self.config.guild(guild).clear()
async def update_infochannel(self, guild: discord.Guild): guild_data = await self.config.guild(guild).all() botcount = guild_data["bot_count"] onlinecount = guild_data["online_count"] # Gets count of bots bots = lambda x: x.bot num = len([m for m in guild.members if bots(m)]) bot_msg = f"Bots: {num}" # Gets count of online users members = guild.member_count offline = len( list( filter(lambda m: m.status is discord.Status.offline, guild.members))) num = members - offline online_msg = f"Online: {num}" # Gets count of actual users total = lambda x: not x.bot num = len([m for m in guild.members if total(m)]) human_msg = f"♡︎ ; {num}" channel_id = guild_data["channel_id"] if channel_id is None: return botchannel_id = guild_data["botchannel_id"] onlinechannel_id = guild_data["onlinechannel_id"] channel_id = guild_data["channel_id"] channel: discord.VoiceChannel = guild.get_channel(channel_id) botchannel: discord.VoiceChannel = guild.get_channel(botchannel_id) onlinechannel: discord.VoiceChannel = guild.get_channel( onlinechannel_id) if guild_data["member_count"]: name = "{} ".format(human_msg) await channel.edit(reason="InfoChannel update", name=name) if botcount: name = "{} ".format(bot_msg) await botchannel.edit(reason="InfoChannel update", name=name) if onlinecount: name = "{} ".format(online_msg) await onlinechannel.edit(reason="InfoChannel update", name=name)
async def maybe_send_announcement(self, guild: discord.Guild, rule, announce_embed: discord.Embed) -> None: """ Method to send announcements to channel depending on settings. Can be local to the rule, or global. Parameters ---------- guild The guild where infraction was found. rule The rule triggered. announce_embed Announcement embed """ try: announce_channel = None should_announce_global, announce_channel_id = await self.announcements_enabled( guild=guild) if should_announce_global and announce_channel_id is not None: announce_channel = guild.get_channel(announce_channel_id) rule_specific_announce_channel = await rule.get_specific_announce_channel( guild) if rule_specific_announce_channel is not None: announce_channel = rule_specific_announce_channel if announce_channel is None: return # not Announcing return await announce_channel.send(embed=announce_embed) except discord.errors.Forbidden: log.exception(f"Missing permissions to send messages") except discord.errors.NotFound: log.exception( f"Could not send announce embed as channel was deleted")
async def bump_remind(self, guild: discord.Guild): guild = self.bot.get_guild(guild.id) if not guild: return data = await self.config.guild(guild).all() channel = guild.get_channel(data["channel"]) if not channel: await self.config.guild(guild).channel.clear() return my_perms = channel.permissions_for(guild.me) if not my_perms.send_messages: await self.config.guild(guild).channel.clear() return if data["lock"] and my_perms.manage_roles: await self.autolock_channel(guild, channel, my_perms, lock=False) message = data["message"] allowed_mentions = self.bot.allowed_mentions if data["role"]: role = guild.get_role(data["role"]) if role: message = f"{role.mention}: {message}" allowed_mentions = discord.AllowedMentions(roles=[role]) kwargs = self.process_tagscript(message) try: await channel.send(allowed_mentions=allowed_mentions, **kwargs) except discord.Forbidden: await self.config.guild(guild).channel.clear() await self.config.guild(guild).nextBump.clear()
async def get_nsfw_channel(self, guild: discord.Guild): channel_id = await self.config.guild(guild).channel_id() if channel_id is None: return None else: return guild.get_channel(channel_id=channel_id)
async def decancer_log( self, guild: discord.Guild, member: discord.Member, moderator: discord.Member, old_nick: str, new_nick: str, dc_type: str, ): channel = guild.get_channel(await self.config.guild(guild).modlogchannel()) if not channel or not (channel.permissions_for(guild.me).send_messages and channel.permissions_for( guild.me).embed_links): await self.config.guild(guild).modlogchannel.clear() return color = 0x2FFFFF description = [ f"**Offender:** {member} {member.mention}", f"**Reason:** Remove cancerous characters from previous name", f"**New Nickname:** {new_nick}", f"**Responsible Moderator:** {moderator} {moderator.mention}", ] embed = discord.Embed( color=discord.Color(color), title=dc_type, description="\n".join(description), timestamp=datetime.utcnow(), ) embed.set_footer(text=f"ID: {member.id}") await channel.send(embed=embed)
def _get_text_channel( self, guild: Guild, channel_id: int, ) -> Optional[TextChannel]: """Fetches text channel, if exists, from guild""" return guild.get_channel(channel_id)
async def from_json(cls, data: dict, guild: discord.Guild): channel = cast(discord.TextChannel, guild.get_channel(data["channel"])) message = None if not channel: return None try: message = await channel.fetch_message(data["message"]) except AttributeError: message = await channel.get_message(data["message"] ) # type: ignore except Exception: # Return None if we can't find the original events return None hoster = guild.get_member(data["hoster"]) if not hoster: return None members = [] for m, p_class in data["members"]: mem = guild.get_member(m) if not mem: continue members.append((mem, p_class)) max_slots = None if "max_slots" in data: max_slots = data["max_slots"] maybe = [] if "maybe" in data: for m in data["maybe"]: mem = guild.get_member(m) if not mem: continue maybe.append(mem) return cls(hoster, members, data["event"], max_slots, guild.get_member(data["approver"]), message, channel, maybe)
async def send_notification(self, guild: discord.Guild, notification: str, *, ping=False, link_message: discord.Message = None, file: discord.File = None, embed: discord.Embed = None, react: str = None): if ping: id_to_ping = await self.config.guild(guild).notify_role() if id_to_ping: notification = f"<@&{id_to_ping}>! {notification}" if link_message: m = link_message link = f"https://discordapp.com/channels/{m.guild.id}/{m.channel.id}/{m.id}" notification = f"{notification}\n{link}" notify_channel_id = await self.config.guild(guild).notify_channel() notify_channel = guild.get_channel(notify_channel_id) if notify_channel: msg = await notify_channel.send( notification, file=file, embed=embed, allowed_mentions=discord.AllowedMentions(roles=True)) if react: await msg.add_reaction(react) return msg return False
async def bump_message(self, guild: discord.Guild): data = await self.config.guild(guild).all() channel = guild.get_channel(data["channel"]) allowed_mentions = discord.AllowedMentions(roles=True) if not channel or not channel.permissions_for(guild.me).send_messages: await self.config.guild(guild).channel.clear() elif data["role"]: role = guild.get_role(data["role"]) if role: message = f"{role.mention}: {data['message']}" cog = self.bot.get_cog("ForceMention") if cog: await cog.forcemention(channel, role, message) else: await channel.send(message, allowed_mentions=allowed_mentions) else: await self.config.guild(guild).role.clear() elif channel: message = data["message"] try: await channel.send(message, allowed_mentions=allowed_mentions) except discord.errors.Forbidden: await self.config.guild(guild).channel.clear() else: await self.config.guild(guild).channel.clear() await self.config.guild(guild).nextBump.clear()
async def __get_channel(self, guild: discord.Guild) -> discord.TextChannel: """Gets the best text channel to use for event notices. Order of priority: 1. User-defined channel 2. Guild's system channel (if bot can speak in it) 3. First channel that the bot can speak in """ channel = None channel_id = await self.config.guild(guild).channel() if channel_id is not None: channel = guild.get_channel(channel_id) if channel is None or not self.__can_speak_in(channel): channel = guild.system_channel if channel is None or not self.__can_speak_in(channel): for ch in guild.text_channels: if self.__can_speak_in(ch): channel = ch break return channel
async def log(bot: Bot, guild: discord.Guild, **kwargs) -> Optional[discord.Message]: """Logs a message to a Parameters ---------- bot : Bot To search whether a log channel is set or not. guild : Guild The guild to use. kwargs : The kwargs used to send a message. Returns ------- Optional[discord.Message] Returns a `Message` if sent. """ settings = await bot.settings.find_one({'guildId': guild.id}) if settings is None or settings.get('log', None) is None: return channel_id = settings['log'] channel = guild.get_channel(channel_id) if channel is None: channel = await guild.fetch_channel(channel_id) if channel is None: return try: return await channel.send(**kwargs) except discord.HTTPException: pass
async def get_log(self, guild: Guild) -> t.Optional[TextChannel]: """ Try to obtain the proper channel for given guild, if the channel is found, return it, otherwise, return `None`. """ member_log_id = await LogChannels.get_log_channel(self.bot.db_engine, "member_log", guild) return guild.get_channel(int(member_log_id))
async def get_channel(self, guild: discord.Guild): if not await self.is_channel_set(guild): return None channel_id = await self.config.guild(guild).channel_log() channel = guild.get_channel(channel_id) return channel
async def get_modlog_channel( guild: discord.Guild) -> Union[discord.TextChannel, None]: """ Get the current modlog channel Parameters ---------- guild: `discord.Guild` The guild to get the modlog channel for Returns ------- `discord.TextChannel` or `None` The channel object representing the modlog channel Raises ------ RuntimeError If the modlog channel is not found """ if hasattr(guild, "get_channel"): channel = guild.get_channel(await _conf.guild(guild).mod_log()) else: channel = await _conf.guild(guild).mod_log() if channel is None: raise RuntimeError("Failed to get the mod log channel!") return channel
async def get_welcome_channel( self, member: Union[discord.Member, List[discord.Member]], guild: discord.Guild) -> Optional[discord.TextChannel]: # grab the welcome channel # guild_settings = await self.config.guild(guild).guild_settings() c_id = await self.config.guild(guild).CHANNEL() channel = cast(discord.TextChannel, guild.get_channel(c_id)) only_whisper = await self.config.guild(guild).WHISPER() is True if channel is None: # complain even if only whisper if not only_whisper: log.info( _("welcome.py: Channel not found. It was most likely deleted. User joined: " ) + str(member)) return None else: # We will not complain here since some people only want the bot to whisper at times return None # we can stop here if not guild.me.permissions_in(channel).send_messages: log.info( _("Permissions Error. User that joined: ") + "{0}".format(member)) log.info( _("Bot doesn't have permissions to send messages to ") + "{0.name}'s #{1.name} channel".format(guild, channel)) return None return channel
async def get_modlog_channel(guild: discord.Guild) -> discord.TextChannel: """ Get the current modlog channel. Parameters ---------- guild: `discord.Guild` The guild to get the modlog channel for. Returns ------- `discord.TextChannel` The channel object representing the modlog channel. Raises ------ RuntimeError If the modlog channel is not found. """ if hasattr(guild, "get_channel"): channel = guild.get_channel(await _config.guild(guild).mod_log()) else: # For unit tests only channel = await _config.guild(guild).mod_log() if channel is None: raise RuntimeError("Failed to get the mod log channel!") return channel
async def _log_verify_message( self, guild: discord.Guild, user: discord.Member, verifier: discord.Member, **kwargs, ): """Private method for logging a message to the logchannel""" failmessage = kwargs.get("failmessage", None) message = failmessage or "User Verified" log_id = await self.config.guild(guild).logchannel() if log_id: log = guild.get_channel(log_id) data = discord.Embed(color=discord.Color.orange()) data.set_author(name=f"{message} - {user}", icon_url=user.avatar_url) data.add_field(name="User", value=user.mention) data.add_field(name="ID", value=user.id) if not failmessage: if not verifier: data.add_field(name="Verifier", value="Auto") else: data.add_field(name="Verifier", value=verifier.mention) reason = kwargs.get("reason", False) if reason: data.add_field(name="Reason", value=reason) if log: try: await log.send(embed=data) except discord.Forbidden: await log.send(f"**{message}** - {user.id} - {user}")
async def create_lfg_message(client: discord.Client, guild: discord.Guild, author: discord.Member, activity: str, description: str, start_time: datetime, max_joined_members: int): # get next free id lfg_id = await get_next_free_lfg_message_id() # get blacklisted members blacklisted_members = await get_lfg_blacklisted_members(author.id) # get channel id result = await getPersistentMessage("lfg", guild.id) if not result: return channel = guild.get_channel(result[0]) # create LfgMessage object lfg_message = LfgMessage( client=client, id=lfg_id, guild=guild, channel=channel, author=author, activity=activity, description=description, start_time=start_time, max_joined_members=max_joined_members, blacklisted_members=blacklisted_members ) # send and save to db await lfg_message.send()
async def get_messages(self, guild: discord.Guild, author: discord.Member, links: list): messages = [] for link in links: link_segments = link.split("/") link_ids = [] for segment in link_segments[-3:]: try: link_ids.append(int(segment)) except ValueError: continue if link_ids[0] != guild.id: continue channel = guild.get_channel(link_ids[1]) if (not channel or channel.is_nsfw() or not ( channel.permissions_for(author).read_messages and channel.permissions_for(author).read_message_history)): continue if not (channel.permissions_for(guild.me).read_messages and channel.permissions_for(guild.me).read_message_history): continue try: message = await channel.fetch_message(link_ids[2]) messages.append(message) except discord.errors.NotFound: continue return messages
async def _get_announce_channel(self, guild: discord.Guild) -> discord.TextChannel: channel_id = await self.config.guild(guild).announce_channel() channel = None if channel_id is not None: channel = guild.get_channel(channel_id) if channel is None: channel = guild.system_channel if channel is None: channel = guild.text_channels[0] return channel
async def send_report(self, msg: discord.Message, guild: discord.Guild): author = guild.get_member(msg.author.id) report = msg.clean_content channel_id = await self.config.guild(guild).output_channel() channel = guild.get_channel(channel_id) if channel is None: return None files: List[discord.File] = await Tunnel.files_from_attatch(msg) ticket_number = await self.config.guild(guild).next_ticket() await self.config.guild(guild).next_ticket.set(ticket_number + 1) if await self.bot.embed_requested(channel, author): em = discord.Embed(description=report) em.set_author( name=_("Report from {author}{maybe_nick}").format( author=author, maybe_nick=(f" ({author.nick})" if author.nick else "") ), icon_url=author.avatar_url, ) em.set_footer(text=_("Report #{}").format(ticket_number)) send_content = None else: em = None send_content = _("Report from {author.mention} (Ticket #{number})").format( author=author, number=ticket_number ) send_content += "\n" + report try: await Tunnel.message_forwarder( destination=channel, content=send_content, embed=em, files=files ) except (discord.Forbidden, discord.HTTPException): return None await self.config.custom("REPORT", guild.id, ticket_number).report.set( {"user_id": author.id, "report": report} ) return ticket_number