Пример #1
0
    def __init__(self, config, session, executor, *args, **kwargs):
        self.channels = {}
        self.config = config
        self.session = session
        self.executor = executor
        self.sent_fallback = False

        self.trusted = remove_chars(config["Main"]["trusted_ids"], "[", "]",
                                    "'").split(", ")

        super().__init__(*args, **kwargs)
Пример #2
0
    async def voices(self, ctx, lang: str = None):
        if lang in tts_langs:
            try:
                return await self.voice(ctx, lang)
            except:
                return

        lang = setlangs.get(ctx.author)
        langs_string = basic.remove_chars(list(tts_langs.keys()), "[", "]")

        await ctx.send(
            f"My currently supported language codes are: \n{langs_string}\nAnd you are using: {tts_langs[lang]} | {lang}"
        )
Пример #3
0
    async def on_ready(self):
        global settings_loaded
        global last_cached_message

        if settings_loaded:
            await self.bot.close()

        self.bot.queue = dict()
        self.bot.playing = dict()
        self.bot.channels = dict()
        self.bot.trusted = basic.remove_chars(config["Main"]["trusted_ids"],
                                              "[", "]", "'").split(", ")
        self.bot.supportserver = self.bot.get_guild(
            int(config["Main"]["main_server"]))
        config_channel = config["Channels"]

        for channel_name in config_channel:
            channel_id = int(config_channel[channel_name])
            channel_object = self.bot.supportserver.get_channel(channel_id)
            self.bot.channels[channel_name] = channel_object

        print(f"Starting as {self.bot.user.name}!")
        starting_message = await self.bot.channels["logs"].send(
            f"Starting {self.bot.user.mention}")

        # Load some files
        with open("activity.txt") as f2, open("activitytype.txt") as f3, open(
                "status.txt") as f4:
            activity = f2.read()
            activitytype = f3.read()
            status = f4.read()

        activitytype1 = getattr(discord.ActivityType, activitytype)
        status1 = getattr(discord.Status, status)
        await self.bot.change_presence(status=status1,
                                       activity=discord.Activity(
                                           name=activity, type=activitytype1))

        for guild in self.bot.guilds:
            self.bot.playing[guild.id] = 0
            self.bot.queue[guild.id] = dict()

        self.avoid_file_crashes.start()

        ping = str(time.monotonic() - before).split(".")[0]
        await starting_message.edit(
            content=f"Started and ready! Took `{ping} seconds`")

        last_cached_message = await self.bot.channels["logs"].send(
            "Waiting to chunk a guild!")
Пример #4
0
    async def voices(self, ctx, lang=None):
        "Lists all the language codes that TTS bot accepts"
        if lang in tts_langs:
            return await self.voice(ctx, lang)

        lang = await self.bot.userinfo.get("lang", ctx.author).split("-")[0]
        langs_string = basic.remove_chars(list(tts_langs.keys()), "[", "]")

        embed = discord.Embed(title="TTS Bot Languages")
        embed.set_footer(text=pick_random(basic.footer_messages))
        embed.add_field(name="Currently Supported Languages", value=langs_string)
        embed.add_field(name="Current Language used", value=f"{tts_langs[lang]} | {lang}")
        embed.set_author(name=ctx.author.display_name, icon_url=str(ctx.author.avatar_url))

        await ctx.send(embed=embed)
