Exemple #1
0
 async def bot_welcome(self, member, guild):
     bot_welcome = await self.config.guild(guild).BOTS_MSG()
     bot_role = await self.config.guild(guild).BOTS_ROLE()
     msg = bot_welcome or rand_choice(await
                                      self.config.guild(guild).GREETING())
     channel = await self.get_welcome_channel(member, guild)
     is_embed = await self.config.guild(guild).EMBED()
     if bot_role:
         try:
             role = guild.get_role(bot_role)
             await member.add_roles(role)
         except Exception:
             log.error(_("welcome.py: unable to add  a role. ") +
                       f"{bot_role} {member}",
                       exc_info=True)
         else:
             log.debug(
                 _("welcome.py: added ") + str(role) + _(" role to ") +
                 _("bot, ") + str(member))
     if bot_welcome:
         # finally, welcome them
         if is_embed and channel.permissions_for(guild.me).embed_links:
             em = await self.make_embed(member, guild, msg, False)
             if await self.config.guild(guild).EMBED_DATA.mention():
                 await channel.send(member.mention, embed=em)
             else:
                 await channel.send(embed=em)
         else:
             await channel.send(
                 filter_mass_mentions(await self.convert_parms(
                     member, guild, bot_welcome, False)))
Exemple #2
0
async def type_message(destination: discord.abc.Messageable, content: str,
                       **kwargs) -> discord.Message:
    """Simulate typing and sending a message to a destination.

    Will send a typing indicator, wait a variable amount of time based on the length
    of the text (to simulate typing speed), then send the message.
    """
    content = common_filters.filter_mass_mentions(content)
    content = common_filters.filter_urls(content)
    content = common_filters.filter_various_mentions(content)
    try:
        async with destination.typing():
            await asyncio.sleep(len(content) * 0.01)
            return await destination.send(content=content, **kwargs)
    except discord.HTTPException:
        pass  # Not allowed to send messages to this destination (or, sending the message failed)
Exemple #3
0
 async def process_message(self, rift, message, destination):
     if isinstance(destination, discord.Message):
         send_coro = destination.edit
     else:
         send_coro = destination.send
     channel = (
         message.author if isinstance(message.channel, discord.DMChannel) else message.channel
     )
     send = channel == rift.source
     destination = rift.destination if send else rift.source
     author = message.author
     me = (
         destination.dm_channel.me
         if isinstance(destination, discord.User)
         else destination.guild.me
     )
     is_owner = await self.bot.is_owner(author)
     author_perms = self.permissions(destination, author, is_owner)
     bot_perms = self.permissions(destination, me)
     content = message.content
     if not is_owner:
         if not author_perms.administrator:
             content = common_filters.filter_invites(content)
         if not author_perms.mention_everyone:
             content = common_filters.filter_mass_mentions(content)
     attachments = message.attachments
     files = []
     embed = None
     if attachments and author_perms.attach_files and bot_perms.attach_files:
         overs = await asyncio.gather(*(self.save_attach(file, files) for file in attachments))
         overs = list(filter(bool, overs))
         if overs:
             if bot_perms.embed_links:
                 embed = await self.get_embed(destination, overs)
             else:
                 content += (
                     "\n\n"
                     + _("Attachments:")
                     + "\n"
                     + "\n".join(f"({self.xbytes(a.size)}) {a.url}" for a in attachments)
                 )
     if not any((content, files, embed)):
         raise RiftError(_("No content to send."))
     if not is_owner or not send:
         content = f"{author}: {content}"
     return await send_coro(content=content, files=files, embed=embed)
