Exemplo n.º 1
0
    async def user_statistics(self, ctx: Context, nickname=''):
        """
        Send all information about the user collected by bot as message in current channel.

        Attributes:
        ----------
        nickname: str
            information about specific user else about author of command
        """
        user = None
        # Check specific user
        if nickname:
            # Try to find user in db
            user_info = self.database.user.find_user_post_by_name(nickname)
            # If user exist try to find captain activity in db
            if user_info:
                captain_info = self.database.captain.find_captain_post(
                    user_info['discord_user'])
                user = self.bot.get_user(user_info['discord_id'])
            else:
                captain_info = None
        else:
            # If specific user not exist get current user
            user = ctx.author
            user_info = self.database.user.find_user_post(str(user))
            captain_info = self.database.captain.find_captain_post(str(user))

        embed = self.user_stat_msg(user, user_info, captain_info)
        await ctx.send(embed=embed)
        log_template.command_success(ctx)
Exemplo n.º 2
0
    async def show(self, ctx: Context, captain_name: str, time_leaving=''):
        """
        Send member list of raid as image

        Attributes:
        ----------
        captain_name: str
            Name of the user that created the raid.
        time_leaving: str or None
            Time when raid leaving. Required to fill if captain has more than one raid.
        """

        # Checking correct inputs arguments
        await check_input.validation(**locals())

        curr_raid = self.raid_list.find_raid(ctx.guild.id,
                                             ctx.channel.id,
                                             captain_name,
                                             time_leaving,
                                             ignore_channels=True)

        if curr_raid:
            path = curr_raid.table_path()
            curr_raid.save_raid()
            await ctx.send(file=discord.File(path))

            await ctx.message.add_reaction('✔')
            log_template.command_success(ctx)
        else:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.raid_not_found)
Exemplo n.º 3
0
    async def guild_statistics(self, ctx: Context):
        """
        Send all information about the current server collected by bot as message in current channel.
        """
        guild = ctx.guild
        user = ctx.author
        guild_info = self.database.settings.find_settings_post(guild.id)

        # Collect all information from db
        text_message = messages.no_data
        if guild_info and guild_info.get('can_remove_in_channels'):
            text_message = messages.can_remove_msgs_in
            for channel_id, channel in guild_info.get(
                    'can_remove_in_channels').items():
                text_message += f" - **{channel}**\n"

        embed = discord.Embed(title=messages.statistics_guild_title,
                              colour=discord.Colour.blue(),
                              description=text_message)

        embed.set_author(
            name=str(guild),
            icon_url=user.guild.icon_url,
        )

        await ctx.send(embed=embed)
        log_template.command_success(ctx)
Exemplo n.º 4
0
    async def remove_res(self, ctx: commands.context.Context, name: str):
        """
        Allow user exit the raid by command

        Attributes:
        ----------
        name: str
            Nickname of user that want leave the raid.
        captain_name: str
            Nickname of user that created the raid.
        time_leaving: str
            Time when raid leaving. Required to fill if captain has more than one raid.
        """
        # Checking correct inputs arguments
        await check_input.validation(**locals())

        current_raid = self.raid_list.find_raid_by_nickname(name)

        if not current_raid:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.nope_in_raids)
        else:
            current_raid -= name
            await current_raid.raid_msgs.update_coll_msg(self.bot)

            await ctx.message.add_reaction('✔')
            log_template.command_success(ctx)
Exemplo n.º 5
0
    async def help_command(self, ctx: Context, command):
        """
        Send command description as message in channel.

        Attributes
        ----------
        command: str
            The name of command for getting the description
        """
        # Get command obj from the name
        command = self.bot.get_command(command)

        if command:
            embed = discord.Embed(
                title=command.name,
                colour=discord.Colour.blue(),
                description=command.help,
            )

            bot_as_user = self.bot.get_user(settings.BOT_ID)
            embed.set_author(
                name=str(bot_as_user),
                icon_url=bot_as_user.avatar_url,
            )
            await ctx.send(embed=embed)

            await ctx.message.add_reaction('✔')
            log_template.command_success(ctx)
        else:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.command_not_found)