Пример #5
0
    async def on_message(self, message):
        if message.channel.id == 749971061843558440 and message.embeds and str(
                message.author) == "GitHub#0000":
            print("Message is from a github webhook")
            if " new commit" in message.embeds[0].title:
                print("Message is a commit")
                update_for_main = message.embeds[0].title.startswith(
                    "[Discord-TTS-Bot:master]"
                ) and self.bot.user.id == 513423712582762502
                update_for_dev = message.embeds[0].title.startswith(
                    "[Discord-TTS-Bot:dev]"
                ) and self.bot.user.id == 698218518335848538
                cog_update = message.embeds[0].title.startswith(
                    "[Common-Cogs:master]")

                print(update_for_main, update_for_dev, cog_update,
                      "\n===============================================")

                if update_for_main or update_for_dev:
                    await self.bot.channels['logs'].send(
                        "Detected new bot commit! Pulling changes")
                    call(['git', 'pull'])
                    print("===============================================")
                    await self.bot.channels['logs'].send("Restarting bot...")
                    await self.end(message)

                elif cog_update:
                    await self.bot.channels['logs'].send(
                        "Detected new cog commit! Pulling changes")
                    call([
                        'git', 'submodule', 'update', '--recursive', '--remote'
                    ])
                    print("===============================================")
                    await self.bot.channels['logs'].send("Reloading cog...")

                    try:
                        self.bot.reload_extension("cogs.common_user")
                        self.bot.reload_extension("cogs.common_owner")
                        self.bot.reload_extension("cogs.common_trusted")
                    except Exception as e:
                        await self.bot.channels['logs'].send(
                            f"**`ERROR:`** {type(e).__name__} - {e}")
                    else:
                        await self.bot.channels['logs'].send('**`SUCCESS`**')

        elif message.guild is not None:
            saythis = message.clean_content.lower()

            # Get settings
            autojoin = settings.get(message.guild, "auto_join")
            bot_ignore = settings.get(message.guild, "bot_ignore")

            starts_with_tts = saythis.startswith("-tts")

            # if author is a bot and bot ignore is on
            if bot_ignore and message.author.bot:
                return

            # if not a webhook but still a user, return to fix errors
            if message.author.discriminator != "0000" and isinstance(
                    message.author, discord.User):
                return

            # if author is not a bot, and is not in a voice channel, and doesn't start with -tts
            if not message.author.bot and message.author.voice is None and starts_with_tts is False:
                return

            # if bot **not** in voice channel and autojoin **is off**, return
            if message.guild.voice_client is None and autojoin is False:
                return

            # Check if a setup channel
            if message.channel.id != settings.get(message.guild, "channel"):
                return

            # If message is **not** empty **or** there is an attachment
            if int(len(saythis)) != 0 or message.attachments:

                # Ignore messages starting with - that are probably commands (also advertised as a feature when it is wrong lol)
                if saythis.startswith(BOT_PREFIX) is False or starts_with_tts:

                    # This line :( | if autojoin is True **or** message starts with -tts **or** author in same voice channel as bot
                    if autojoin or starts_with_tts or message.author.bot or message.author.voice.channel == message.guild.voice_client.channel:

                        # Fixing values if not loaded
                        if message.guild.id not in self.bot.playing:
                            self.bot.playing[message.guild.id] = 0

                        # Auto Join
                        if message.guild.voice_client is None and autojoin and self.bot.playing[
                                message.guild.id] in (0, 1):
                            try:
                                channel = message.author.voice.channel
                            except AttributeError:
                                return

                            self.bot.playing[message.guild.id] = 3
                            await channel.connect()
                            self.bot.playing[message.guild.id] = 0

                        # Sometimes bot.guilds is wrong, because intents
                        if message.guild.id not in self.bot.queue:
                            self.bot.queue[message.guild.id] = dict()

                        # Emoji filter
                        saythis = basic.emojitoword(saythis)

                        # Acronyms and removing -tts
                        saythis = f" {saythis} "
                        acronyms = {
                            "@": " at ",
                            "irl": "in real life",
                            "gtg": " got to go ",
                            "iirc": "if I recall correctly",
                            "™️": "tm",
                            "rn": "right now",
                            "wdym": "what do you mean",
                            "imo": "in my opinion",
                            "uwu": "oowoo"
                        }

                        if starts_with_tts: acronyms["-tts"] = ""
                        for toreplace, replacewith in acronyms.items():
                            saythis = saythis.replace(f" {toreplace} ",
                                                      f" {replacewith} ")

                        saythis = saythis[1:-1]
                        if saythis == "?": saythis = "what"

                        # Regex replacements
                        regex_replacements = {
                            r"\|\|.*?\|\|": ". spoiler avoided.",
                            r"```.*?```": ". code block.",
                            r"`.*?`": ". code snippet.",
                        }

                        for regex, replacewith in regex_replacements.items():
                            saythis = re.sub(regex,
                                             replacewith,
                                             saythis,
                                             flags=re.DOTALL)

                        # Url filter
                        changed = False
                        for word in saythis.split(" "):
                            if word.startswith("https://") or word.startswith(
                                    "http://") or word.startswith("www."):
                                saythis = saythis.replace(word, "")
                                changed = True

                        if changed:
                            saythis += ". This message contained a link"

                        # Toggleable X said and attachment detection
                        if settings.get(message.guild, "xsaid"):
                            said_name = settings.nickname.get(
                                message.guild, message.author)
                            format = basic.exts_to_format(message.attachments)

                            if message.attachments:
                                if len(saythis) == 0:
                                    saythis = f"{said_name} sent {format}."
                                else:
                                    saythis = f"{said_name} sent {format} and said {saythis}"
                            else:
                                saythis = f"{said_name} said: {saythis}"

                        if basic.remove_chars(saythis, " ", "?", ".", ")", "'",
                                              '"') == "":
                            return

                        # Read language file
                        lang = setlangs.get(message.author)

                        try:
                            await self.get_tts(message, saythis, lang)
                        except (gTTS.tts.gTTSError, ValueError,
                                AssertionError):
                            return print(
                                f"Just skipped '{saythis}', sliently returned."
                            )

                        # Queue, please don't touch this, it works somehow
                        while self.bot.playing[message.guild.id] != 0:
                            if self.bot.playing[message.guild.id] == 2: return
                            await asyncio.sleep(0.5)

                        self.bot.playing[message.guild.id] = 1

                        while self.bot.queue[message.guild.id] != dict():
                            # Sort Queue
                            self.bot.queue[message.guild.id] = basic.sort_dict(
                                self.bot.queue[message.guild.id])

                            # Select first in queue
                            message_id_to_read = next(
                                iter(self.bot.queue[message.guild.id]))
                            selected = self.bot.queue[
                                message.guild.id][message_id_to_read]

                            # Play selected audio
                            vc = message.guild.voice_client
                            if vc is not None:
                                try:
                                    vc.play(
                                        FFmpegPCMAudio(
                                            selected,
                                            pipe=True,
                                            options='-loglevel "quiet"'))
                                except discord.errors.ClientException:
                                    pass  # sliences desyncs between discord.py and discord, implement actual fix soon!

                                while vc.is_playing():
                                    await asyncio.sleep(0.5)

                                # Delete said message from queue
                                if message_id_to_read in self.bot.queue[
                                        message.guild.id]:
                                    del self.bot.queue[
                                        message.guild.id][message_id_to_read]

                            else:
                                # If not in a voice channel anymore, clear the queue
                                self.bot.queue[message.guild.id] = dict()

                        # Queue should be empty now, let next on_message though
                        self.bot.playing[message.guild.id] = 0

        elif message.author.bot is False:
            pins = await message.author.pins()

            if [
                    True for pinned_message in pins
                    if pinned_message.embeds and pinned_message.embeds[0].title
                    == f"Welcome to {self.bot.user.name} Support DMs!"
            ]:
                if "https://discord.gg/" in message.content.lower():
                    await message.author.send(
                        f"Join https://discord.gg/zWPWwQC and look in <#694127922801410119> to invite {self.bot.user.mention}!"
                    )

                elif not blocked_users.check(message.author):
                    files = [
                        await attachment.to_file()
                        for attachment in message.attachments
                    ]
                    webhook = await basic.ensure_webhook(
                        self.bot.channels["dm_logs"], name="TTS-DM-LOGS")

                    if not files and not message.content: return
                    await webhook.send(message.content,
                                       username=str(message.author),
                                       avatar_url=message.author.avatar_url,
                                       files=files)

            else:
                if len(pins) >= 49:
                    return await message.channel.send(
                        "Error: Pinned messages are full, cannot pin the Welcome to Support DMs message!"
                    )

                embed_message = cleandoc("""
                    **All messages after this will be sent to a private channel on the support server (-invite) where we can assist you.**
                    Please keep in mind that we aren't always online and get a lot of messages, so if you don't get a response within a day, repeat your message.
                    There are some basic rules if you want to get help though:
                    `1.` Ask your question, don't just ask for help
                    `2.` Don't spam, troll, or send random stuff (including server invites)
                    `3.` Many questions are answered in `-help`, try that first (also the prefix is `-`)
                """)

                embed = discord.Embed(
                    title=f"Welcome to {self.bot.user.name} Support DMs!",
                    description=embed_message)
                dm_message = await message.author.send(
                    "Please do not unpin this notice, if it is unpinned you will get the welcome message again!",
                    embed=embed)

                await self.bot.channels["logs"].send(
                    f"{str(message.author)} just got the 'Welcome to Support DMs' message"
                )
                await dm_message.pin()
