[Node.JS] [Discord] Оригинальная страница помощи в боте

currently dead.
Пользователь
Статус
Оффлайн
Регистрация
27 Июн 2018
Сообщения
148
Реакции[?]
78
Поинты[?]
0
Если здесь ничего нету, ждите прогрузки, гифка объемная!

Как вы знаете, в дискорде ботам доступна отправка "встроенных" сообщений, которые в документации зовутся embed'ами. Также, боты могут ставить собственные реакции к сообщению, потом обрабатывать их. И вот, мне пришли идея сделать перелистывающееся меню помощи в боте.

Итак, для начала нам требуется отрисовать различные элементы нашего будущего "интерфейса". Я брал иконки с
Пожалуйста, авторизуйтесь для просмотра ссылки.
и накладывал нужный стиль в фотошопе.

Теперь, нам необходимо создать сервер в дискорде, на который мы загрузим наши иконки как эмодзи.
Шаг 1. Открываем настройки сервера


Шаг 2. Открываем раздел "Эмодзи"


Шаг 3. Нажимаем кнопку "Загрузить эмодзи"


Шаг 4. Даём эмодзи название, которое нам будет удобно использовать в коде.
Теперь переходим к коду. Вам необходимо иметь
Пожалуйста, авторизуйтесь для просмотра ссылки.
и
Пожалуйста, авторизуйтесь для просмотра ссылки.
кода

Создаём папку, нажимаем ПКМ внутри неё, далее "Открыть с помощью Code"
Далее, в окне программы открываем консоль (я это делаю сочетанием Ctrl + Shift + ~ (ё)).
Теперь нам нужно установить все необходимые зависимости (в нашем случае, нам нужен только
Пожалуйста, авторизуйтесь для просмотра ссылки.
), для этого мы пишем в консоль npm i discord.js.
Дождавшись окончания загрузки, создаём новый файл и называем его index.js.
Открываем файл и пишем в него
Пожалуйста, авторизуйтесь для просмотра ссылки.
код:
JavaScript:
const Discord = require('discord.js'); // Подключаем зависимость "discord.js"
const bot = new Discord.Client() // Создаём нового клиента (бота)

/////////////НАСТРОЙКИ//БОТА/////////////
const token = "123456" // Токен бота из https://discordapp.com/developers/applications/
const prefix = "/"; // Префикс перед сообщением
const guildmode = false; // Режим работы только на серверах (может удалять сообщения и т.д.)
const emoji_guild = "599247397494849536"; // ID сервера, откуда бот берёт эмодзи
/////////////НАСТРОЙКИ//БОТА/////////////

var emojis = {};

bot.on("ready", async () => {
    console.log("Hello from wilddip (каво?)! Logged in as " + bot.user.tag);
    // Не смущаейтесь, что на пиндосском, это мой код :D
    // Get this guild by ID
    let guild = bot.guilds.get(emoji_guild);
    // Writing all emojis
    guild.emojis.forEach(emoji => {
        emojis[emoji.name] = emoji;
    });
})

