То, что начиналось как побочный проект, теперь заканчивается руководством!

Узнайте, как создать собственного бота Telegram с помощью NodeJS и Firebase, чтобы узнать о возможностях синхронизации, которые вы можете интегрировать в свои собственные проекты для будущего использования. Создайте бота, который поможет вам обеспечить связь в режиме реального времени с несколькими устройствами, а также с несколькими платформами, что обеспечит беспроблемный опыт разработки.

Почему?
Я искал способ интегрировать информацию из Google Keep, где я записываю все свои идеи, и из Apple Notes, где я размышляю по этим темам.
Наиболее часто используемым приложением на моем телефоне является приложение для обмена сообщениями. С его помощью я также отслеживаю важные ссылки, записываю мысли на ходу и многое другое.
Я хотел найти способ заменить все три одной специальной службой, поэтому решил создать телеграмм-бота.

Что?
Я хотел, чтобы этот бот был личным помощником, аналогом JARVIS Железного Человека (да, клише!), но достаточно людей использовали это имя, поэтому я выбрал ближайшую лучшую пятницу для своего помощника, который будет очищать ссылки, запоминать задачи, хранить будущие заголовки блогов, мысли и многое другое (есть бесконечные возможности того, что может сделать помощник ИИ)

Так родился мой бот FridayAura, вы спросите, что означает AURA, ну, искусственно интеллектуальная утилита и помощник по реагированию.

Предпосылки

- У вас должен быть установлен NodeJS, вы можете проверить это, введя node -v
- У вас должна быть учетная запись телеграммы
- У вас должна быть учетная запись firebase

Создание бота для телеграмм

Ищите BotFather в телеграмме, как следует из названия, он обрабатывает всех ботов и может помочь вам создать своего.
- Чтобы начать разговор, введите /start
- Как видите, для создания нового бота нам нужно ввести /newbot
- Следуйте инструкциям и дайте имя своему боту, я назвал своего бота FridayAuraBot
- BotFather отвечает важной информацией
- Надежно храните ваши токен бота для использования HTTP API

Настройка NodeJS

Чтобы инициализировать проект NodeJS, выполните следующую команду (-y использует значения по умолчанию во время установки, это необязательно)

 npm init -y

Нам нужно установить необходимые библиотеки, которые являются firebase, а также библиотеки телеграмм.

Для этого мы можем запустить

npm install nodemon node-telegram-bot-api firebase-admin

Настройка Firebase

Создать новый проект

Введите название вашего проекта

Поскольку нам не нужен Google Analytics, мы можем отключить его.

Создайте новую базу данных firestore в категории Build.

Запустите тестовый режим и выберите предпочтительное местоположение

Ваша новая база данных FireStore готова и выглядит так:

Нам нужно изменить правила, чтобы наш бот мог выполнять функции CRUD (создавать, читать, обновлять, удалять).

Мы удаляем оператор if и публикуем изменения

Вернувшись на домашнюю страницу проекта, мы можем добавить веб-приложение в firebase.

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

Ваш файл JSON с ключом загружен

Переместите этот файл в каталог вашего проекта

Написание кода

firebase.js

В этот файл мы включим данные аутентификации нашей учетной записи службы, которые помогут нам использовать API Firebase, скопируйте следующие строки в ваш файл и сохраните его.

const {initializeApp, cert}= require("firebase-admin/app")
const {getFirestore} = require("firebase-admin/firestore")

const serviceAccount=require("PATH_TO_YOUR_PRIVATE_KEY_FILE")

initializeApp({
 credential:cert(serviceAccount)
})

const db= getFirestore()
module.exports={ db }

index.js

Для начала импортируем все необходимые библиотеки

const TelegramBot = require('node-telegram-bot-api');
const botToken = 'ENTER_YOUR_BOT_TOKEN_HERE';
const bot = new TelegramBot(botToken, { polling: true });
const { initializeApp, applicationDefault, cert } = require('firebase-admin/app');
const { getFirestore, Timestamp, FieldValue, Filter } = require('firebase-admin/firestore');
const {db}=require("PATH_TO_FIREBASE.JS")

Теперь, когда мы импортировали наши библиотеки, давайте начнем с функции для базовой функциональности, команды «/start».

bot.onText(/\/start/, (msg) => {
  const chatId = msg.chat.id;
  bot.sendMessage(chatId, 'Welcome to the FridayAuraBot!\nHow can I assist you?\nPossible use cases:\n\/todo: for appending to a todolist\n\/idea: for random ideas\n\/thoughts: for deep thoughts\n\/blog: for adding blog titles\n\/showtodo: to show todolist\n\/done: to remove item from todolist\n\/showtitles to show all blog titles');
});

