Как управлять своими задачами с помощью телеграм-бота на JS

Telegram - одна из популярных социальных сетей. Большую часть времени проводя в telegram, в какой-то момент я подумала, что было бы удобно управлять своими задачами, не выходя из приложения, просто перейдя из диалога с другом в диалог с ботом.

В данной публикации я расскажу о создании телеграм-бота на JS. В настоящее время популярность телеграм-ботов остается высокой. Хоть большинство ботов и пишут на Python с использованием библиотеки python-telegram-bot, их также можно создавать на JavaScript.

С чего начать?

Одна из популярных библиотек для создания телеграм-ботов на JavaScript — это Telegraf.js (простая и гибкая, облегчает разработку телеграм-ботов на основе JS).

Первое, что нужно сделать при создании телеграм-бота - обратиться к специальному сервису @BotFather (Рис. 1) социальной сети Telegram. После того как я указала адрес и уникальное имя пользователя, которое заканчивается на “bot”, в диалоге с @BotFather, мне предоставили уникальный токен для управления моим телеграм-ботом. Его необходимо хранить в безопасности, чтобы избежать несанкционированный доступ к боту. Если возникнет необходимость, всегда можно изменить токен или настроить другие параметры бота, обратившись к @BotFather.

Рис. 1 Сервис @BotFather в Telegram
Рис. 1 Сервис @BotFather в Telegram

Создание проекта

У меня уже был установлен Node.JS, поэтому я сразу приступила к инициализации проекта

npm init –yes

Затем я установила фреймворк для Node.js, который позволяет разрабатывать веб-приложения, и API-Express.js

npm i express

Далее я установила библиотеку Telegraf, которую упоминала выше

npm install telegraf --save

В отдельный файл config.js для безопасности я вынесла порт сервера и токен, который получила выше.

В файле app.js я реализовала приветствие, которое выводит бот при вводе команды /start (Рис. 2)

import express from 'express' import { PORT, TOKEN } from './config.js' import { Telegraf } from "telegraf"; const app = express() const Tbot = new Telegraf(TOKEN) Tbot.start((context) => { context.replyWithHTML( "Добро пожаловать в <b>to-do list</b>\n\n" + "Для добавления задачи необходимо ее <b>написать</b> и отправить боту" ); }); Tbot.launch() app.listen(PORT, () => console.log(`Сервер запущен. Порт: ${PORT}`));
<p>Рис. 2 Приветствие телеграм-бота</p>

Рис. 2 Приветствие телеграм-бота

Требования к боту

Мне было важно, чтобы бот добавлял задачу в перечень не по нажатию кнопки, а при получении сообщения от пользователя при отправке текста боту. Нужно, чтобы он умел выводить список всех задач и удалять, какую мне необходимо. Также я хотела, чтобы была какая-то инструкция для пользователя и по запросу выводилась мотивационная картинка Я создала файл db.js, в котором хранится массив с задачами

export let missionList = []

Создание клавиатуры

В файле keyboards.js я импортировала класс Markup из модуля telegraf и использовала его для создания клавиатурной разметки с кнопками. Клавиатура автоматически масштабируется под размер экрана пользователя (Рис. 3). Функция getMenu создает клавиатуру с тремя кнопками: "Моя задача", "Добавить задачу" и " Получить мотивацию" (Рис. 4).

import { Markup } from "telegraf"; export function getMenu() { return Markup.keyboard([ ["Мои задачи", "Инструкция"],["Получить мотивацию"], ]).resize(); }
<p>Рис. 3 Интерфейс бота</p>

Рис. 3 Интерфейс бота

<p>Рис. 4 Ответ бота на нажатие кнопки «Получить мотивацию»</p>

Рис. 4 Ответ бота на нажатие кнопки «Получить мотивацию»

Далее я вернулась в файл app.js. Логично, что функция getMenu должна вызывать при старте бота. Поэтому я ее импортировала и добавила в действие при команде /start.

import express from 'express' import { PORT, TOKEN } from './config.js' import { Telegraf } from "telegraf"; import { getMenu} from "./keyboards.js"; const app = express() const Tbot = new Telegraf(TOKEN) Tbot.start((context) => { context.replyWithHTML( "Добро пожаловать в <b>to-do list</b>\n\n" + "Для добавления задачи необходимо ее <b>написать</b> и отправить боту", getMenu() ); }); Tbot.launch() app.listen(PORT, () => console.log(`Сервер запущен. Порт: ${PORT}`));