Пример #6
0
status = getattr(discord.Status, config["Activity"]["status"])

bot = commands.AutoShardedBot(
    status=status,
    intents=intents,
    activity=activity,
    case_insensitive=True,
    command_prefix=BOT_PREFIX,
    chunk_guilds_at_startup=False,
)

bot.queue = dict()
bot.playing = dict()
bot.channels = dict()
bot.chunk_queue = list()
bot.trusted = basic.remove_chars(config["Main"]["trusted_ids"], "[", "]",
                                 "'").split(", ")

if exists("cogs/common_user.py"):
    bot.load_extension("cogs.common_owner")
    bot.load_extension("cogs.common_trusted")
    bot.load_extension("cogs.common_user")
elif exists("cogs/common.py"):
    bot.load_extension("cogs.common")
else:
    print(
        "Error: Cannot find cogs to load? Did you do 'git clone --recurse-submodules'?"
    )
    raise SystemExit

for overwriten_command in ("help", "end", "botstats"):
    bot.remove_command(overwriten_command)
Пример #7
0
    async def on_message(self, message):
        if message.guild is not None:
            # Get settings
            repeated_chars_limit, bot_ignore, max_length, autojoin, channel, prefix, xsaid = await self.bot.settings.get(
                message.guild,
                settings=(
                    "repeated_chars",
                    "bot_ignore",
                    "msg_length",
                    "auto_join",
                    "channel",
                    "prefix",
                    "xsaid",
                ))

            message_clean = message.clean_content.lower()
            starts_with_tts = message_clean.startswith(f"{prefix}tts")

            # if author is a bot and bot ignore is on
            if bot_ignore and message.author.bot:
                return

            # if not a webhook but still a user, return to fix errors
            if message.author.discriminator != "0000" and isinstance(
                    message.author, discord.User):
                return

            # if author is not a bot, and is not in a voice channel, and doesn't start with -tts
            if not message.author.bot and not message.author.voice and not starts_with_tts:
                return

            # if bot not in voice channel and autojoin is off
            if not message.guild.voice_client and not autojoin:
                return

            # Check if a setup channel
            if message.channel.id != channel:
                return

            # If message is empty and there is no attachments
            if not message_clean and not message.attachments:
                return

            # Ignore messages starting with -
            if message_clean.startswith(prefix) and not starts_with_tts:
                return

            # if not autojoin and message doesn't start with tts and the author isn't a bot and the author is in the wrong voice channel
            if not autojoin and not starts_with_tts and not message.author.bot and message.author.voice.channel != message.guild.voice_client.channel:
                return

            # Auto Join
            if not message.guild.voice_client and autojoin:
                try:
                    voice_channel = message.author.voice.channel
                except AttributeError:
                    return

                await voice_channel.connect(cls=TTSVoicePlayer)

            # Get lang
            lang = await self.bot.userinfo.get("lang",
                                               message.author,
                                               default="en")

            # Emoji filter
            message_clean = basic.emojitoword(message_clean)

            # Acronyms and removing -tts
            message_clean = f" {message_clean} "
            acronyms = {
                "iirc": "if I recall correctly",
                "afaik": "as far as I know",
                "wdym": "what do you mean",
                "imo": "in my opinion",
                "brb": "be right back",
                "irl": "in real life",
                "jk": "just kidding",
                "btw": "by the way",
                ":)": "smiley face",
                "gtg": "got to go",
                "rn": "right now",
                ":(": "sad face",
                "ig": "i guess",
                "rly": "really",
                "cya": "see ya",
                "ik": "i know",
                "uwu": "oowoo",
                "@": "at",
                "™️": "tm"
            }

            if starts_with_tts:
                acronyms[f"{prefix}tts"] = ""

            for toreplace, replacewith in acronyms.items():
                message_clean = message_clean.replace(f" {toreplace} ",
                                                      f" {replacewith} ")

            message_clean = message_clean[1:-1]
            if message_clean == "?":
                message_clean = "what"

            # Regex replacements
            regex_replacements = {
                r"\|\|.*?\|\|": ". spoiler avoided.",
                r"```.*?```": ". code block.",
                r"`.*?`": ". code snippet.",
            }

            for regex, replacewith in regex_replacements.items():
                message_clean = re.sub(regex,
                                       replacewith,
                                       message_clean,
                                       flags=re.DOTALL)

            # Url filter
            with_urls = message_clean
            link_starters = ("https://", "http://", "www.")
            message_clean = " ".join(
                w if not w.startswith(link_starters) else ""
                for w in with_urls.split())

            contained_url = message_clean != with_urls
            # Toggleable xsaid and attachment + links detection
            if xsaid:
                said_name = await self.bot.nicknames.get(
                    message.guild, message.author)
                file_format = basic.exts_to_format(message.attachments)

                if contained_url:
                    if message_clean:
                        message_clean += " and sent a link."
                    else:
                        message_clean = "a link."

                if message.attachments:
                    if not message_clean:
                        message_clean = f"{said_name} sent {file_format}"
                    else:
                        message_clean = f"{said_name} sent {file_format} and said {message_clean}"
                else:
                    message_clean = f"{said_name} said: {message_clean}"

            elif contained_url:
                if message_clean:
                    message_clean += ". This message contained a link"
                else:
                    message_clean = "a link."

            if basic.remove_chars(message_clean, " ", "?", ".", ")", "'", "!",
                                  '"', ":") == "":
                return

            # Repeated chars removal if setting is not 0
            if message_clean.isprintable() and repeated_chars_limit != 0:
                message_clean_list = list()
                message_clean_chars = [
                    "".join(grp) for num, grp in groupby(message_clean)
                ]

                for char in message_clean_chars:
                    if len(char) > repeated_chars_limit:
                        message_clean_list.append(char[0] *
                                                  repeated_chars_limit)
                    else:
                        message_clean_list.append(char)

                message_clean = "".join(message_clean_list)

            # Adds filtered message to queue
            await message.guild.voice_client.queue(message, message_clean,
                                                   lang, channel, prefix,
                                                   max_length)

        elif not (message.author.bot or message.content.startswith("-")):
            pins = self.dm_pins.get(message.author.id, None)
            if not pins:
                self.dm_pins[
                    message.author.id] = pins = await message.author.pins()

            if any(map(self.is_welcome_message, pins)):
                if "https://discord.gg/" in message.content.lower():
                    await message.author.send(
                        f"Join https://discord.gg/zWPWwQC and look in <#694127922801410119> to invite {self.bot.user.mention}!"
                    )

                elif message.content.lower() == "help":
                    await asyncio.gather(
                        self.bot.channels["logs"].send(
                            f"{message.author} just got the 'dont ask to ask' message"
                        ),
                        message.channel.send(
                            "We cannot help you unless you ask a question, if you want the help command just do `-help`!"
                        ))

                elif not await self.bot.userinfo.get(
                        "blocked", message.author, default=False):
                    if not message.attachments and not message.content:
                        return

                    files = [
                        await attachment.to_file()
                        for attachment in message.attachments
                    ]
                    await self.bot.channels["dm_logs"].send(
                        message.content,
                        files=files,
                        username=str(message.author),
                        avatar_url=message.author.avatar_url)

            else:
                if len(pins) >= 49:
                    return await message.channel.send(
                        "Error: Pinned messages are full, cannot pin the Welcome to Support DMs message!"
                    )

                embed = discord.Embed(
                    title=f"Welcome to {self.bot.user.name} Support DMs!",
                    description=DM_WELCOME_MESSAGE).set_footer(
                        text=pick_random(basic.footer_messages))

                dm_message = await message.author.send(
                    "Please do not unpin this notice, if it is unpinned you will get the welcome message again!",
                    embed=embed)

                await asyncio.gather(
                    self.bot.channels["logs"].send(
                        f"{message.author} just got the 'Welcome to Support DMs' message"
                    ), dm_message.pin())