Exemple #4
0
 async def process_message(self, rift, message, destination):
     if isinstance(destination, discord.Message):
         send_coro = destination.edit
     else:
         send_coro = destination.send
     channel = (
         message.author if isinstance(message.channel, discord.DMChannel) else message.channel
     )
     send = channel == rift.source
     destination = rift.destination if send else rift.source
     source = rift.source if send else rift.destination
     author = message.author
     me = (
         destination.dm_channel.me
         if isinstance(destination, discord.User)
         else destination.guild.me
     )
     is_owner = await self.bot.is_owner(author)
     author_perms = self.permissions(destination, author, is_owner)
     bot_perms = self.permissions(destination, me)
     content = message.content
     if not is_owner:
         if not author_perms.administrator:
             content = common_filters.filter_invites(content)
         if not author_perms.mention_everyone:
             content = common_filters.filter_mass_mentions(content)
     attachments = message.attachments
     files = []
     embed = None
     if attachments and author_perms.attach_files and bot_perms.attach_files:
         overs = await asyncio.gather(*(self.save_attach(file, files) for file in attachments))
         overs = list(filter(bool, overs))
         if overs:
             content += (
                 "\n\n"
                 + _("Attachments:")
                 + "\n"
                 + "\n".join(f"({self.xbytes(a.size)}) {a.url}" for a in attachments)
             )
     if not any((content, files, embed)):
         raise RiftError(_("No content to send."))
     msg_embed = await self.create_message_embed(ctx=message, source=source, content=content, files=attachments)
     return await send_coro(embed=msg_embed)
Exemple #5
0
 async def send_testing_msg(self,
                            ctx: commands.Context,
                            bot: bool = False,
                            msg: str = None,
                            leave: bool = False) -> None:
     # log.info(leave)
     default_greeting = "Welcome {0.name} to {1.name}!"
     default_goodbye = "See you later {0.name}!"
     default_bot_msg = "Hello {0.name}, fellow bot!"
     guild = ctx.message.guild
     guild_settings = await self.config.guild(guild).get_raw()
     # log.info(guild_settings)
     channel = guild.get_channel(guild_settings["CHANNEL"])
     if leave:
         channel = guild.get_channel(guild_settings["LEAVE_CHANNEL"])
     rand_msg = msg or rand_choice(guild_settings["GREETING"])
     if leave:
         rand_msg = msg or rand_choice(guild_settings["GOODBYE"])
     if bot:
         rand_msg = guild_settings["BOTS_MSG"]
     if rand_msg is None and msg is None:
         rand_msg = default_greeting
     if rand_msg is None and bot:
         rand_msg = default_bot_msg
     if rand_msg is None and leave:
         rand_msg = default_goodbye
     is_welcome = not leave
     is_embed = guild_settings["EMBED"]
     member = ctx.message.author
     whisper_settings = guild_settings["WHISPER"]
     if channel is None and whisper_settings not in ["BOTH", True]:
         msg = _(
             "I can't find the specified channel. It might have been deleted."
         )
         await ctx.send(msg)
         return
     if channel is None:
         await ctx.send(_("`Sending a testing message to ") + "` DM")
     else:
         await ctx.send(
             _("`Sending a testing message to ") +
             "`{0.mention}".format(channel))
     if not bot and guild_settings["WHISPER"]:
         if is_embed:
             em = await self.make_embed(member, guild, rand_msg, is_welcome)
             await ctx.author.send(embed=em, delete_after=60)
         else:
             await ctx.author.send(await self.convert_parms(
                 member, guild, rand_msg, is_welcome),
                                   delete_after=60)
         if guild_settings["WHISPER"] != "BOTH":
             return
     if bot or whisper_settings is not True:
         if not channel:
             return
         if guild_settings["GROUPED"]:
             member = [ctx.author, ctx.me]
         if is_embed and channel.permissions_for(guild.me).embed_links:
             em = await self.make_embed(member, guild, rand_msg, is_welcome)
             if await self.config.guild(guild).EMBED_DATA.mention():
                 if guild_settings["GROUPED"]:
                     await channel.send(humanize_list(
                         [m.mention for m in member]),
                                        embed=em,
                                        delete_after=60)
                 else:
                     await channel.send(member.mention,
                                        embed=em,
                                        delete_after=60)
             else:
                 await channel.send(embed=em, delete_after=60)
         else:
             await channel.send(
                 filter_mass_mentions(await self.convert_parms(
                     member, guild, rand_msg, is_welcome)),
                 delete_after=60,
             )