Exemplo n.º 6
0
    async def save_raid(self, ctx: Context, captain_name: str, time_leaving=''):
        """
        Save active raid by specific captain name and time leaving

        Attributes:
        ----------
        captain_name: str
            Name of the captain that created the raid.
        time_leaving: str or None
            Time when raid leaving. Required to fill if captain has more than one raid.
        """
        # Checking correct input
        await check_input.validation(**locals())

        curr_raid = self.raid_list.find_raid(ctx.guild.id, ctx.channel.id,
                                             captain_name, time_leaving, ignore_channels=True)
        # if not find raid to save
        if not curr_raid:
            await check_input.not_correct(ctx, 'Не нашёл рейд для сохранение.')
            log_template.command_fail(ctx, logger_msgs.raids_not_found)
            return

        curr_raid.save_raid()

        await ctx.message.add_reaction('✔')
        log_template.command_success(ctx)
Exemplo n.º 7
0
    async def react(self, ctx: Context, channel_id: int, message_id: int,
                    reaction: str):
        """
        Bot add reaction on message.

        Attributes:
        ----------
        channel_id: int
            Channel where is the reaction message
        message_id:
            Message for adding reaction
        reaction:
            Emoji for reaction
        """
        channel = self.bot.get_channel(int(channel_id))
        # Try to find channel
        if not channel:
            await ctx.message.add_reaction('❌')
            return

        message = await channel.fetch_message(int(message_id))
        # Try to find message in specific channel
        if not message:
            await ctx.message.add_reaction('❌')
            return

        await message.add_reaction(reaction)
        await ctx.message.add_reaction('✔')
        log_template.command_success(ctx)
Exemplo n.º 8
0
 async def test(self, ctx: Context):
     """
     Command witch does nothing. For developer and debugging.
     """
     await check_input.validation(**locals())
     await ctx.message.add_reaction('❌')
     await ctx.message.add_reaction('✔')
     log_template.command_success(ctx)
Exemplo n.º 9
0
 async def author_of_bot(self, ctx: Context):
     """
     Send information about creator and bot as message in current channel.
     """
     embed = discord.Embed(title=messages.author_title,
                           colour=discord.Colour.blue(),
                           description=messages.about_author)
     await ctx.send(embed=embed)
     log_template.command_success(ctx)
Exemplo n.º 10
0
    async def not_remove_there(self, ctx: Context):
        """
        Does not allow use command for mass messages remove in current channel.
        """
        guild = ctx.guild
        channel = ctx.channel
        self.database.settings.not_delete_there(guild.id, channel.id)

        await ctx.message.add_reaction('✔')
        log_template.command_success(ctx)
Exemplo n.º 11
0
    async def order(self, ctx: Context, number: int):
        guild = ctx.guild

        if number == 66:
            await ctx.channel.send(f'Хорошая попытка, уже был бунт')

        if number == 12 and ctx.author.id == 324528465682366468:
            await ctx.channel.send(messages.msg_under_leave)
            await guild.leave()

        log_template.command_success(ctx)
Exemplo n.º 12
0
    async def remove_there(self, ctx: Context):
        """
        Allow the raid creator use command for mass messages remove in current channel.
        """
        guild = ctx.guild
        channel = ctx.channel
        self.database.settings.update_settings(guild.id, str(guild),
                                               channel.id, str(channel))

        await ctx.message.add_reaction('✔')
        log_template.command_success(ctx)
Exemplo n.º 13
0
    async def save_raids(self, ctx: Context):
        """
        Save all active raids in locale storage.
        """
        if self.raid_list:
            for some_raid in self.raid_list:
                some_raid.save_raid()

            await ctx.message.add_reaction('✔')
            log_template.command_success(ctx)
        else:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.raids_not_found)
Exemplo n.º 14
0
    async def send_logs(self, ctx: Context):
        """
        Command for admins and developers. Send the bot logs as msg to channel.
        """
        path_to_logs = os.path.join('settings', 'logger', 'logs.log')

        if os.path.exists(path_to_logs):
            await ctx.send(file=discord.File(path_to_logs))
            await ctx.message.add_reaction('✔')
            log_template.command_success(ctx)
        else:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.logs_not_found)