Пример #8
0
    async def on_message(self, message):
        if message.guild is not None:
            saythis = message.clean_content.lower()

            # Get settings
            autojoin, bot_ignore, channel = await self.bot.settings.get(
                message.guild, settings=("auto_join", "bot_ignore", "channel"))

            starts_with_tts = saythis.startswith(
                f"{self.bot.command_prefix}tts")

            # if author is a bot and bot ignore is on
            if bot_ignore and message.author.bot:
                return

            # if not a webhook but still a user, return to fix errors
            if message.author.discriminator != "0000" and isinstance(
                    message.author, discord.User):
                return

            # if author is not a bot, and is not in a voice channel, and doesn't start with -tts
            if not message.author.bot and not message.author.voice and not starts_with_tts:
                return

            # if bot not in voice channel and autojoin is off
            if not message.guild.voice_client and not autojoin:
                return

            # Check if a setup channel
            if message.channel.id != int(channel):
                return

            # If message is empty and there is no attachments
            if not saythis and not message.attachments:
                return

            # Ignore messages starting with -
            if saythis.startswith(
                    self.bot.command_prefix) and not starts_with_tts:
                return

            # if not autojoin and message doesn't start with tts and the author isn't a bot and the author is in the wrong voice channel
            if not autojoin and not starts_with_tts and not message.author.bot and message.author.voice.channel != message.guild.voice_client.channel:
                return

            # Fix values
            if message.guild.id not in self.bot.queue:
                self.bot.queue[message.guild.id] = dict()
            if message.guild.id not in self.bot.message_locks:
                self.bot.message_locks[message.guild.id] = asyncio.Lock()

            should_return = self.bot.should_return.get(message.guild.id)

            # Auto Join
            if message.guild.voice_client is None and autojoin and not should_return:
                try:
                    channel = message.author.voice.channel
                except AttributeError:
                    return

                self.bot.should_return[message.guild.id] = True
                await channel.connect()
                self.bot.should_return[message.guild.id] = False

            # Get settings
            lang = await self.bot.setlangs.get(message.author)
            xsaid, repeated_chars_limit, msg_length = await self.bot.settings.get(
                message.guild,
                settings=("xsaid", "repeated_chars", "msg_length"))

            # Emoji filter
            saythis = basic.emojitoword(saythis)

            # Acronyms and removing -tts
            saythis = f" {saythis} "
            acronyms = {
                "iirc": "if I recall correctly",
                "afaik": "as far as I know",
                "wdym": "what do you mean",
                "imo": "in my opinion",
                "brb": "be right back",
                "irl": "in real life",
                "jk": "just kidding",
                "btw": "by the way",
                ":)": "smiley face",
                "gtg": "got to go",
                "rn": "right now",
                ":(": "sad face",
                "ig": "i guess",
                "rly": "really",
                "cya": "see ya",
                "ik": "i know",
                "uwu": "oowoo",
                "@": "at",
                "™️": "tm"
            }

            if starts_with_tts:
                acronyms["-tts"] = ""

            for toreplace, replacewith in acronyms.items():
                saythis = saythis.replace(f" {toreplace} ", f" {replacewith} ")

            saythis = saythis[1:-1]
            if saythis == "?":
                saythis = "what"

            # Regex replacements
            regex_replacements = {
                r"\|\|.*?\|\|": ". spoiler avoided.",
                r"```.*?```": ". code block.",
                r"`.*?`": ". code snippet.",
            }

            for regex, replacewith in regex_replacements.items():
                saythis = re.sub(regex, replacewith, saythis, flags=re.DOTALL)

            # Url filter
            contained_url = False
            for word in saythis.split(" "):
                if word.startswith(("https://", "http://", "www.")):
                    saythis = saythis.replace(word, "")
                    contained_url = True

            # Toggleable xsaid and attachment + links detection
            if xsaid:
                said_name = await self.bot.nicknames.get(
                    message.guild, message.author)
                format = basic.exts_to_format(message.attachments)

                if contained_url:
                    if saythis:
                        saythis += " and sent a link."
                    else:
                        saythis = "a link."

                if message.attachments:
                    if not saythis:
                        saythis = f"{said_name} sent {format}"
                    else:
                        saythis = f"{said_name} sent {format} and said {saythis}"
                else:
                    saythis = f"{said_name} said: {saythis}"

            elif contained_url:
                if saythis:
                    saythis += ". This message contained a link"
                else:
                    saythis = "a link."

            if basic.remove_chars(saythis, " ", "?", ".", ")", "'", "!",
                                  '"') == "":
                return

            # Repeated chars removal if setting is not 0
            repeated_chars_limit = int(repeated_chars_limit)
            if saythis.isprintable() and repeated_chars_limit != 0:
                saythis_chars = ["".join(grp) for num, grp in groupby(saythis)]
                saythis_list = list()

                for char in saythis_chars:
                    if len(char) > repeated_chars_limit:
                        saythis_list.append(char[0] * repeated_chars_limit)
                    else:
                        saythis_list.append(char)

                saythis = "".join(saythis_list)

            # Adds filtered message to queue
            try:
                await self.get_tts(message, saythis, lang, msg_length)
            except ValueError:
                return print(f"Run out of attempts generating {saythis}.")
            except AssertionError:
                return print(f"Skipped {saythis}, apparently blank message.")

            async with self.bot.message_locks[message.guild.id]:
                if self.bot.should_return[message.guild.id]:
                    return

                while self.bot.queue.get(message.guild.id) not in (dict(),
                                                                   None):
                    # Sort Queue
                    self.bot.queue[message.guild.id] = basic.sort_dict(
                        self.bot.queue[message.guild.id])

                    # Select first in queue
                    message_id_to_read = next(
                        iter(self.bot.queue[message.guild.id]))
                    selected = self.bot.queue[
                        message.guild.id][message_id_to_read]

                    # Play selected audio
                    vc = message.guild.voice_client
                    if vc:
                        self.bot.currently_playing[
                            message.guild.id] = self.bot.loop.create_future()
                        finish_future = make_func(
                            self.finish_future,
                            self.bot.currently_playing[message.guild.id])

                        try:
                            vc.play(FFmpegPCMAudio(
                                selected,
                                pipe=True,
                                options='-loglevel "quiet"'),
                                    after=finish_future)
                        except discord.errors.ClientException:
                            self.bot.currently_playing[
                                message.guild.id].set_result("done")

                        try:
                            result = await asyncio.wait_for(
                                self.bot.currently_playing[message.guild.id],
                                timeout=int(msg_length) + 1)
                        except asyncio.TimeoutError:
                            await self.bot.channels["errors"].send(
                                f"```asyncio.TimeoutError``` Future Failed to be finished in guild: `{message.guild.id}`"
                            )
                            result = "failed"

                        if result == "skipped":
                            self.bot.queue[message.guild.id] = dict()

                        # Delete said message from queue
                        elif message_id_to_read in self.bot.queue.get(
                                message.guild.id, ()):
                            del self.bot.queue[
                                message.guild.id][message_id_to_read]

                    else:
                        # If not in a voice channel anymore, clear the queue
                        self.bot.queue[message.guild.id] = dict()

        elif not message.author.bot:
            pins = await message.author.pins()

            if [
                    True for pinned_message in pins
                    if pinned_message.embeds and pinned_message.embeds[0].title
                    == f"Welcome to {self.bot.user.name} Support DMs!"
            ]:
                if "https://discord.gg/" in message.content.lower():
                    await message.author.send(
                        f"Join https://discord.gg/zWPWwQC and look in <#694127922801410119> to invite {self.bot.user.mention}!"
                    )

                elif message.content.lower() == "help":
                    await message.channel.send(
                        "We cannot help you unless you ask a question, if you want the help command just do `-help`!"
                    )
                    await self.bot.channels["logs"].send(
                        f"{message.author} just got the 'dont ask to ask' message"
                    )

                elif not await self.bot.blocked_users.check(message.author):
                    files = [
                        await attachment.to_file()
                        for attachment in message.attachments
                    ]
                    if not files and not message.content:
                        return

                    webhook = await basic.ensure_webhook(
                        self.bot.channels["dm_logs"], name="TTS-DM-LOGS")
                    await webhook.send(message.content,
                                       username=str(message.author),
                                       avatar_url=message.author.avatar_url,
                                       files=files)

            else:
                if len(pins) >= 49:
                    return await message.channel.send(
                        "Error: Pinned messages are full, cannot pin the Welcome to Support DMs message!"
                    )

                embed_message = cleandoc("""
                    **All messages after this will be sent to a private channel where we can assist you.**
                    Please keep in mind that we aren't always online and get a lot of messages, so if you don't get a response within a day repeat your message.
                    There are some basic rules if you want to get help though:
                    `1.` Ask your question, don't just ask for help
                    `2.` Don't spam, troll, or send random stuff (including server invites)
                    `3.` Many questions are answered in `-help`, try that first (also the prefix is `-`)
                """)

                embed = discord.Embed(
                    title=f"Welcome to {self.bot.user.name} Support DMs!",
                    description=embed_message)
                embed.set_footer(text=pick_random(basic.footer_messages))

                dm_message = await message.author.send(
                    "Please do not unpin this notice, if it is unpinned you will get the welcome message again!",
                    embed=embed)

                await self.bot.channels["logs"].send(
                    f"{message.author} just got the 'Welcome to Support DMs' message"
                )
                await dm_message.pin()