Реализация логики бота

Перед тем как начинать реализовывать логику бота далее, важно знать, какие методы бывают. Метод hears() вызывает обработчика, который реагирует на введенный текст. А метод reply() содержит ответ бота пользователю.

Tbot.hears("Мои задачи", async (context) => { const missions = await getMyMissions(); let results = ""; for (let i = 0; i < missions.length; i++) { results = results + `${i + 1}. ${missions[i]}\n`; } if (results !== "") { context.replyWithHTML("<b>Перечень задач:</b>\n\n" + `${results}`); } else { context.replyWithHTML("<b>Перечень задач пуст</b>"); } }); Tbot.hears("Инструкция", (context) => { context.replyWithHTML( `Чтобы удалить задачу отправьте фразу <b>"удалить"</b> с указанием порядкового номера задачи. ` + `Например, <b>"удалить 3"</b>:\n\n ` + `Чтобы добавить новую задачу, просто напишите ее и отправьте боту. ` ); }); Tbot.hears(/^удалить\s(\d+)$/, (context) => { const id = Number(+/\d+/.exec(context.message.text)) - 1; deleteMission(id); context.reply("Задача успешно удалена"); }); Tbot.on("text", (context) => { if (!context.session) context.session = {}; context.session.missionText = context.message.text; context.replyWithHTML( `Вы действительно хотите добавить задачу:\n\n` + `<i>${context.message.text}</i>`, noYesKeyboard() ); }); Tbot.action(["true", "false"], (context) => { if (context.callbackQuery.data === "true") { addMission(context.session.missionText); context.editMessageText("Задача успешно добавлена"); } else { context.deleteMessage(); } });

При добавлении задачи бот дополнительно спрашивает, действительно ли пользователь хочет это сделать. Поэтому в файле keyboards.js я создала клавиатуру с ответами «да» и «нет». И если пользователь отвечает, что да, то выводится сообщение, что задача успешно добавлена.

export function noYesKeyboard() { return Markup.inlineKeyboard( [ Markup.button.callback("Да", "true"),Markup.button.callback("Нет", "false")], { columns: 2 } ); }

Также я добавила функции вывода, добавления и удаления для базы данных в файле db.js

export function getMyMissions() { return new Promise((resolve) => { setTimeout(() => { resolve(missionList); }, 500); }); } export function addMission(text) { missionList.push(text); } export function deleteMission(id) { missionList.splice(id, 1); }

Что же делает кнопка «Получить мотивацию»? При нажатии выводятся «рандомные» картинки, которые я храню в папке и подписи, которые хранятся в массиве

function getRandomImageWithCaption() { const imagesFolderPath = "./images"; const captions = [ Список цитат ]; const imageFiles = fs.readdirSync(imagesFolderPath); const randomIndex = Math.floor(Math.random() * imageFiles.length); const randomImage = imageFiles[randomIndex]; const randomCaption = captions[Math.floor(Math.random() * captions.length)]; return { image: randomImage, caption: randomCaption }; } Tbot.hears("Получить мотивацию", (context) => { const { image, caption } = getRandomImageWithCaption(); const imagePath = `./images/${image}`; context.replyWithPhoto( { source: imagePath }, { caption: caption, } ); });

Заключение

Созданный телеграм-бот всегда находится под рукой, помогает планировать и управлять повседневными задачами, показывая изображения для мотивации. Это поможет вам сохранять продуктивность на протяжении всего дня. Для управления ботом используется клавиатура, что делает использование приложения максимально простым и интуитивным. Надеюсь, что мой телеграм-бот станет для вас надежным помощником в организации рабочих и личных дел, всегда готовым помочь и поддержать. Полный код: https://github.com/SVErmol/Telegram-bot

77
3 комментария

Отличная статья с подробными и понятным объяснением. Большое спасибо автору!)

2

Код удивительным образом похож на https://delaney.gitbook.io/telegram-bot-na-js/#nachinaem-kodit . может стоит указывать соавторство?

Автор

Спасибо за ваш комментарий! В указанном вами примере реализация функционала бота происходит по-другому.