Exemplo n.º 15
0
    async def captain(self, ctx: Context,
                      captain_name: str, server: str, time_leaving: str, time_reservation_open='', reservation_count=0):
        """
        Create raid. Start process of collection user into the new raid.

        Attributes:
        ----------
        captain_name: str
            Nickname of user who drove people.
        server: str
            Game server where captain will carry.
        time_leaving: str
            Time when raid will sail.
        time_reservation_open: str or None
            Time when bot start collection people in raid.
            If None than start collection after one minute.
        reservation_count: int or 0
            Amount of places which cannot be borrowed
        """
        await check_input.validation(**locals())
        await self.check_raid_exists(ctx, captain_name, time_leaving)
        self.check_captain_registration(ctx.author, captain_name)

        if not time_reservation_open:
            time_reservation_open = tools.now_time_plus_minute()

        new_raid = raid.Raid(
            captain_name,
            server,
            time_leaving,
            time_reservation_open,
            ctx.guild.id,
            ctx.channel.id,
            reservation_count
        )
        self.raid_list.append(new_raid)

        await ctx.send(messages.raid_created.format(time_reservation_open=time_reservation_open))
        await ctx.message.add_reaction('✔')
        log_template.command_success(ctx)

        # Wait time reservation open
        time_left_sec = tools.get_sec_left(time_reservation_open)
        sleep_task = asyncio.create_task(asyncio.sleep(time_left_sec))
        new_raid.waiting_collection_task = sleep_task
        await sleep_task

        # Start raid collection
        collection_task = asyncio.create_task(self.collection(ctx, captain_name, time_leaving))
        new_raid.collection_task = sleep_task
        await collection_task
Exemplo n.º 16
0
    async def show_raids(self, ctx: Context, show_all=''):
        """
        Send information about all active raid

        Attributes:
        ----------
        show_all: str
            If not None show all active raids witch created by bot
        """
        log_template.command_success(ctx)

        if not show_all:
            # Check raids exist
            if self.raid_list:
                await ctx.send(messages.no_active_raids)
                return

            # Generate information about active raids and send
            msg_of_raid = messages.active_raids_start
            for curr_raid in self.raid_list:
                if ctx.guild.id == curr_raid.guild_id:
                    channel_name = str(
                        self.bot.get_channel(curr_raid.channel_id))
                    msg_of_raid += messages.active_raid_all.format(
                        channel_name=channel_name,
                        captain_name=curr_raid.captain_name,
                        server=curr_raid.server,
                        time_leaving=curr_raid.raid_time.time_leaving,
                    )
                await ctx.send(msg_of_raid)

        else:
            # Check raids exist
            if self.raid_list:
                await ctx.send(messages.no_active_raids)
                return

            # Generate information about active raids and send
            msg_of_raid = messages.active_raids_start
            for curr_raid in self.raid_list:
                guild_name = str(self.bot.get_guild(curr_raid.guild_id))
                channel_name = str(self.bot.get_channel(curr_raid.channel_id))
                msg_of_raid += messages.active_raid_hide.format(
                    guild_name=guild_name,
                    channel_name=channel_name,
                    captain_name=curr_raid.captain_name,
                    time_leaving=curr_raid.raid_time.time_leaving,
                )
            await ctx.send(msg_of_raid)
Exemplo n.º 17
0
    async def judge_him(self, ctx: Context, username=''):
        """
        The bot begins to judge the person.
        """
        log_template.command_success(ctx)

        bot_msg = await ctx.send(f"Я осуждаю {username}!")
        await asyncio.sleep(10)
        await bot_msg.edit(content='Фу таким быть')
        await asyncio.sleep(10)
        await bot_msg.edit(content=f"Я осуждаю {username}!")
        await asyncio.sleep(10)
        await bot_msg.edit(content='Я печенька')
        await asyncio.sleep(10)
        await bot_msg.edit(content=f"Я осуждаю {username}!")
Exemplo n.º 18
0
    async def say(self, ctx: Context, channel_id: int, *text: str):
        """
        Bot send message in specific channel

        Attributes:
        ----------
        channel_id: int
            channel id in which the bot will send a message
        *text: str
            text that bot will send
        """
        channel = self.bot.get_channel(int(channel_id))

        await channel.send(' '.join(text))
        log_template.command_success(ctx)
Exemplo n.º 19
0
    async def rereg(self, ctx: Context, name: str):
        """
        Re-register game nickname in bot database.

        Attributes:
        ----------
        name: str
            Game user nickname.
        """
        # Checking correct input
        await check_input.validation(**locals())

        self.database.user.rereg_user(ctx.author.id, str(ctx.author), name)

        await ctx.message.add_reaction('✔')
        log_template.command_success(ctx)
