Example #1
0
    async def convert(self, ctx: Context, server_invite: str) -> dict:
        """Check whether the string is a valid Discord server invite."""
        invite_code = INVITE_RE.search(server_invite)
        if invite_code:
            response = await ctx.bot.http_session.get(
                f"{URLs.discord_invite_api}/{invite_code[1]}"
            )
            if response.status != 404:
                invite_data = await response.json()
                return invite_data.get("guild")

        id_converter = IDConverter()
        if id_converter._get_id_match(server_invite):
            raise BadArgument("Guild IDs are not supported, only invites.")

        raise BadArgument("This does not appear to be a valid Discord server invite.")
Example #2
0
    async def _has_invites(self, text: str) -> Union[dict, bool]:
        """
        Checks if there's any invites in the text content that aren't in the guild whitelist.

        If any are detected, a dictionary of invite data is returned, with a key per invite.
        If none are detected, False is returned.

        Attempts to catch some of common ways to try to cheat the system.
        """
        text = self.clean_input(text)

        # Remove backslashes to prevent escape character aroundfuckery like
        # discord\.gg/gdudes-pony-farm
        text = text.replace("\\", "")

        invites = [m.group("invite") for m in INVITE_RE.finditer(text)]
        invite_data = dict()
        for invite in invites:
            if invite in invite_data:
                continue

            response = await self.bot.http_session.get(
                f"{URLs.discord_invite_api}/{invite}",
                params={"with_counts": "true"})
            response = await response.json()
            guild = response.get("guild")
            if guild is None:
                # Lack of a "guild" key in the JSON response indicates either an group DM invite, an
                # expired invite, or an invalid invite. The API does not currently differentiate
                # between invalid and expired invites
                return True

            guild_id = guild.get("id")
            guild_invite_whitelist = self._get_filterlist_items("guild_invite",
                                                                allowed=True)
            guild_invite_blacklist = self._get_filterlist_items("guild_invite",
                                                                allowed=False)

            # Is this invite allowed?
            guild_partnered_or_verified = ('PARTNERED' in guild.get(
                "features", []) or 'VERIFIED' in guild.get("features", []))
            invite_not_allowed = (
                guild_id in
                guild_invite_blacklist  # Blacklisted guilds are never permitted.
                or guild_id not in
                guild_invite_whitelist  # Whitelisted guilds are always permitted.
                and
                not guild_partnered_or_verified  # Otherwise guilds have to be Verified or Partnered.
            )

            if invite_not_allowed:
                reason = None
                if guild_id in guild_invite_blacklist:
                    reason = self._get_filterlist_value(
                        "guild_invite", guild_id, allowed=False)["comment"]

                guild_icon_hash = guild["icon"]
                guild_icon = ("https://cdn.discordapp.com/icons/"
                              f"{guild_id}/{guild_icon_hash}.png?size=512")

                invite_data[invite] = {
                    "name": guild["name"],
                    "id": guild['id'],
                    "icon": guild_icon,
                    "members": response["approximate_member_count"],
                    "active": response["approximate_presence_count"],
                    "reason": reason
                }

        return invite_data if invite_data else False