bot.on("message", async msg => {
    if (msg.author.bot || msg.author.id == bot.user.id) return;
    if (guildmode && !msg.guild) return;
    if (!msg.content.startsWith(prefix)) return;

    let args = msg.content
        .slice(prefix.length)
        .trim()
        .split(/ +/g);

    let command = args.shift().toLowerCase();

    if (command === "help") {

        // А это и не должно работать !!!
        // function get(uid) {
        //   let u = bot.users.get(uid);
        //   if (!u) u = "<тут должно быть упоминание>";
        //   return u;
        // }

        let data = require("./help.json"); // Подключение файла с помощью
        let pages = data.pages;

        function getPage(number) {
            let page = pages[number];

            let cmd = [];
            cmd.push("**" + page[0] + "**:");
            page.slice(1, page.length).forEach(el => {
                let i = pages.indexOf(page) === pages.length - 1;

                // Лучше не трогайте всё что ниже. Код писал относительно давно, сам уже не помню что да как, ъуъ сука :P

                if (i) {
                    let n = el[0],
                        m = el[1],
                        t = el[2];

                    cmd.push(
                        "**" + n + "**: " + m + "[TG](https://tele.click/" + t + ")"
                    );
                } else {
                    let n = el[0],
                        d = el[1],
                        s = el[2],
                        r = [];

                    r.push("`" + prefix + n + "` ");
                    if (s) r.push("`" + s + "` ");
                    r.push("- " + d);

                    cmd.push(r.join(" "));
                }
            });
            cmd.push("\n");
            if (pages[number - 1]) cmd.push("`<<` **" + pages[number - 1][0] + "**");
            if (pages[number + 1]) cmd.push("**" + pages[number + 1][0] + "** `>>`");

            return cmd.join("\n");
        }

        let page = 1;
        let embed = new Discord.RichEmbed()
            .setColor(msg.member ? msg.member.displayHexColor : '#111111')
            .setDescription(getPage(page - 1))
            .setFooter(`${page} / ${pages.length}`, emojis.paper_stack.url)
            .setTimestamp();

        msg.channel.send(embed).then(async helpMsg => {
            let time = 120;

            let backFilter = (reaction, user) =>
                reaction.emoji === emojis.arrow_back && user.id === msg.author.id;
            let refreshFilter = (reaction, user) =>
                reaction.emoji === emojis.refresh && user.id === msg.author.id;
            let nextFilter = (reaction, user) =>
                reaction.emoji === emojis.arrow_next && user.id === msg.author.id;
            let closeFilter = (reaction, user) =>
                reaction.emoji === emojis.close && user.id === msg.author.id;

            let back = helpMsg.createReactionCollector(backFilter, {
                time: time * 1000
            });
            let refresh = helpMsg.createReactionCollector(refreshFilter, {
                time: time * 1000
            });
            let next = helpMsg.createReactionCollector(nextFilter, {
                time: time * 1000
            });
            let close = helpMsg.createReactionCollector(closeFilter, {
                time: time * 1000
            });

            let timeout = setTimeout(() => {
                msg.delete().catch();
                embed.setFooter(`Время вышло!`, emojis.close.url);
                helpMsg.edit(embed);
                return helpMsg.clearReactions().catch();
            }, time * 1000);

            back.on("collect", r => {
                r.remove(msg.author.id).catch(err => {
                    if (err) {
                        if (guildmode) {
                            embed
                                .setDescription(getPage(page - 1))
                                .setFooter(`Невозможно удалить реакцию...`);
                            clearTimeout(timeout);
                            return helpMsg.edit(embed);
                        }
                        else return;
                    }
                });
                if (page === 1) return;
                page--;
                embed
                    .setDescription(getPage(page - 1))
                    .setFooter(`${page} / ${pages.length}`, emojis.paper_stack.url);
                helpMsg.edit(embed);
            });

            refresh.on("collect", r => {
                r.remove(msg.author.id).catch(err => {
                    if (err) {
                        if (guildmode) {
                            embed
                                .setDescription(getPage(page - 1))
                                .setFooter(`Невозможно удалить реакцию...`);
                            clearTimeout(timeout);
                            return helpMsg.edit(embed);
                        }
                        else return;
                    }
                });
                page = 1;
                embed
                    .setDescription(getPage(page - 1))
                    .setFooter(`${page} / ${pages.length}`, emojis.paper_stack.url);
                helpMsg.edit(embed);
            });

            next.on("collect", r => {
                r.remove(msg.author.id).catch(err => {
                    if (err) {
                        if (guildmode) {
                            embed
                                .setDescription(getPage(page - 1))
                                .setFooter(`Невозможно удалить реакцию...`);
                            clearTimeout(timeout);
                            return helpMsg.edit(embed);
                        }
                        else return;
                    }
                });
                if (page === pages.length) return;
                page++;
                embed
                    .setDescription(getPage(page - 1))
                    .setFooter(`${page} / ${pages.length}`, emojis.paper_stack.url);
                helpMsg.edit(embed);
            });

            close.on("collect", r => {
                if (guildmode) msg.delete().catch();
                helpMsg.delete().catch();
                return clearTimeout(timeout);
            });

            await helpMsg.react(emojis.arrow_back);
            await helpMsg.react(emojis.refresh);
            await helpMsg.react(emojis.arrow_next);
            await helpMsg.react(emojis.close);
        });
    }
})

// Лучше это не трогать, это обработчик событий, чтобы бот видел реакции на сообщения, которые были отправлены до его запуска.
bot.on("raw", packet => {
    if (!["MESSAGE_REACTION_ADD", "MESSAGE_REACTION_REMOVE"].includes(packet.t))
        return;
    const channel = bot.channels.get(packet.d.channel_id);
    if (channel.messages.has(packet.d.message_id)) return;
    channel.fetchMessage(packet.d.message_id).then(message => {
        const emoji = packet.d.emoji.id
            ? `${packet.d.emoji.name}:${packet.d.emoji.id}`
            : packet.d.emoji.name;
        const reaction = message.reactions.get(emoji);
        if (reaction)
            reaction.users.set(packet.d.user_id, bot.users.get(packet.d.user_id));
        if (packet.t === "MESSAGE_REACTION_ADD") {
            bot.emit("messageReactionAdd", reaction, bot.users.get(packet.d.user_id));
        }
        if (packet.t === "MESSAGE_REACTION_REMOVE") {
            bot.emit(
                "messageReactionRemove",
                reaction,
                bot.users.get(packet.d.user_id)
            );
        }
    });
});
bot.login(token);

// Want a bot? Write me > https://tele.click/wilddip [redirect, have no fear]
Далее, создаём другой файл и называем его help.json. В нём будут храниться страницы помощи.
Вставляем в него
Пожалуйста, авторизуйтесь для просмотра ссылки.
:
JSON:
{
    "pages": [
      [
        "Информативные команды",
        ["help", "Страница помощи", ""],
        ["kick", "Кикнуть пользователя", "@user / ID"]
      ],
      [
        "Авторы",
        ["резу", "<@252387050232217602>", "su2008"],
        ["дип-дип", "<@394166097928126464>", "wilddip"]
      ]
    ]
}
Теперь к пояснениям. Самая первые строки ("Информативные команды" и "Авторы") - названия разделов помощи, они будут показываться при пролистывании и сверху страницы. Далее идут команды вида "Команда без префикса" - "Описание" - "Как употреблять".

!!! Самый последний раздел "Авторы" нельзя удалять, просто замените данные на свои ("Имя" - "<@ID Discord>" - "Ник в телеге"), остальные можно дублировать до бесконечности (но до 10-12 команд на 1 раздел, если команд больше - можете бить на части, например, раздел "Информативные команды 1/2")

!!! Также, на вашем сервере должны присутствовать эмодзи с названиями: arrow_back (стрелка влево), arrow_next (стрелка вправо), close (закрыть меню), refresh (перезагрузка), paper_stack (листочек бумаги). Если не хотите тратить время на создание иконок, можете написать мне в телегу (или по другим контактам), чтобы я добавил вас и вашего бота на свой сервак с эмодзи.
 
Последнее редактирование:
currently dead.
Пользователь
Статус
Оффлайн
Регистрация
27 Июн 2018
Сообщения
148
Реакции[?]
78
Поинты[?]
0
Сверху Снизу