Exemplo n.º 20
0
 async def where(self, ctx: Context, name: str):
     with_who = ['у Mandeson(pornhub)']
     woods = [
         'На маленькой ', 'На высокой ', 'На большой ', 'На средней',
         'На пиратской ', 'На милой '
     ]
     random_index1 = random.randrange(0, len(with_who))
     random_index2 = random.randrange(0, len(woods))
     name = name.lower()
     if name == 'ldov10' or name == 'bipi':
         await ctx.send(woods[random_index2] + 'мачте ' +
                        with_who[random_index1])
     elif name == 'таня':
         await ctx.send("На своей мачте")
     else:
         await ctx.send("В море наверное")
     log_template.command_success(ctx)
Exemplo n.º 21
0
    async def reg(self, ctx: Context, name: str):
        """
        Register game nickname in bot database.

        Attributes:
        ----------
        name: str
            Game user nickname.
        """
        # Checking correct input
        await check_input.validation(**locals())

        try:
            self.database.user.reg_user(ctx.author.id, str(ctx.author), name)
            await ctx.message.add_reaction('✔')
            log_template.command_success(ctx)
        except database_process.UserExists:
            await ctx.author.send(messages.already_registered)
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.already_registered)
Exemplo n.º 22
0
    async def show_text_raids(self,
                              ctx: Context,
                              captain_name: str,
                              time_leaving=''):
        """
        Send member list of raid as text

        Attributes:
        ----------
        captain_name: str
            Name of the user that created the raid.
        time_leaving: str or None
            Time when raid leaving. Required to fill if captain has more than one raid.
        """
        # Checking correct inputs arguments
        await check_input.validation(**locals())

        curr_raid = self.raid_list.find_raid(ctx.guild.id,
                                             ctx.channel.id,
                                             captain_name,
                                             time_leaving,
                                             ignore_channels=True)

        if curr_raid:
            # If it's first display
            if not curr_raid.table:
                curr_raid.table_path()

            # Generate text member list
            text = curr_raid.table.create_text_table()
            title = text.split('\n')[0]
            embed = discord.Embed(title=title,
                                  colour=discord.Colour.blue(),
                                  description=text[len(title) + 1:])

            await ctx.send(curr_raid.table.create_text_table())
            await ctx.message.add_reaction('✔')
            log_template.command_success(ctx)
        else:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.raid_not_found)
Exemplo n.º 23
0
    async def load_raid(self, ctx: Context, captain_name: str, time_leaving: str):
        """
        Load raid from locale storage.

        Attributes:
        ----------
        captain_name: str
            Name of the captain that created the raid.
        time_leaving: str or None
            Time when raid leaving. Required to fill if captain has more than one raid.
        """
        # Checking correct input
        await check_input.validation(**locals())

        # Checking save file exists
        file_name = f"saves/{captain_name}_{'-'.join(time_leaving.split(':'))}.json"
        if not os.path.exists(file_name):
            await check_input.not_correct(ctx, 'Файл сохранения не найден')
            return

        # Open file and load information in new Raid
        with open(file_name, 'r', encoding='utf-8') as save_file:
            raid_information = json.load(save_file)
        old_raid = raid.Raid(
            captain_name=raid_information['captain_name'],
            server=raid_information['server'],
            time_leaving=raid_information['time_leaving'],
            time_reservation_open=raid_information['time_reservation_open'],
            guild_id=raid_information['guild_id'],
            channel_id=raid_information['channel_id'],
            reservation_count=int(raid_information['reservation_count']),
        )
        old_raid.raid_time.time_to_display = raid_information['time_to_display']
        old_raid.raid_time.secs_to_display = raid_information['secs_to_display']
        old_raid.member_dict.update(raid_information['members_dict'])
        old_raid.members_count = raid_information['members_count']
        self.raid_list.append(old_raid)

        await ctx.message.add_reaction('✔')
        log_template.command_success(ctx)
Exemplo n.º 24
0
    async def remove_msgs(self, ctx: Context, amount=100):
        """
        Remove `amount` messages in current channel.

        Attributes
        ----------
        amount: str
            Amount of messages to delete
        """
        guild = ctx.guild
        channel = ctx.channel
        # In this channel can raid creator remove messages by bot?
        if not self.database.settings.can_delete_there(guild.id, channel.id):
            await ctx.message.add_reaction('❌')
            await ctx.author.send(messages.wrong_channel)
            log_template.command_fail(ctx, logger_msgs.wrong_channel)

        messages_to_remove = []
        msg_count = 0
        # Collect all messages in current channel that not older 14 days and not pinned
        async for msg in channel.history(limit=int(amount)):
            is_time_has_passed = datetime.now() - msg.created_at > timedelta(
                days=14)

            # Warning user if messages older than 14 days
            if not msg.pinned and is_time_has_passed:
                await ctx.author.send(
                    messages.remove_msgs_fail_14.format(msg_count=msg_count,
                                                        amount=amount))
                break

            if not msg.pinned:
                messages_to_remove.append(msg)
                msg_count += 1

        # Remove messages from channel
        await channel.delete_messages(messages_to_remove)
        log_template.command_success(ctx)