Exemple #6
0
    async def on_member_remove(self, member: discord.Member) -> None:
        guild = member.guild
        if not await self.config.guild(guild).LEAVE_ON():
            return
        if guild is None:
            return
        if version_info >= VersionInfo.from_str("3.4.0"):
            if await self.bot.cog_disabled_in_guild(self, guild):
                return
        if await self.config.guild(guild).GROUPED():
            if guild.id not in self.joined:
                self.joined[guild.id] = []
            if member in self.joined[guild.id]:
                self.joined[guild.id].remove(member)
            return

        bot_welcome = member.bot and await self.config.guild(guild).BOTS_MSG()
        msg = bot_welcome or rand_choice(await
                                         self.config.guild(guild).GOODBYE())
        is_embed = await self.config.guild(guild).EMBED()
        delete_after = await self.config.guild(guild).DELETE_AFTER_GOODBYE()
        save_msg = None

        # grab the welcome channel
        # guild_settings = await self.config.guild(guild).guild_settings()
        channel = self.bot.get_channel(
            await self.config.guild(guild).LEAVE_CHANNEL())
        if channel is None:  # complain even if only whisper
            log.info(
                _("welcome.py: Channel not found in {guild}. It was most likely deleted."
                  ).format(guild=guild))
            return
        # we can stop here
        if await self.config.guild(guild).DELETE_PREVIOUS_GOODBYE():
            old_id = await self.config.guild(guild).LAST_GOODBYE()
            if channel is not None and old_id is not None:
                try:
                    old_msg = await channel.fetch_message(old_id)
                    await old_msg.delete()
                except discord.errors.NotFound:
                    log.debug(_("Message not found for deletion."))
                    pass
                except discord.errors.Forbidden:
                    await self.config.guild(guild).DELETE_PREVIOUS_GOODBYE.set(
                        False)

        if not channel.permissions_for(guild.me).send_messages:
            log.info(_("Permissions Error in {guild}"))
            return
        elif not member.bot:
            if is_embed and channel.permissions_for(guild.me).embed_links:
                em = await self.make_embed(member, guild, msg, False)
                if await self.config.guild(guild).EMBED_DATA.mention():
                    save_msg = await channel.send(member.mention,
                                                  embed=em,
                                                  delete_after=delete_after)
                else:
                    save_msg = await channel.send(embed=em,
                                                  delete_after=delete_after)
            else:
                save_msg = await channel.send(
                    filter_mass_mentions(await self.convert_parms(
                        member, guild, msg, False)),
                    delete_after=delete_after,
                )
        if save_msg is not None:
            await self.config.guild(guild).LAST_GOODBYE.set(save_msg.id)
Exemple #7
0
    async def send_member_join(self, member: Union[discord.Member,
                                                   List[discord.Member]],
                               guild: discord.Guild) -> None:
        only_whisper = await self.config.guild(guild).WHISPER() is True
        channel = await self.get_welcome_channel(member, guild)
        msg = rand_choice(await self.config.guild(guild).GREETING())
        is_embed = await self.config.guild(guild).EMBED()
        delete_after = await self.config.guild(guild).DELETE_AFTER_GREETING()
        save_msg = None

        if await self.config.guild(guild).DELETE_PREVIOUS_GREETING():
            old_id = await self.config.guild(guild).LAST_GREETING()
            if channel is not None and old_id is not None:
                try:
                    old_msg = await channel.fetch_message(old_id)
                    await old_msg.delete()
                except discord.errors.NotFound:
                    pass
                except discord.errors.Forbidden:
                    await self.config.guild(
                        guild).DELETE_PREVIOUS_GREETING.set(False)
        # whisper the user if needed
        if not await self.config.guild(guild).GROUPED():
            if await self.config.guild(guild).WHISPER():
                try:
                    if is_embed:
                        em = await self.make_embed(member, guild, msg, True)
                        if await self.config.guild(guild).EMBED_DATA.mention():
                            await member.send(member.mention,
                                              embed=em)  # type: ignore
                        else:
                            await member.send(embed=em)  # type: ignore
                    else:
                        await member.send(await self.convert_parms(
                            member, guild, msg, False))  # type: ignore
                except discord.errors.Forbidden:
                    log.info(
                        _("welcome.py: unable to whisper a user. Probably "
                          "doesn't want to be PM'd") + str(member))
                except Exception:
                    log.error("error sending member join message",
                              exc_info=True)
        if only_whisper:
            return
        if not channel:
            return
        if is_embed and channel.permissions_for(guild.me).embed_links:
            em = await self.make_embed(member, guild, msg, True)
            if await self.config.guild(guild).EMBED_DATA.mention():
                if await self.config.guild(guild).GROUPED():
                    members = cast(List[discord.Member], member)
                    save_msg = await channel.send(
                        humanize_list([m.mention for m in members]),
                        embed=em,
                        delete_after=delete_after,
                    )
                else:
                    member = cast(discord.Member, member)
                    save_msg = await channel.send(str(member.mention),
                                                  embed=em,
                                                  delete_after=delete_after)
            else:
                save_msg = await channel.send(embed=em,
                                              delete_after=delete_after)
        else:
            save_msg = await channel.send(
                filter_mass_mentions(await self.convert_parms(
                    member, guild, msg, True)),
                delete_after=delete_after,
            )
        if save_msg is not None:
            await self.config.guild(guild).LAST_GREETING.set(save_msg.id)