Давайте проверим это, открыв терминал и набрав

nodemon index.js

И в телеграмме отправка /start нашему боту

Теперь давайте добавим некоторые функции, использующие Firebase. Эта функция написана для команды «/todo», которая добавляет задачу в коллекцию firebase под названием «todolist».
Мы будем использовать асинхронный обратный вызов, чтобы не возникало ошибок в операциях с базой данных.

bot.onText(/\/todo/, async (msg) => {
  const chatId = msg.chat.id;
  item=msg.text.substring(5)
  //item is where we store user input
  const data = {
  title: item,
  timestamp: FieldValue.serverTimestamp()
  };//JSON format data to be uploaded

  const res = await db.collection('todolist').doc(item).set(data);
  
  bot.sendMessage(chatId, `Item appended to to do list:${item}`);
});

Теперь мы можем добавить, что остальная часть функциональности разделена на различные функции.

bot.onText(/\/showtodo/, async (msg) => {
  
  const chatId = msg.chat.id;
  const todoRef = db.collection('todolist');
  const snapshot = await todoRef.get();//creating a snapshot of the todo reference to access and display all documents
  snapshot.forEach(doc => {
      console.log(doc.id, '=>', doc.data());
      bot.sendMessage(chatId, `-${doc.data().title}\n`);
  })
  
});

bot.onText(/\/done/, async (msg) => {
  const chatId = msg.chat.id;
  item=msg.text.substring(5)
  let flag = false;
  const todoRef = db.collection('todolist');
  const snapshot = await todoRef.get();
  snapshot.forEach(doc => {
      //console.log(doc.id, '=>', doc.data());
    if(item.trim()===doc.data().title.trim())
    {
      flag=true;
    }
  })
  if(flag)
  {
  const res = await db.collection('todolist').doc(item).delete();  
  bot.sendMessage(chatId, `Congratulations! You have removed "${item}" from your to do list`);
  }
  else
  {
    bot.sendMessage(chatId, `Sorry! "${item}" was never on the to do list`);
  }
});

bot.onText(/\/idea/, async (msg) => {
  const chatId = msg.chat.id;
  item=msg.text.substring(5)
  const data = {
  title: item,
  timestamp: FieldValue.serverTimestamp()
  };

  const res = await db.collection('ideas').add({
  title: item,
  timestamp: FieldValue.serverTimestamp()
  });
  bot.sendMessage(chatId, `idea "${item}" has been recorded with ref id: ${res.id}`);
});

bot.onText(/\/thoughts/, async (msg) => {
  const chatId = msg.chat.id;
  item=msg.text.substring(10)
  const data = {
  dump: item,
  timestamp: FieldValue.serverTimestamp()
  };

  const res = await db.collection('thoughts').add({
  dump: item,
  timestamp: FieldValue.serverTimestamp()
  });
  bot.sendMessage(chatId, `a reflective deep thought\n"${item} "\n has been recorded with ref id: ${res.id}`);
});

bot.onText(/\/blog/, async (msg) => {
  const chatId = msg.chat.id;
  item=msg.text.substring(5)
  const data = {
  blogtitle: item,
  timestamp: FieldValue.serverTimestamp()
  };

  const res = await db.collection('blog').doc(item).set(data);
  bot.sendMessage(chatId, `a blog title \n"${item} "\n has been added`);
});

bot.onText(/\/showtitles/, async (msg) => {
  const chatId = msg.chat.id;
  const todoRef = db.collection('blog');
  const snapshot = await todoRef.get();
  await bot.sendMessage(chatId,"The titles are:\n")
  snapshot.forEach(doc => {
      //console.log(doc.id, '=>', doc.data());
      bot.sendMessage(chatId, `-${doc.data().blogtitle}\n`);
  })
});


bot.on('polling_error', (error) => {
  // console.log(error)
  console.log("Polling error code: ",error.code);
  console.log("Error Message: ", error.message);
  console.log("Stack trace: ", error.stack);
})

Примечание.Чтобы ваш бот работал, index.js должен быть запущен, вы также можете разместить свой серверный код (будущие обновления).

Примеры

Будущие улучшения:

– Всегда активен (хост на Azure?)
– Напоминания
– Добавление описания к идеям/заголовкам блога (функции обновления)

Спасибо за ваше время, терпение и поддержку.
Вы можете найти полный код на GitHub