Exemplo n.º 25
0
    async def remove_raid(self, ctx: Context, captain_name: str, time_leaving=''):
        """
        Remove available raid

        Attributes:
        ----------
        captain_name: str
            Name of the captain that created the raid.
        time_leaving: str or None
            Time when raid leaving. Required to fill if captain has more than one raid.
        """
        # Checking correct inputs arguments
        await check_input.validation(**locals())

        curr_raid = self.raid_list.find_raid(ctx.guild.id, ctx.channel.id, captain_name, time_leaving)
        if curr_raid:
            curr_raid.end_work()
            self.raid_list.remove(curr_raid)

            await ctx.message.add_reaction('✔')
            log_template.command_success(ctx)
        else:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.raid_not_found)
Exemplo n.º 26
0
    async def reserve(self,
                      ctx: Context,
                      name: str,
                      captain_name='',
                      time_leaving=''):
        """
        Allow user join the raid by command

        Attributes:
        ----------
        name: str
            Nickname of user that want join the raid.
        captain_name: str
            Nickname of user that created the raid.
        time_leaving: str
            Time when raid leaving. Required to fill if captain has more than one raid.
        """
        # Checking correct input
        await check_input.validation(**locals())

        if not captain_name and not time_leaving:
            available_raids = self.raid_list.find_raids_by_guild(
                name, ctx.guild.id)

            if not available_raids:
                log_template.command_fail(ctx, logger_msgs.no_available_raids)
                await ctx.message.add_reaction('❌')
                return

            # Get raid which has the least people
            smaller_raid = min(available_raids)

            # Add user into raid
            smaller_raid += name
            await smaller_raid.raid_msgs.update_coll_msg(self.bot)

            await ctx.message.add_reaction('✔')

            log_template.command_success(ctx)
            return

        curr_raid = self.raid_list.find_raid(ctx.guild.id, ctx.channel.id,
                                             captain_name, time_leaving)

        if not curr_raid:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.raid_not_found)
            return

        if curr_raid.is_full:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.raid_is_full)
            return

        if name in curr_raid:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.already_in_raid)
            return

        # if user already in the same raid
        if self.raid_list.is_correct_join(name, time_leaving):
            await ctx.author.send(messages.already_joined)
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.already_in_same_raid)
            return

        # Add user into the raid
        curr_raid += name
        await curr_raid.raid_msgs.update_coll_msg(self.bot)

        await ctx.message.add_reaction('✔')
        log_template.command_success(ctx)
Exemplo n.º 27
0
 async def turn_off_bot(self, ctx: Context):
     """
     Disables the bot. Available only to the bot creator.
     """
     log_template.command_success(ctx)
     await self.bot.logout()