Exemple #8
0
    async def translate_message(
            self,
            message: discord.Message,
            flag: str,
            reacted_user: Optional[discord.Member] = None) -> None:
        guild = cast(discord.Guild, message.guild)
        channel = cast(discord.TextChannel, message.channel)
        if message.id in self.cache["cooldown_translations"]:
            if str(flag) in self.cache["cooldown_translations"][
                    message.id]["past_flags"]:
                return
            if not self.cache["cooldown_translations"][message.id]["multiple"]:
                return
            if time.time() < self.cache["cooldown_translations"][
                    message.id]["wait"]:
                delete_after = (
                    self.cache["cooldown_translations"][message.id]["wait"] -
                    time.time())
                await channel.send(_("You're translating too many messages!"),
                                   delete_after=delete_after)
                return
        if message.embeds != []:
            if message.embeds[0].description:
                to_translate = cast(str, message.embeds[0].description)
        else:
            to_translate = message.clean_content
        num_emojis = 0
        for reaction in message.reactions:
            if reaction.emoji == str(flag):
                num_emojis = reaction.count
        if num_emojis > 1:
            return
        target = FLAGS[str(flag)]["code"]
        try:
            detected_lang = await self.detect_language(to_translate)
            await self.add_detect(guild)
        except GoogleTranslateAPIError:
            return
        except Exception:
            log.exception("Error detecting language")
            return
        original_lang = detected_lang[0][0]["language"]
        if target == original_lang:
            return
        try:
            translated_text = filter_mass_mentions(await self.translate_text(
                original_lang, target, to_translate))
            await self.add_requests(guild, to_translate)
        except Exception:
            log.exception("Error translating message")
            return
        if not translated_text:
            return
        author = message.author
        from_lang = detected_lang[0][0]["language"].upper()
        to_lang = target.upper()
        if from_lang == to_lang:
            # don't post anything if the detected language is the same
            return
        translation = (translated_text, from_lang, to_lang)

        if message.id not in self.cache["cooldown_translations"]:
            if not self.cache["cooldown"]:
                self.cache["cooldown"] = await self.config.cooldown()
            cooldown = deepcopy(self.cache["cooldown"])
        else:
            cooldown = self.cache["cooldown_translations"][message.id]
        cooldown["wait"] = time.time() + cooldown["timeout"]
        cooldown["past_flags"].append(str(flag))
        self.cache["cooldown_translations"][message.id] = cooldown

        if channel.permissions_for(guild.me).embed_links:
            em = await self.translation_embed(author, translation,
                                              reacted_user)
            translated_msg = await channel.send(embed=em)
        else:
            msg = _("{author} said:\n{translated_text}").format(
                author=author, translate_text=translated_text)
            translated_msg = await channel.send(msg)
        if not cooldown["multiple"]:
            self.cache["translations"].append(translated_msg.id)