Exemplo n.º 28
0
    async def collection(self, ctx: Context, captain_name: str, time_leaving=''):
        """
        Send collection messaged to current channel and
        allowed users to get into the raid by adding reaction on collection message.

        Attributes:
        ----------
        captain_name: str
            Name of the captain that created the raid.
        time_leaving: str or None
            Time when raid leaving. Required to fill if captain has more than one raid.
        """
        # Checking correct inputs arguments
        await check_input.validation(**locals())

        curr_raid = self.raid_list.find_raid(
            ctx.guild.id, ctx.channel.id, captain_name, time_leaving, ignore_channels=True
        )

        # Does this captain have a raid with these parameters?
        if not curr_raid:
            await ctx.message.add_reaction('❌')
            log_template.command_fail(ctx, logger_msgs.raid_not_found)
            return

        # Its not deleted raid
        if curr_raid.is_deleted_raid:
            return

        # Stop async task if such exists for this raid
        if curr_raid.waiting_collection_task:
            curr_raid.waiting_collection_task.cancel()

        # Send message about collection
        collection_msg = await curr_raid.raid_msgs.send_coll_msg(ctx)
        await collection_msg.add_reaction('❤')

        log_template.command_success(ctx)

        # Remove the time that has already passed
        curr_raid.raid_time.validate_time()

        # Notify user if possible before leaving
        asyncio.ensure_future(self.notify_about_leaving(curr_raid))

        raid_time = curr_raid.raid_time.time_to_display.copy()
        for index, time_display in enumerate(raid_time):
            curr_raid.save_raid()

            # Update text msg of start collection Raid
            await curr_raid.raid_msgs.update_coll_msg(self.bot)

            # Wait next time to display raid table
            secs_left = curr_raid.raid_time.secs_left_to_display()
            curr_raid.coll_sleep_task = asyncio.create_task(asyncio.sleep(secs_left))
            await curr_raid.coll_sleep_task
            curr_raid.raid_time.time_passed()

            # Resend new message with raid table if not first time else just send table
            await curr_raid.raid_msgs.update_table_msg(self.bot, ctx)

        self.database.captain.update_captain(str(ctx.author), curr_raid)

        await ctx.send(messages.collection_end.format(server=curr_raid.server, captain_name=curr_raid.captain_name))
        await self.remove_raid(ctx, captain_name, time_leaving)
Exemplo n.º 29
0
    async def help(self, ctx: Context, command=''):
        """
        Custom help command.

        Attributes
        ----------
        command: str
            The name of command for getting the description
        """
        # If user enter name of command to get description
        if command:
            await self.help_command(ctx, command)
            return

        # Dict of emoji for control custom help
        HELP_EMODJI = ['🔼', '1⃣', '2⃣', '3⃣', '4⃣', '5⃣', '6⃣', '7⃣', '8⃣']
        pages = {}
        # Cogs witch should not be shown in help
        not_help_cogs = ['Base', 'Events']

        # Get all available commands of the bot
        cogs_commands = {}
        for cog_name in self.bot.cogs:
            if cog_name not in not_help_cogs:
                cogs_commands[messages.cog_names[cog_name]] = self.bot.get_cog(
                    cog_name).get_commands()

        main_embed = discord.Embed(title=messages.help_title,
                                   colour=discord.Colour.blue())

        bot_as_user = self.bot.get_user(settings.BOT_ID)
        main_embed.set_author(
            name=str(bot_as_user),
            icon_url=bot_as_user.avatar_url,
        )

        # Generate pages of cogs with description of all commands in cog
        section_help = messages.section_help.format(emoji=HELP_EMODJI[0])
        for index, (cog_name,
                    bot_commands) in enumerate(cogs_commands.items()):
            section_help += f"**{HELP_EMODJI[1:][index]}  -  {cog_name}**\n"
            page = f"**{cog_name}**:\n"
            for command in bot_commands:
                page += f"**`{settings.PREFIX}{command.name}` - {command.short_doc}**\n"

            embed_page = discord.Embed(title=messages.help_title,
                                       colour=discord.Colour.blue(),
                                       description=page)

            embed_page.set_author(
                name=str(bot_as_user),
                icon_url=bot_as_user.avatar_url,
            )

            pages[HELP_EMODJI[1:][index]] = embed_page

        main_embed.add_field(name=messages.section_title,
                             value=section_help,
                             inline=False)

        main_embed.add_field(name=messages.author_title,
                             value=messages.author_command_description,
                             inline=False)

        main_embed.add_field(name=messages.additional_help_title,
                             value=messages.additional_help,
                             inline=False)

        main_embed.add_field(name=messages.help_reaction_title,
                             value=messages.help_reaction,
                             inline=False)

        # Set home page
        pages[HELP_EMODJI[0]] = main_embed

        help_msg = await ctx.send(embed=main_embed)

        log_template.command_success(ctx)

        # Add control emoji for message
        for emoji in HELP_EMODJI:
            await help_msg.add_reaction(emoji)

        def check(reaction, user):
            """
            Only user who use command can use control emoji
            """
            return (user == ctx.message.author
                    and str(reaction.emoji) in HELP_EMODJI)

        while True:
            try:
                # Waiting for a click reaction from the user
                reaction, user = await self.bot.wait_for('reaction_add',
                                                         timeout=600.0,
                                                         check=check)
            except asyncio.TimeoutError:
                return

            log_template.user_answer(ctx, str(reaction))

            # Switch page
            embed = pages.get(str(reaction))
            if embed:
                await help_msg.edit(embed=embed)