Как написать чат бота для telegram на javascript

Время на прочтение
5 мин

Количество просмотров 49K

Я начал погружение в мир IT лишь три недели назад. Серьезно, три недели назад я даже не понимал синтаксиса HTML, а знакомство с языками программирования заканчивалось школьной программой по Pascal 10-летней давности. Однако я решился поехать в IT-лагерь, для детей которого было бы неплохо сделать бота. Я решил, что это вряд ли так сложно.

С этого начался длинный путь, в рамках которого я:

  • развернул облачный сервер с Ubuntu,
  • зарегистрировался на GitHub,
  • выучил базовый синтаксис JavaScript,
  • прочитал тонну статей на английском и русском языках,
  • сделал, наконец, бота,
  • написал эту статью, наконец.

Выглядел итоговый результат примерно так:

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

А еще — для продвинутых программистов — просто чтобы их немного посмешить.

1. Как писать код на JS?

Я понимал, что стоит для начала хотя бы разобраться в синтаксисе языка. Выбор пал на JavaScript, просто потому что следующим шагом для меня было создание приложения на ReactNative. Я начал с курса на Codecademy и остался в большом восторге. Первые 7 дней бесплатно. Реальные проекты. Рекомендую. Прохождение его заняло порядка 25 часов. На самом деле далекоооо не все из него пригодилось. Вот так примерно выглядит структура курса и подробно первый блок.

2. Как зарегистрировать бота?

В начале мне очень помогла вот эта статья из блога некоего Арчакова. Он разжевывает самое начало. Но главное, что там есть — это инструкция по регистрации бота. Лучше я не напишу, и поскольку это самая легкая часть, просто напишу суть. Нужно создать бота и получить его API. Это делается через другого бота — @BotFather. Найдите его в telegram, напишите ему, пройдите простой путь и получите (сохраните!) API-ключ (это набор цифр и букв). Он пригодился мне позже.

3. Как выглядит код бота?

После долгого изучения статей, я понял, что стоит использовать какую-то библиотеку (сторонний код в формате модуля), чтобы не мучаться с изучением API телеграма и созданием с нуля больших кусков кода. Я нашел фреймворк telegraf, который нужно было как-то подключить к чему-то при помощи npm или yarn. Примерно так я понимал тогда, из чего состоит развертывание бота. Смеяться здесь. Я не обижусь. Больше всего при последующем создании бота мне помогли примеры, указанные внизу страницы:

3. Как создать собственный облачный сервер за 100 рублей

После долгих поисков я понял, что команда ‘npm’ из картинки выше относится к командной строке. Командная строка есть везде, но чтобы получилось ее исполнить, нужно поставить NodePackageManager. Проблема была в том, что программировал я на PixelBook с ChromeOS. Я пропущу здесь большой блок про то, как я познавал Linux — для большинства это пустое и ненужное. Если у вас есть Windows или MacBook, у вас уже есть консоль.

Если в двух словах, я поставил Linux через Crostini.

Однако в процессе я понял, что для постоянной работы бота (а не только когда у меня включен компьютер) мне нужен облачный сервер. Я выбрал vscale.io Я закинул 100 рублей, купил самый дешевый сервер Ubuntu (см.картинку).

4. Как подготовить сервер для запуска бота

После этого я понял, что нужно сделать на сервере какую-то папку, в которую я положу файл с текстом кода. Для этого в консоли (запускать прямо на сайте через кнопку «Открыть консоль») я вбил

mkdir bot

bot — это стало название моей папки. После этого я установил npm и Node.js, что позволит запускать мне потом код из файликов с разрешением *.js

sudo apt update
sudo apt install nodejs
sudo apt install npm

Очень рекомендую на этом этапе настроить подключение к серверу через свою консоль. Вот инструкция Это позволит работать с сервером напрямую через консоль своего компьютера.

5. Как написать код первого бота.

А вот теперь просто открытие для меня. Любая программа — это просто строки текста. Их можно вбить куда угодно, сохранить с нужным расширением и все. Ты прекрасен. Я использовал Atom, но реально, можно просто в блокноте стандартном писать. Главное — сохранить потом файл в нужном расширении. Это как написать текст в Word и сохранить.

Я сделал новый файл, в который вставил код из примера на странице telegraf и сохранил в файл index.js (вообще не обязательно называть файл так, но так принято). Важно — вместо BOT_TOKEN вставьте свой API-ключ из второго пункта.

const Telegraf = require('telegraf')

const bot = new Telegraf(process.env.BOT_TOKEN)
bot.start((ctx) => ctx.reply('Welcome!'))
bot.help((ctx) => ctx.reply('Send me a sticker'))
bot.on('sticker', (ctx) => ctx.reply(''))
bot.hears('hi', (ctx) => ctx.reply('Hey there'))
bot.launch()

6. Как закинуть код на сервер через github

Теперь мне нужно было закинуть как-то этот код на сервер и запустить его. Для меня это стало челленджем. В итоге, после долгих мытарств я понял, что проще будет создать файл на github, который позовляет обновлять код при помощи команды в консоли. Я зарегал аккаунт на github и сделал новый проект, куда и загрузил файл. После этого мне нужно было понять, как же настроить загрузку файлов с моего аккаунта (открытого!) на сервер в папку bot (если вдруг вы вышли из нее — просто напишите cd bot).

7. Как загрузить файлы на сервер через github ч.2

Мне нужно было поставить на сервер программу, которая будет загружать файлы с git. Я поставил git на сервер, вбив в консоль

apt-get install git

После этого мне нужно было настроить загрузку файлов. Для этого я вбил в командную строку

git clone git://github.com/b0tank/bot.git bot

В итоге все из проекта загрузилось на сервер. Ошибкой на данном этапе было, что я, по сути, сделал вторую папку внутри уже существующей папки bot. Адрес до файла выглядел как */bot/bot/index.js

Я решил пренебречь этой проблемой.

И чтобы подгрузить библиотеку telegraf, которую мы запрашиваем в первой строке кода, вбейте в консоль команду.

npm install telegraf

8. Как запустить бота

Для этого, находясь в папке с файлом (чтобы переходить из папки в папку через консоль — выполняйте команду формата cd bot Чтобы убедиться, что вы там, где нужно можно вбить команду, которая отобразит в консоли все файлы и папки, которые там лежат ls -a

Для запуска я ввел в консоль

node index.js

Если нет никакой ошибки — все хорошо, бот работает. Ищите его в телеграме. Если ошибка есть — применяйте свои знания из 1 пункта.

9. Как запустить бота в фоновом режиме

Достаточно быстро вы поймете, что бот работает только тогда, когда вы сами сидите в консоли. Чтобы решить эту проблему я использовал команду

screen

После этого появится экран с каким-то текстом. Это значит, что все хорошо. Вы на виртуальном сервере на облачном сервере. Чтобы понять лучше, как это все работает — вот статья. Просто заходите в свою папку и вбивайте команду по запуску бота

node index.js

10. Как работает бот и как расширить его функционал

Что же умеет наш бот из примера? Он умеет

bot.start((ctx) => ctx.reply('Welcome!'))

говорить «Welcome!» в момент старта (попробуйте поменять текст)

bot.help((ctx) => ctx.reply('Send me a sticker'))

в ответ на стандартную команду /help отправлять сообщение «Send me a sticker»

bot.on('sticker', (ctx) => ctx.reply(''))

в ответ на стикер отправлять одобрение

bot.hears('hi', (ctx) => ctx.reply('Hey there'))

отвечать «Hey there», если ему пишут ‘hi’
bot.launch()

Если вы посмотрите код на github, то быстро поймете, что сильно далеко от этого функционала я не ушел. Что активно используется, так это функция ctx.replyWithPhoto Она позволяет отправлять заданное фото или gif в ответ на определенный текст.

Значимая часть кода была написана детьми 11-13 лет, которым я дал доступ к боту. Они ввели свои user-case. Думаю, легко определить, какая часть сделана была ими.

Например, на сообщение «джейк» приходит гифка с известным персонажем из мультика Adventure Time.

Чтобы развивать бота дальше, подключать клавиатуру нужно смотреть примеры, например, отсюда

11. Как обновлять код и перезапускать бота

Не забывайте, что надо обновлять код не только на github, но и на сервере. Делать это просто — стопим бота (нажать ctrl+c),

— вводим в консоль, находясь в целевой папке, git pull
— вновь запускаем бота командой node index.js

END

Многие вещи, описанные в этом файле, будут супер очевидны для продвинутых программистов. Однако когда я сам пытался одним махом перепрыгнуть пропасть до мира ботов, мне очень не хватало подобного гайда. Гайда, в котором не пропускается очевидные и простые для любого IT-специалиста вещи.

В дальнейшем я планирую пост про то, как сделать свое первое приложение на ReactNative в таком же стиле, подписывайтесь!

Сегодня будем делать бота — это отличное (и быстрое) занятие, которое развивает уставший мозг и даёт возможность отправить друзьям ссылочку со словами «Смотри, это моё».

Для работы понадобятся

  • Редактор кода, чтобы писать код. Если не знаете, какой выбрать — мы уже рассказывали. Если не умеете писать код, то вот инструкция, как его написать и запустить.
  • Node.js любой версии, выше 0.12. Нужно, чтобы библиотека для ботов заработала.
    Как установить Node.js.
  • Консоль. Или встроенный в систему вариант, или какой-нибудь другой.

Шаг 1. Регистрируем бота

Находим в поиске Телеграма бота @botFather — это главный инструмент для создания ботов. Набираем в нём /newbot.

Придумываем название и имя боту. Название — то, как он будет подписан в списке контактов. Имя — строка, по которой его можно будет найти. Обратите внимание, что имя должно оканчиваться на bot. В ответ мы получим токен — длинную последовательность символов, которая пригодится нам в будущем. Мы назвали бота echoKeksBot, но вам придётся придумать другое название, потому что это уже занято. Извините.

Создание бота

Шаг 2. Создаём проект

Создаем папку в любом месте и открываем её в консоли. Там пишем npm init -y — эта команда создаст файл package.json, который выглядит примерно так:

Содержимое файла package.json

Теперь установим node-telegram-bot-api — это библиотека для создания телеграм-ботов на Node.js. Введём команду:

npm install --save --save-exact node-telegram-bot-api

Создадим пустой файл index.js и напишем там самого простого бота, который будет отвечать на любое сообщение:

bot.on('message', (msg) => {
  const chatId = msg.chat.id;
  bot.sendMessage(chatId, 'Привет, Друг!');
});

Шаг 3. Запускаем бота

Тут всё просто, в консоли пишем node index.js, заходим к нашему боту в телеграм и начинаем с ним общаться. Не закрывайте консоль — бот работает только на вашем компьютере, и без консоли он не станет отвечать.

Запуск бота

Как видим, бот успешно отвечает. Но бот-повторяха — не интересно, усложним задачу. Пусть бот присылает нам картинку.

Шаг 4. Отсылаем картинку

Добавим картинку с Кексом в папку с проектом. Для отправки изображения используем метод .sendPhoto() — передадим в него id чата и путь до картинки. Получится такой код:

bot.on('message', (msg) => {
  const chatId = msg.chat.id;
  bot.sendPhoto(chatId, 'keks.png');
});

Запускаем бота, проверяем, работает:

Получаем от бота изображение с Кексом

Шаг 5. Добавим клавиатуру. И пёсика

Добавим фотографию милого пёсика в корень проекта. Теперь там две картинки.

Создадим конфигурацию для клавиатуры в боте, пусть у нас будет 3 кнопки: «Хочу кота», «Хочу пёсика» и «Пойти учиться».

Получаем от бота изображение с пёсиком

// Конфиг клавиатуры
const keyboard = [
  [
    {
      text: 'Хочу кота', // текст на кнопке
      callback_data: 'moreKeks' // данные для обработчика событий
    }
  ],
  [
    {
      text: 'Хочу песика',
      callback_data: 'morePes'
    }
  ],
  [
    {
      text: 'Хочу проходить курсы',
      url: 'https://htmlacademy.ru/courses' //внешняя ссылка
    }
  ]
];

На нажатия первых двух кнопок мы ответим соответствующим сообщением в Телеграме, а последняя уведёт на внешний ресурс.

Чтобы отличить первые 2 кнопки, воспользуемся полем callback_data, где будем передавать тип кнопки. Для обработки нажатий добавим слушателя на событие callback_query, и в зависимости от значения query.data отправим нужную картинку к пользователю.

// Обработчик нажатий на клавиатуру
bot.on('callback_query', (query) => {
  const chatId = query.message.chat.id;

  let img = '';

  if (query.data === 'moreKeks') { // если кот
    img = 'keks.png';
  }

  if (query.data === 'morePes') { // если пёс
    img = 'pes.png';
  }

  if (img) {
    bot.sendPhoto(chatId, img, { // прикрутим клаву
      reply_markup: {
        inline_keyboard: keyboard
      }
    });
  } else {
    bot.sendMessage(chatId, 'Непонятно, давай попробуем ещё раз?', {
      // прикрутим клаву
      reply_markup: {
        inline_keyboard: keyboard
      }
    });
  }
});

Не забудем про возможные ошибки и предложим пользователю попробовать снова, если он ввёл что-то не то. Перезапустим бота и проверим — всё работает. Главное — не закрывать консоль, иначе бот перестанет отвечать.

Полный файл с кодом: index.js.

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

Сегодня будем делать бота — это отличное (и быстрое) занятие, которое развивает уставший мозг и даёт возможность отправить друзьям ссылочку со словами «Смотри, это моё».

Для работы понадобятся

  • Редактор кода, чтобы писать код. Если не знаете, какой выбрать — мы уже рассказывали. Если не умеете писать код, то вот инструкция, как его написать и запустить.
  • Node.js любой версии, выше 0.12. Нужно, чтобы библиотека для ботов заработала. Как установить Node.js.
  • Консоль. Или встроенный в систему вариант, или какой-нибудь другой.
  • VPN. Возможно но не факт, потому что Телеграм работает не везде.

Шаг 1. Регистрируем бота

Находим в поиске Телеграма бота @botFather — это главный инструмент для создания ботов. Набираем в нём /newbot.

Придумываем название и имя боту. Название — то, как он будет подписан в списке контактов. Имя — строка, по которой его можно будет найти. Обратите внимание, что имя должно оканчиваться на bot. В ответ мы получим токен — длинную последовательность символов, которая пригодится нам в будущем. Мы назвали бота echoKeksBot, но вам придётся придумать другое название, потому что это уже занято. Извините.

Шаг 2. Создаём проект

Создаем папку в любом месте и открываем её в консоли. Там пишем npm init -y — эта команда создаст файл package.json, который выглядит примерно так:

Теперь установим node-telegram-bot-api — это библиотека для создания телеграм-ботов на Node.js. Введём команду:

npm install —save —save-exact node-telegram-bot-api

Создадим пустой файл index.js и напишем там самого простого бота, который будет отвечать на любое сообщение:

bot.on(‘message’, (msg) => {
const chatId = msg.chat.id;
bot.sendMessage(chatId, ‘Привет, Друг!’);
});

Шаг 3. Запускаем бота

Тут всё просто, в консоли пишем node index.js, заходим к нашему боту в телеграм и начинаем с ним общаться. Не закрывайте консоль — бот работает только на вашем компьютере, и без консоли он не станет отвечать.

Как видим, бот успешно отвечает. Но бот-повторяха — не интересно, усложним задачу. Пусть бот присылает нам картинку.

Шаг 4. Отсылаем картинку

Добавим картинку с Кексом в папку с проектом. Для отправки изображения используем метод .sendPhoto() — передадим в него id чата и путь до картинки. Получится такой код:

bot.on(‘message’, (msg) => {
const chatId = msg.chat.id;
bot.sendPhoto(chatId, ‘keks.png’);
});

Запускаем бота, проверяем, работает:

Шаг 5. Добавим клавиатуру. И пёсика

Добавим фотографию милого пёсика в корень проекта. Теперь там две картинки.

Создадим конфигурацию для клавиатуры в боте, пусть у нас будет 3 кнопки: «Хочу кота», «Хочу пёсика» и «Пойти учиться».

// Конфиг клавиатуры
const keyboard = [
[
{
text: ‘Хочу кота’, // текст на кнопке
callback_data: ‘moreKeks’ // данные для обработчика событий
}
],
[
{
text: ‘Хочу песика’,
callback_data: ‘morePes’
}
],
[
{
text: ‘Хочу проходить курсы’,
url: ‘https://htmlacademy.ru/courses’ //внешняя ссылка
}
]
];

На нажатия первых двух кнопок мы ответим соответствующим сообщением в Телеграме, а последняя уведёт на внешний ресурс.

Чтобы отличить первые 2 кнопки, воспользуемся полем callback_data, где будем передавать тип кнопки. Для обработки нажатий добавим слушателя на событие callback_query, и в зависимости от значения query.data отправим нужную картинку к пользователю.

// Обработчик нажатий на клавиатуру
bot.on(‘callback_query’, (query) => {
const chatId = query.message.chat.id;

let img = »;

if (query.data === ‘moreKeks’) { // если кот
img = ‘keks.png’;
}

if (query.data === ‘morePes’) { // если пёс
img = ‘pes.png’;
}

if (img) {
bot.sendPhoto(chatId, img, { // прикрутим клаву
reply_markup: {
inline_keyboard: keyboard
}
});
} else {
bot.sendMessage(chatId, ‘Непонятно, давай попробуем ещё раз?’, {
// прикрутим клаву
reply_markup: {
inline_keyboard: keyboard
}
});
}
});

Не забудем про возможные ошибки и предложим пользователю попробовать снова, если он ввёл что-то не то. Перезапустим бота и проверим — всё работает. Главное — не закрывать консоль, иначе бот перестанет отвечать.

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

Тарас Голомозый, fullstack web-разработчик и преподаватель в школе программирования Elbrus Bootcamp, написал инструкцию по созданию простого бота на JavaScript с возможностью расширения функционала. В базовом варианте его задача — показывать текущую погоду по геолокации пользователя.

Пару слов об уровне знаний, на который рассчитан этот текст. Для создания бота достаточно иметь базовое представления о JavaScript, а также знать, как работает API. Перед началом работы нужно установить библиотеку telegraf.js, которая работает на базе официального API Telegram, и библиотеку для выполнения HTTP-запросов (например, axios).

Шаг первый: базовый функционал

Откроем редактор кода и инициализируем проект через терминал с помощью команды npm -y. После этого в проекте появится файл package.json. Теперь мы можем добавить все необходимые библиотеки командой npm i, после которой через пробел прописываются названия необходимых нам библиотек. Все названия можно посмотреть в документации: в этом примере это будут telegraf и axios.

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

Пока устанавливаются библиотеки, можно прочитать документацию к ним. У telegraf.js есть несколько примеров готового бота. Можно взять первый пример и посмотреть, как он работает.

Для этого создадим новый файл с именем bot.js и добавим в него следующий код:

const { Telegraf } = require('telegraf');

const bot = new Telegraf(process.env.BOT_TOKEN);
bot.start((ctx) => ctx.reply('Welcome'));
bot.help((ctx) => ctx.reply('Send me a sticker'));
bot.on('sticker', (ctx) => ctx.reply('👍'));
bot.hears('hi', (ctx) => ctx.reply('Hey there'));
bot.launch();

// Enable graceful stop
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));

В package.json пропишем стартовый скрипт для этого файла. Для этого в разделе scripts добавим новый пункт со следующим содержанием:

"start": "node bot.js"

Если мы запустим проект в терминале командой npm start, то увидим сообщение «Bot token is required». Получить токен можно через Telegram BotFather — официального бота мессенджера, который создает другие боты и управляет ими. В интерфейсе выбираем /start, затем — /newbot, и следом задаем имя и адрес. В этой инструкции это будет elbrusbootcampweatherbot.

После этого BotFather пришлет сообщение с токеном и ссылкой на бот. Копируем токен и вставляем его в третью строчку примера:

const bot = new Telegraf(process.env.BOT_TOKEN);

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

Первая строка отвечает за подключение библиотеки telegraf, которая непосредственно взаимодействует с API Telegram и позволяет нам использовать определенные методы для работы с ботом. В следующей строке создаем нового бота и указываем ключ доступа к нему.

Далее указано, как бот будет реагировать на различные команды: при нажатии /start он отправит сообщение welcome, при отправке стрикера — эмодзи и так далее. Последние две строчки нужны для того, чтобы выполнение ботом команд правильно завершалось в облачных сервисах.

Другие методы кроме /start нам не понадобятся, поэтому их можно смело удалить:

const { Telegraf } = require('telegraf');

const bot = new Telegraf(process.env.BOT_TOKEN);
bot.start((ctx) => ctx.reply('Welcome'));
bot.launch();

// Enable graceful stop
process.once('SIGINT', () => bot.stop('SIGINT'));
process.once('SIGTERM', () => bot.stop('SIGTERM'));

Добавим собственные методы: при отправке геолокации бот отвечает актуальном прогнозом погоды для этой территории. Первым делом напишем обработчик, который будет принимать сообщение от пользователя и выводить его в консоль.

bot.on ('message',(ctx) => {
  console.log('ctx.message');
} )

Теперь при отправке боту геолокации в консоли мы увидим объект location, в котором содержится широта и долгота. Добавим проверку: если в сообщении пользователя содержится объект location, данные из него отправляются на сервер через API агрегатора прогнозов погоды.

bot.on ('message',(ctx) => {
  if('ctx.message.location'){
    console.log('ctx.message.location');
} )

Шаг второй: подключаем API

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

Вставим пример в код, используя результат проверки ctx.message.location с указанием широты и долготы:

bot.on('message', (ctx) => {
  if (ctx.message.location) {
    const weatherAPIUrl = `https://openweathermap.org/data/2.5/weather?lat=${ctx.message.location.latitude}&lon=${ctx.message.location.longitude}&appid=439d4b8O4bc8187953eb36d2a8c26a02`;
  }
});

API-ключ можно создать в личном кабинете на сайте OpenWeather. Ключ указывается как параметр appid.

Следующим шагом нужно обратиться по адресу, предоставленному OpenWeather, и получить данные. Для этого используем библиотеку axios. Функция для подключения библиотеки указана в ее официальной документации и выглядит следующим образом:

const axios = require('axios');

Поскольку все операции со сторонним сервером выполняются асинхронно, добавим async и await в метод bot.on:

bot.on('message', async (ctx) => {
  if (ctx.message.location) {
    const weatherAPIUrl = `https://openweathermap.org/data/2.5/weather?lat=${ctx.message.location.latitude}&lon=${ctx.message.location.longitude}&appid=439d4b8O4bc8187953eb36d2a8c26a02`;
    const response = await axios.get(weatherAPIUrl);
  }
});

Теперь при отправке боту геолокации в консоли мы увидим информацию о погоде в текущем месте расположения пользователя. Остается только сформировать сообщение, которое бот отправит пользователю в качестве ответа. В тексте укажем название района и температуру в градусах Цельсия:

ctx.reply(`${response.data.name}: ${response.data.weather[0].main} ${response.data.main.temp} °C`);

Заключение

На этом все: итоговый код проекта можно найти в репозитории на GitHub.

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

node-telegram-bot-api-tutorial

This is a beginners’ guide for node-telegram-bot-api .

  • Creating new bot with BotFather
  • First message
  • Commands
  • Keyboards
  • User
  • Inline keyboards
  • parse_mode
  • Location and Number
  • Interacting with groups and channels

Creating new bot with BotFather

The following steps describe how to create a new bot:

  • Contact @BotFather in your Telegram messenger
  • To get a token, send BotFather a message that says /newbot
  • When asked for a name for your new bot choose something that ends with the word bot. For example, my_test_bot
  • If your chosen name is available, BotFather will send you a token
  • Save the token

Once your bot is created, you can set a Description for it. Description is a message in middle of the page usually describing what the bot can do.

To set Description for your bot in BotFather do the following:

  • Send /setdescription to BotFather
  • Select the bot for which you are writing a Description
  • Change the description and send it to BotFather

There are some other useful methods in BotFather which we won’t cover in this tutorial like /setcommands and other.

First message

Ok now you’re ready to go. Create a node project and install bot-api:

npm install --save node-telegram-bot-api

Create a file index.js (or any other name) and inside the file require node-telegram-bot-api:

const TelegramBot = require('node-telegram-bot-api');

  Then you need to assign your token which you got from BotFather:

const token = 'YOUR_TELEGRAM_BOT_TOKEN';

And now create a new bot :

const bot = new TelegramBot(token, {polling: true});

Let’s try out our bot and do some real world things. We need to get messages that user sends us , to do so we would use following code:

bot.on('message', (msg) => {

     //anything

});

Let’s create simple greeting here. Here’s big picture of our code :

const TelegramBot = require('node-telegram-bot-api');
const token = 'YOUR_TELEGRAM_BOT_TOKEN';
const bot = new TelegramBot(token, {polling: true});

bot.on('message', (msg) => {

  //anything

});

We were trying to greet and we’ll do it here:

bot.on('message', (msg) => {

var Hi = "hi";
if (msg.text.toString().toLowerCase().indexOf(Hi) === 0) {
bot.sendMessage(msg.chat.id,"Hello dear user");
}

});

Ok , now open up your command prompt and type:

Go to your bot and hit on /start and then type "Hi" to it:

So now that you know how to send and receive messages in your bot you may want to put some salt on it:

bot.on('message', (msg) => {

var hi = "hi";
if (msg.text.toString().toLowerCase().indexOf(hi) === 0) {
bot.sendMessage(msg.chat.id,"Hello dear user");
}

var bye = "bye";
if (msg.text.toString().toLowerCase().includes(bye)) {
bot.sendMessage(msg.chat.id, "Hope to see you around again , Bye");
}

});

This time we’re using «includes» method so if user sends us anything containing «bye» word we’ll send him back the message:

And definitely you can use any other string method that you want.

Commands

That’s really common to send user a message describing use of bot while he taps on «/start». (these are called commands)
To do so :

bot.onText(//start/, (msg) => {

bot.sendMessage(msg.chat.id, "Welcome");

});

Let’s create another command that will send a picture to user:

bot.onText(//sendpic/, (msg) => {

bot.sendPhoto(msg.chat.id,"https://www.somesite.com/image.jpg" );

});

So now if you write «/sendpic» on your bot an image will be sent.
Sending audios is same and simple you can use «sendAudio» method .

Now you might have seen some pictures containing caption with them like the following picture.

Well , How to to create these?
Answer is really simple you can send a caption with option on photo like so :

bot.onText(//sendpic/, (msg) => {

bot.sendPhoto(msg.chat.id,"https://www.somesite.com/image.jpg",{caption : "Here we go ! nThis is just a caption "} );

});

So now you know how to create captions and how to go to new line in your messages by typing n .

Keyboards

Let’s go a step further and start working with keyboards.
keyboards are actually the ones shown in this picture:

Keyboards are nothing but an easy way to send fixed messages. It’s like you’re not forcing users to write something down and send it to bot, but instead you’re demonstrating them some options that they can tap on and send back as an answer.
So let’s see how we can create Keyboards , we’ll send a Keyboard on «/start» message:

bot.onText(//start/, (msg) => {

bot.sendMessage(msg.chat.id, "Welcome", {
"reply_markup": {
    "keyboard": [["Sample text", "Second sample"],   ["Keyboard"], ["I'm robot"]]
    }
});

});

So now if you run you will see:

As I said in fact Keyboards are not nothing but automatic type and send for user. There is no difference if you write «I’m robot» and sending on your own or you click on Keyboard. Let’s do something simple when that «I’m robot» is received.So add this up to your previous on message:

bot.on('message', (msg) => {
var Hi = "hi";
if (msg.text.toString().toLowerCase().indexOf(Hi) === 0) {
    bot.sendMessage(msg.chat.id, "Hello dear user");
}
var bye = "bye";
if (msg.text.toString().toLowerCase().includes(bye)) {
    bot.sendMessage(msg.chat.id, "Hope to see you around again , Bye");
}
var robot = "I'm robot";
if (msg.text.indexOf(robot) === 0) {
    bot.sendMessage(msg.chat.id, "Yes I'm robot but not in that way!");
}
});

So now if you go to your bot tap on start you see Keyboards and if you tap on I’m robot you’ll see the message. Note that there is no difference if you type it or you send it by Keyboards.

User

node-telegram-bot-api does not have any method to get users information but in case if you want to, you can get information like so:

var Hi = "hi";
if (msg.text.toString().toLowerCase().indexOf(Hi) === 0) {
    bot.sendMessage(msg.from.id, "Hello  " + msg.from.first_name);
}

And if you wanted to get user profile pictures you can use getUserProfilePhotos .

Inline Keybords

This section is under construction…

parse_mode

If you want to send messages with some style there, here is how it goes. parse_mode defines how you want you message to be rendered.You can define it inside in your options when sending message.
Available option are HTML and Markdown.Let’s see how it works in action:

bot.on('message', (msg) => {

 var Hi = "hi";
 if (msg.text.toString().toLowerCase().indexOf(Hi) === 0) {
   bot.sendMessage(msg.chat.id,"<b>bold</b> n <i>italic</i> n <em>italic with em</em> n <a href="http://www.example.com/">inline URL</a> n <code>inline fixed-width code</code> n <pre>pre-formatted fixed-width code block</pre>" ,{parse_mode : "HTML"});
   }
});

So you get idea where parse_mode is defined.Now if we run this:

So that’s how we do it with Html you can also write with Markdown.As mentioned in official api of Telegram only these tags are supported till now:

<b>bold</b>, <strong>bold</strong>
<i>italic</i>, <em>italic</em>
<a href="http://www.example.com/">inline URL</a>
<code>inline fixed-width code</code>
<pre>pre-formatted fixed-width code block</pre>

And for Markdown you can only use:

*bold text*
_italic text_
[text](http://www.example.com/)
`inline fixed-width code`

Location and Number

There are some methods that enable you to send users location.
Here is an example:

bot.on('message', (msg) => {
    var location = "location";
    if (msg.text.indexOf(location) === 0) {
        bot.sendLocation(msg.chat.id,44.97108, -104.27719);
        bot.sendMessage(msg.chat.id, "Here is the point");

    }
});

And there is also sendVenue.
To send a phone number you can use sendContact.

Interacting with groups and channels

One interesting use of bots is in groups and channels.You can use bots to manage groups , receiving users messages and sending group messages. You can even send keyboards to members so that they can use the bot easier.
For better understanding of how bots can be useful in groups let’s create one and add it to a group.
So we want to create a bot that says «Have a nice day Username» when any member of group said something containing «Bye» keyword.
Before doing anything you have to know that a bot has no accessibility to users messages unless we add it as of a administrator.
And if don’t do that bot will only has access to Commands that any user sends to group.And all of this is because of the privacy policy that Telegram messenger follows which I think is right.
So let’s get back to creating that bot , actually we don’t have to do anything different than creating bot for a single user usage , everything is similar.

bot.on('message', (msg) => {

var bye = "bye";
if (msg.text.toString().toLowerCase().includes(bye)) {
bot.sendMessage(msg.chat.id, "Have a nice day " + msg.from.first_name);
}

});

Now that we wrote codes go ahead and add this bot to a group , after adding it set it as of a administrator of the group so that it could get users messages.
Now say something that includes «bye»:

Now let’s do another thing , write some codes that bot will remove a person from group if they say a specific word.For instance you can create a bot that will remove member if they curse in group.
Here we will write codes that if someone says anything containing «idiot» bot will remove that person from group.

bot.on('message', (msg) => {

var what = "idiot";
if (msg.text.includes(what)) {
bot.kickChatMember(msg.chat.id,  msg.from.id);
}

});

Here we have used kickChatMember method to remove a member it receives two parameters , first one is id of chat and second one is id of user which you want to remove.Now if you add this bot among admins of a group and somebody says something containing «idiot»:

We can’t cover all methods there are some other methods related to groups and channels: getChat , getChatAdministrators , getChatMembersCount , getChatMember , leaveChat

Contributing

  • If you found any typo or grammatically wrong sentence you can just make a PR.(In case you were not interested to, you can open an issue.)
  • If you have anything in mind that can improve this tutorial please make a PR.

Последнее время начал увлекаться разработкой приложений на Node.JS. Понравился своей гибкостью и тем, что приложения можно писать на JavaScript, а с ним я хоть немного дружу.

Недавно написал скрипт, который следит за активностью группы в ВК. А чуть позже, решил поинтересоваться Telegram API. Дуровы всегда умели делать качественный продукт и Telegram меня обрадовал своей быстротой и возможностью создания своего бота с понятным даже новичку API.

И в этой статье я коротко расскажу о том, как создать своего бота на Node.JS. Кстати, вот ссылка на репозиторий бота.

Первым делом, нам надо создать своего бота и получить Token. Волноваться вам не стоит насчет тяжести создания бота, для этого у нас есть @BotFather.

Если вы открыли чат с ботом, кликаем на кнопку «Start«.

После чего, бот нам выдает все доступные команды.

Отправляем команду /newbot или кликаем по активной ссылке этой команды. Далее, бот нас попросить ввести имя для нашего бота.

Можете не париться с именем и вписать любое тестовое имя. Плюс в том, что вы в любой момент сможете удалить тестового бота или поменять имя.

Я решил во время статьи создать бота для этого блога и назвал его «Archakov Blog«.

На последнем этапе, бот попросит вас придумать никнейм (логин). К никнейму в конце обязательно надо добавить суффикс «bot» можно и «Bot«. К сожалению, никнейм поменять больше не получится. Если это ваш первый бот, не парьтесь и придумайте любой никнейм.

В итоге, получаем сообщение о том, что бот был создан и в конце будет указан его токен. Этот токен нам пригодится в процессе разработки.

[info] Не советую делиться токеном с другими людьми. Так как он дает полный доступ к вашему боту. Начиная от редактирования имени и до удаления бота.

Теперь приступим к написанию кода и первым делом установим Node.JS. У меня OS X и хочу предупредить, что от операционной системы не будет зависеть разработка нашего бота.

Как установить Node.JS рассказывать я не хочу и не буду. Для этого обращаемся к гугл с запросом как установить Node.JS.

После того, как установили Node.JS, начинаем разрабатывать наше приложение, а точней бота. Node.JS ищет в каждой папке наличие папки node_modules с модулями, откуда он и будет подключать библиотеку для работы с Telegram API.

Советую поучиться работать с npm командой в консоли. Заранее установите этот менеджер пакетов, он нам скоро пригодится. Кстати, очень крутая и полезная штука, в будущем пригодится. Особенно, когда наступит апокалипсис, будете сидеть и пакеты устанавливать…

Создаем папку с тестовым проектом, к примеру telegram-bot. Далее, в этой папке создаем файл index.js и все! Вы красавчик! Бот создан, можете работать с ним.

Ага, канешна. Код сам не напишется!

Прежде чем его и писать, установим модуль node-telegram-bot-api. Для этого открываем консоль, пропишем путь к директории нашего проекта cd telegram-bot (укажите полный путь к этой папке).

В моем случае, это cd /Applications/MAMP/htdocs/telegram-bot.

Если вы на Windows, советую создавать папку в корне диска, чтобы можно было обращаться к проекту по короче, к примеру cd C:telegram-bot.

Отлично, теперь не забываем про npm. В консоли вбиваем команду: npm install node-telegram-bot-api или yarn add node-telegram-bot-api (в зависимости от того, что вы используете yarn или npm).

И через несколько секунд модуль установился. Ура! В репозитории уже есть пример кода и с помощью этого кода, сделаем своего мега-тру-бота.

Теперь перейдем к файлу index.js и напишем немного кода.

_23

// Подключаем библиотеку для работы с Telegram API в переменную

_23

var TelegramBot = require('node-telegram-bot-api');

_23

_23

// Устанавливаем токен, который выдавал нам бот

_23

var token = 'ТУТ_ВСТАВЛЯЕМ_ТОКЕН';

_23

// Включить опрос сервера. Бот должен обращаться к серверу Telegram, чтобы получать актуальную информацию

_23

// Подробнее: https://core.telegram.org/bots/api#getupdates

_23

var bot = new TelegramBot(token, { polling: true });

_23

_23

// Написать мне ... (/echo Hello World! - пришлет сообщение с этим приветствием, то есть "Hello World!")

_23

bot.onText(//echo (.+)/, function (msg, match) {

_23

var fromId = msg.from.id; // Получаем ID отправителя

_23

var resp = match[1]; // Получаем текст после /echo

_23

bot.sendMessage(fromId, resp);

_23

});

_23

_23

// Простая команда без параметров

_23

bot.on('message', function (msg) {

_23

var chatId = msg.chat.id; // Берем ID чата (не отправителя)

_23

// Фотография может быть: путь к файлу, поток (stream) или параметр file_id

_23

var photo = 'cats.png'; // в папке с ботом должен быть файл "cats.png"

_23

bot.sendPhoto(chatId, photo, { caption: 'Милые котята' });

_23

});

В начале кода мы подключили модуль (библиотеку) для работы с Telegram API. Далее, в переменной token вставляем наш токен, который выдавал нам BotFather при создании нашего бота.

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

Давайте в качестве моего примера, попробуем сделать напоминалку важных дел. Конечно, пример не ахти, но кому-нибудь будет полезно.

Подключаем модуль для работы с Telegram API и прописываем токен:

_10

var TelegramBot = require('node-telegram-bot-api');

_10

_10

var token = 'ТУТ_ВСТАВЛЯЕМ_ТОКЕН';

_10

var bot = new TelegramBot(token, {polling: true});

Далее, создаем переменную в которой будут храниться все заметки от пользователя.

Добавляем команду /напомни, с помощью которой и будем добавлять напоминание.

_10

bot.onText(/напомни (.+) в (.+)/, function (msg, match) {

_10

var userId = msg.from.id;

_10

var text = match[1];

_10

var time = match[2];

_10

_10

notes.push({ 'uid': userId, 'time': time, 'text': text });

_10

_10

bot.sendMessage(userId, 'Отлично! Я обязательно напомню, если не сдохну :)');

_10

});

  • userId — хранит ID пользователя который прислал сообщение.
  • text — хранит первый параметр — текст. Его бот и должен прислать мне.
  • time — хранит второй параметр — время. Устанавливаем время когда прийдет уведомление.

Сохраняем все эти параметры в наш массив notes и бот отправляет сообщение, что запись успешно сохранилась.

Теперь надо поставить таймер, он будет каждую секунду проверять записи, которые совпадают с конкретным временем. Если одно из напоминаний соответствует настоящему времени (часу и минуте), то отправляем пользователю напоминание.

_10

setInterval(function(){

_10

for (var i = 0; i < notes.length; i++) {

_10

const curDate = new Date().getHours() + ':' + new Date().getMinutes();

_10

if (notes[i]['time'] === curDate) {

_10

bot.sendMessage(notes[i]['uid'], 'Напоминаю, что вы должны: '+ notes[i]['text'] + ' сейчас.');

_10

notes.splice(i, 1);

_10

}

_10

}

_10

}, 1000);

Чтобы вы поняли как работает код выше, я нарисовал схему:

Итого:

_26

var TelegramBot = require('node-telegram-bot-api');

_26

_26

var token = 'ТУТ_ВСТАВЛЯЕМ_ТОКЕН';

_26

var bot = new TelegramBot(token, {polling: true});

_26

_26

var notes = [];

_26

_26

bot.onText(/напомни (.+) в (.+)/, function (msg, match) {

_26

var userId = msg.from.id;

_26

var text = match[1];

_26

var time = match[2];

_26

_26

notes.push({ 'uid': userId, 'time': time, 'text': text });

_26

_26

bot.sendMessage(userId, 'Отлично! Я обязательно напомню, если не сдохну :)');

_26

});

_26

_26

setInterval(function(){

_26

for (var i = 0; i < notes.length; i++) {

_26

const curDate = new Date().getHours() + ':' + new Date().getMinutes();

_26

if (notes[i]['time'] === curDate) {

_26

bot.sendMessage(notes[i]['uid'], 'Напоминаю, что вы должны: '+ notes[i]['text'] + ' сейчас.');

_26

notes.splice(i, 1);

_26

}

_26

}

_26

}, 1000);

Сохраняем наш скрипт, я назвал reminder.js. Запускаем его через консоль, командой node reminder.js

В итоге, я получил свое ожидаемое напоминание.

Спасибо за внимание. Не ленитесь учить JavaScript, за ним будущее веб и в частности всей галактики! Так же, выкладываю полный файл reminder.js.

Как всем уже давно известно, в популярном клиенте для обмена мгновенными сообщениями Telegram появилась возможность создавать специальных ботов, которые могут оказаться весьма полезными, будучи добавленными в групповые чаты. Боты могут показывать участникам конференции различную полезную информацию, будь то последние новости какого-либо интересного сайта, погоду или курс валют. Функциональность программ для ботов практически не ограничена, например, можно реализовать бота, который будет отправлять в приватный или групповой чат фотографию с подключенной к компьютеру Web-камеры или мониторить температуру процессора на сервере. К примеру, запустив программу бота на домашнем компьютере, можно будет следить за какими-нибудь его показателями удалённо, просто отправляя команды боту с любого устройства, на котором установлен клиент Telegram. Однако, существует несколько ограничений, которые реализованы на уровне Telegram Bot API:

  • Во-первых, бот не может написать первым, он должен обязательно отозваться на команду пользователя;
  • Во-вторых, боты не могут отвечать на сообщения друг-друга.

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


Дайджест-бот, отдающий накопленные сообщения за день в процессе работы. Скриншот из Desktop’ного клиента Telegram.

Для сообщества любителей мобильных гаджетов от Motorola — MotoFan.Ru существует весьма активная конференция в Telegram, участником которой я также являюсь. Мной было замечено, что для того, чтобы отметить значимое событие, произошедшее в течении дня, или какую-нибудь важную информацию, пользователи часто прибегают к использованию тега #digest. Подобным тегом отмечаются сообщения, которые по мнению участников конференции необходимо добавить в сводку текущий событий. При этом посетители группового чата, которые появляются в конференции достаточно редко, могут не читать огромное количество оставленных ранее сообщений, а выделить с помощью тега #digest только основную информацию. Но для этого им нужно воспользоваться поиском тега по сообщениям и попрыгать по листингу чата, что достаточно неудобно. Поэтому возникла идея создания дайджест-бота, который будет накапливать и сохранять все сообщения участников конференции, отмеченные тегом #digest за какой-либо срок, например, за неделю, а потом выдавать их скопом по команде /digest в чат. Это весьма удобно, в отличие от ручного поиска необходимых сообщений.

Содержание:

1. Знакомьтесь, Гаечка :3
2. Подготовка окружения к созданию бота на JavaScript и Node.js
3. Создаём профиль бота с помощью @BotFather
4. Реализация простейшего Hello World!-бота на JavaScript
5. Реализация дайджест-бота на JavaScript
5.1. Обработчик тега #digest
5.2. Обработчик команды /digest
5.3. Функция deleteObsoleteDigestMessages()
5.4. Генерация ответа бота на команду /digest
5.5. Заключение по дайджест-боту
6. Реализация валютного бота на JavaScript
7. Реализация упрощённого дайджест-бота на Python
8. Реализация бота, отправляющего случайную цитату с bash.im, на JavaScript
9. Реализация JavaScript-ботов, работающих со стикерами, мультимедийными объектами и интерактивными кнопками
9.1. Бот, отправляющий в ответ на стикер свой стикер
9.2. Бот, отправляющий в ответ на команду мультимедийный объект в чат
9.3. Бот, работающий с интерактивными кнопками
10. Заключение, полезные ссылки и ресурсы

1. Знакомьтесь, Гаечка :3

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


Gadget Hackwrench — оригинальное имя персонажа из мультфильма Chip ‘n Dale Rescue Rangers, которое российскими локализаторами было переведено как Гаечка.

Позже Гаечке были добавлены некоторые другие возможности, которые часто были нужны участникам конференции MotoFan.Ru: например, демонстрация различных финансовых графиков, валютные котировки и курс драгоценных металлов по ЦБ РФ. Команда /digest стала понимать аргументы, например, /digest 2 выводит сводку событий за два дня, а /digest 7 за неделю. Но реализация этого функционала — это уже другая история, которая не будет затронута в рамках этой статьи. Поскольку исходный код бота был выложен под лицензией MIT, любой желающий может посмотреть на то как и каким образом работает программа и, кроме того, поучаствовать в её разработке. Ссылку на исходный код можно найти в конце статьи.

<< Перейти к содержанию

2. Подготовка окружения к созданию бота на JavaScript и Node.js

Благодаря тому, что команда разработчиков Telegram реализовала простой и хорошо документированный API для работы с ботами, привязки к различным языкам программирования и популярным современным технологиям не заставили себя ждать. Для реализации задуманной идеи я выбрал связку языка программирования JavaScript и фреймворка Node.js, поскольку для Node.js был доступен хорошо документированный пакет node-telegram-bot-api, являющийся абстракцией и удобной надстройкой над официальным Telegram Bot API. С языком программирования JavaScript я уже сталкивался и немного знаком с ним вкупе с технологией QtQuick/QML. Именно поэтому мной и был выбран Qt Creator в качестве IDE для разработки. Эта среда предоставляет базовую поддержку JavaScript, которую с лихвой хватило для удобной навигации по коду проекта. Кроме самого JavaScript’а меня прельстила простота установки необходимых зависимостей в Node.js с помощью специального менеджера пакетов, а также лёгкость разворачивания приложения на любом GNU/Linux-сервере. Реализация дайджест-бота на языке программирования Python отошла в «долгий ящик» и была написана лишь по просьбе одного из участников конференции, её можно будет посмотреть ниже. Выбор языка и технологии для имплементации вашего бота это дело вкуса, вы сами должны решить что для вас наиболее предпочтительно.


Работа с JavaScript кодом дайджест-бота в Qt Creator IDE (кликабельно).

Итак, подготовим окружение, необходимое для запуска и написания бота. Предполагается, что вы работаете в любом deb-based дистрибутиве GNU/Linux и имеете навык работы с консолью. Пользователи дистрибутивов, отличных от deb-based могут самостоятельно найти аналоги устанавливаемых пакетов в своих репозиториях и инсталлировать их с помощью соответствующего системного пакетного менеджера. Пользователи MS Windows тоже могут произвести инсталляцию необходимых программ, но идеологически правильнее будет развернуть виртуальную машину с любым GNU/Linux дистрибутивом в специальной программе виртуализации, например, в бесплатном VMWare Player.

Установку Node.js и сопутствующего ему пакетного менеджера можно произвести следующими командами, введя их в терминале:

sudo aptget install nodejs

sudo aptget install npm

Затем, необходимо создать директорию, в которой можно будет ставить эксперименты и разворачивать бота и перейти в неё. Это тоже проще всего сделать из терминала:

mkdir ~/Deploy/

cd ~/Deploy/

Тильда (~) перед названием директории означает обращение к вашему домашнему каталогу. Вы можете создать директорию для экспериментов в любом удобном для вас месте. Теперь в свежесозданный каталог нужно установить необходимые пакеты с помощью пакетного менеджера Node.js:

npm install nodetelegrambotapi

npm install request


Каталог со всеми необходимыми компонентами для запуска бота, эмулятор терминала Konsole.

Заметьте, что пакеты установятся локально в ту директорию, в которой вы находитесь. В нашем случае это ~/Deploy/. Вы можете установить их глобально в систему, для этого у npm install существует специальный ключ −−global. Пакет node-telegram-bot-api, как было сказано выше, необходимая обёртка над официальным Telegram Bot API, связывающая его с Node.js, а пакет request может пригодиться нам для получения различных файлов из Интернета. В общем случае он не нужен и обычно уже идёт в стандартной поставке вместе с Node.js, но это зависит от дистрибутива. Скорее всего вам вовсе не потребуется эта зависимость, но на всякий случай установим и её.

Итак, окружение готово к работе. Теперь ваш компьютер является сервером для различных приложений на Node.js, частным случаем которых являются боты для Telegram. При желании бота можно будет перенести на какой-нибудь вменяемый хостинг, поддерживающий Node.js и запускать его оттуда. Для отладки Node.js приложений можно воспользоваться специальной облачной Web-платформой Cloud9 IDE.

И ещё нужно отметить кое-что важное, существует две разновидности ботов для Telegram: WebHook-боты с подписанным HTTPS-сертификатом и так называемые Polling-боты. Первых ботов дёргает главный сервер Telegram’а, а вторые сами постоянно ходят на сервер и сканируют чаты на предмет новых сообщений в них. Для реализации ботов первого типа нужен специальный валидный HTTPS-сертификат, причём самоподписанный не годится, поэтому рассматривать в этой статье мы их не будем. Для экспериментов и для простеньких ботов с головой хватит и Polling-режима, задержка в полсекунды не слишком критична на мой взгляд. Эти режимы регламентируются официальным Telegram Bot API и имеют полную реализацию во всех популярных пакетах-обёртках, в node-telegram-bot-api в том числе. При желании и наличии подходящего сертификата вы можете переделать Polling-бота в WebHook-бота, использующего HTTPS-сертификат, следуя официальной документации.

На этом теоретическая часть закончена. Переходим к следующим действиям.

<< Перейти к содержанию

3. Создаём профиль бота с помощью @BotFather

Для экспериментов нам потребуется «физическая сущность» бота в сети Telegram, его профиль, который можно добавлять в групповые чаты или просто начать с ним персональную беседу. Бот должен быть связан с запущенной на вашем компьютере программой посредством специального индивидуального и уникального токена. Заметьте, что этот токен предоставляет доступ к «физической сущности» вашего бота, а следовательно должен быть секретным. К счастью, если токен скомпрометирован, функционал Telegram позволяет его отозвать.


Пример создания профиля бота с помощью @BotFather. Установка изображения аватара в профиль.

@BotFather является специальным ботом, который может создавать профили других ботов, а так же выдавать их токены. Для создания собственного профиля будущего бота, просто начните разговор с @BotFather, после чего он добавится вам в список контактов. Небольшой совет: отправив сообщение, содержащее «@BotFather» в любой чат, вы получите ссылку на профиль бота и возможность начать разговор с ним, просто нажав кнопку «Send Message».

Для создания бота @BotFather‘у в чат необходимо отправить команду /newbot, после чего задать его имя, которое будет отображено в профиле и username, через который пользователи Telegram смогут получить ссылку на профиль. Заметьте, что username обязательно должен заканчиваться на «_bot», например, @MySuperTest_bot. Выберите тот username, который нравится вам и не занят. После того, как вы отправите всю необходимую информацию, @BotFather должен выдать вам уникальный токен бота. Рекомендую записать его в текстовый файл, сохранить и спрятать куда-нибудь в укромное местечко.


Общие команды бота вместе с описанием, установленные с помощью /setcommands и быстрый доступ к ним.

Далее, отправляя @BotFather‘у команды, начинающиеся с «/set» можно настроить различные параметры бота, например: установить ему имя, аватар, текст в профиль и описание. Всё достаточно интуитивно и прозрачно, но есть пара важных моментов.

Разберёмся сначала с командой /setcommands; она устанавливает команды, которые будут отображены в чате по нажатию специальной пиктограммы быстрого доступа (см. изображение выше). Кроме того, пользователь может быстро выбрать необходимую ему команду бота во всплывающей подсказке, просто набрав в чате «/». Весьма важно заполнить эту информацию, пример формата заполнения следующий:

digest Get digest from current chat.

rouble Get current exchange rate of RUB.

grivna Get current exchange rate of UAH.

help Extended help for bot commands.

Рекомендую сохранить текст описания команд в какой-нибудь файл, так как при изменении этого списка вам придётся его отправлять заново.

Следующие команды, на которые надо обратить особое внимание, это /setjoingroups и /setprivacy. Первая команда даёт возможность пользователям добавлять вашего бота в групповые чаты (если мне не изменяет память, по дефолту эта возможность включена), а вторая запрещает боту просматривать все сообщения в группе, кроме команд. Обязательно отключите эту способность, так как для дайджест-бота критически важна возможность мониторинга всех сообщений пользователей на предмет присутствия в них тега #digest. В общем, выставите настройки так, чтобы пользователи могли добавлять бота в групповые чаты (/setjoingroups в ENABLED) и бот мог мониторить сообщения в них (/setprivacy в DISABLED).

Теперь у нас есть токен и настроенный профиль. Самое время взяться за написание Hello World!-бота!

<< Перейти к содержанию

4. Реализация простейшего Hello World!-бота на JavaScript

Перейдём в созданную ранее директорию ~/Deploy/, создадим там файл «HelloWorldBot.js» с помощью любого, удобного вам текстового редактора с поддержкой и подсветкой синтаксиса JavaScript. Вставим в этот файл следующий текст:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

var TelegramBot = require(‘node-telegram-bot-api’);

var token = ‘WRITE_YOUR_TOKEN_HERE’;

var botOptions = {

    polling: true

};

var bot = new TelegramBot(token, botOptions);

bot.getMe().then(function(me)

{

    console.log(‘Hello! My name is %s!’, me.first_name);

    console.log(‘My id is %s.’, me.id);

    console.log(‘And my username is @%s.’, me.username);

});

bot.on(‘text’, function(msg)

{

    var messageChatId = msg.chat.id;

    var messageText = msg.text;

    var messageDate = msg.date;

    var messageUsr = msg.from.username;

    if (messageText === ‘/say’) {

        sendMessageByBot(messageChatId, ‘Hello World!’);

    }

    console.log(msg);

});

function sendMessageByBot(aChatId, aMessage)

{

    bot.sendMessage(aChatId, aMessage, { caption: ‘I’m a cute bot!’ });

}

Вместо WRITE_YOUR_TOKEN_HERE не забудьте вписать выданный вам токен, соблюдая синтаксис, то есть аккуратно заключив его в кавычки. Сохраним файл и пройдёмся по коду с комментариями.

Самая первая строка указывает на то, что необходимо использовать пакет node-telegram-bot-api, уже развёрнутый нами в директорию ~/Deploy/. Далее идёт описание необходимых боту аргументов и опций: это ваш токен и опция polling, определяющая разновидность бота. В данном случае эта опция говорит о том, что бот будет мониторить чат сам, без помощи главного сервера Telegram. Далее создаётся объект bot, с которым мы и будем работать. Вызов функции getMe().then() происходит при успешной авторизации токена бота и выдачи управления программе. При этом в качестве аргумента функция getMe().then() принимает функцию function(me) первым аргументом которой является объект, с помощью которого можно получить различную информацию о вашем боте и, в данном случае, вывести её в консоль. Далее, самая главная функция bot.on(‘text’, …) вызывается когда бот видит чьё-либо сообщение в чате. В качестве первого аргумента она принимает тип отслеживаемого сообщения (об этом можно подробнее почитать в документации node-telegram-bot-api), а в качестве второго аргумента она принимает функцию function(msg) первым аргументом которой является объект, с помощью которого можно «вынуть» различную информацию из полученного сообщения. Именно этим и занимаются нижеследующие строки. В переменной messageChatId сохраняется id чата, из которого пришло сообщение; в messageText — текст; в messageDate — дата, в формате: секунды, прошедшие с UNIX-time; в messageUsr — ник участника, отправившего сообщение.

Далее текст сообщения проверяется на соответствие команде /say; и если пользователь действительно отправил эту команду, вызывается функция sendMessageByBot(), являющаяся обёрткой метода bot.sendMessage(). В функцию sendMessageByBot() необходимо передать два аргумента: первый — id чата, в который нужно отправить сообщение, а второй — собственно, текст отправляемого сообщения. В нашем случае id чата, в который нужно доставить сообщение, это id чата из которого и была получена команда /say. Далее для отладки можно вывести объект msg со всеми его полями прямо в стандартный вывод консоли.

Надеюсь, с этим всё понятно. Теперь необходимо просто запустить нашего бота на исполнение. Для этого в терминале, находясь в директории ~/Deploy/, набираем команду:

nodejs HelloWorldBot

В консоль при удачном соединении и успешной авторизации будет выведена информация о профиле вашего бота. Если этого не произошло, то вы где-то ошиблись. Проверьте интернет-соединение на компьютере, где запускаете программу и корректный ввод токена.


Демонстрация Hello World!-бота, отвечающего на команду /say.

Если всё получилось, программа останется на выполнении. Теперь в клиенте Telegram можно начать диалог с ботом или добавить его в группу. Если боту отправить команду /say, то он выдаст вам в чат сообщение, содержащие текст «Hello World!» (см. изображение выше). При этом на любые сообщения бот должен реагировать выводом полей объекта msg в консоль.

Для остановки работы бота и выхода из приложения просто нажмите сочетание клавиш «Ctrl + C», когда окно терминала будет в фокусе.

На этом всё, теперь можно переходить к созданию более сложного дайджест-бота.

<< Перейти к содержанию

Для реализации функциональсти, описаной в самом начале статьи, было придумано следующее: имеется глобальный лист, образно именуемый стеком, куда будут записаны сообщения с тегом #digest. Глобальный он потому, что при каждом вызове функции bot.on(‘text’, …) в него происходит (или не происходит) добавление соответствующего сообщения или его модификация. Тут вся сложность в том, что бота можно добавить в несколько чатов сразу и в каждом он должен корректно отработать, собирая все сообщения из чатов с вышеупомянутым тегом и корректно (то есть каждому чату именно ему принадлежащие сообщения) выводить соответствующую информацию. В начале планировалось создавать индивидуальные листы, содержащие сообщения для каждого чата индивидуально, но позже пришла мысль использовать лишь один лист, добавляя в него кроме, непосредственно, сообщения ещё и различную дополнительную информацию вроде id чата и даты, благо node-telegram-bot-api позволяет это сделать. Да и возни будет меньше, так как ответ станет формироваться на выходе, где в вывод будут добавлены лишь те сообщения, которые соответствуют id того чата, из которого пришла команда /digest.


Простая схема работы дайджест-бота с листом.

Далее, нужно помнить, что наш стек может неплохо так раздуться, если в него постоянно будут добавлять сообщения из разных чатов. Поэтому необходимо придумать механизм, который будет периодически очищать стек, удаляя неактуальные сообщения. Пусть этот механизм будет работать следующим образом: пользователь, который ввёл команду /digest последним, реформирует стек, удаляя из него устаревшую информацию. Механизм удаления пусть будет следующий: у последней команды /digest берётся время и из этого времени вычитается какая-то фиксированная величина-задержка в секундах, к примеру сутки или неделя, после чего с помощью цикла перебираются все сообщения в стеке и используя сравнение по времени, вычисляется граница (в конкретном случае количество устаревших сообщений «снизу», или порядковый номер граничного сообщения), которая разделяет стек на две части из устаревших и актуальных сообщений. Далее лист режется прямиком по этой границе на две половинки, часть с устаревшими сообщениями выкидывается вместе с ними, а часть с актуальными сообщениями становится новым стеком. Но тут, конечно, нужно помнить, что имеется целых три различных варианта развития событий:

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

Ситуация, когда пользователи постоянно пишут сообщения с тегом #digest, но не вызывают команду /digest маловероятна, поэтому опустим этот случай. При желании, конечно, можно перенести механизм (в конкретном случае одну функцию) и в обработчик, который срабатывает при получении #digest-тега, но таким образом реформация стека будет происходить уж больно часто. В описаной выше функциальности любой пользователь любого чата неявно реформирует стек при каждом вызове команды /digest, удаляя все устаревшие сообщения всех чатов, за которыми следит бот.


Программа-симулятор логики работы со стеком, описанной выше.

После того, как эта функциональность была обдумана в голове, мне захотелось проверить её в боевых действиях. Но, увы, меня подвёло моё плохое интернет-соединение. Поэтому вечером, будучи в «offline», мой воспалённый идеей мозг, накидал простенький симулятор логики на C++ и Qt (см. изображение выше). Два окна с текстом в них — имитируют два активных чата, в которые добавлен бот, реагирующий на команду /digest и тег #digest. Кнопки «Start/Stop Discussion» запускают симуляцию активной беседы в необходимом чате (простой генератор случайных чисел), иногда среди обычных сообщений попадаются имеющие тег #digest, которые старательно складываются ботом в структуру, записываемую в контейнер QList. При этом я могу симулировать поведение пользователя, вводя в текстовые поля сообщения или команду /digest, реформируя QList и получая ответ бота. Исходные тексты этой программки можно найти здесь. Утром, после того как моё интернет-соединение пришло в норму, я просто начал портировать уже готовое решение на JavaScript.

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

<< Перейти к содержанию

5.1. Обработчик тега #digest

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

bot.on(‘text’, function(msg)

{

    ...

    if (messageText.indexOf(‘#digest’) >= 0) {

        var normalMessage = normalizeMessage(messageText);

        if (!(isBlank(normalMessage))) {

            var messageInfoStruct = {

                ‘s_chatID’: messageChatId,

                ‘s_date’: messageDate,

                ‘s_message’: normalMessage,

                ‘s_username’: globalUserNameIs

            };

            globalStackListDigestMessages.push(messageInfoStruct);

            // Send message by bot.

            sendMessageByBot(messageChatId, ‘Added!’);

        }

    }

    ...

}

Тут всё просто. Если сообщение содержит тег #digest, то начинает выполнятся тело условия. В переменную normalMessage помещается нормализированное сообщение, которое возвращает функция normalizeMessage(); она модифицирует полученное сообщение, например, удаляет из него тег, «разряжает» пробелы, меняет регистр первой буквы на заглавную и проводит ещё несколько различных манипуляций. Если сообщение после нормализации вернётся не пустым (например, сообщение, состоящее из одного тега #digest, после нормализации будет пустым), то создаётся простенькая структурка, в которую добавляется вся необходимая информация, после чего структурка закидывается в стек-лист. Затем отправляется сообщение в чат об успешном добавлении информации в стек.

<< Перейти к содержанию

5.2. Обработчик команды /digest

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

bot.on(‘text’, function(msg)

{

    ...

    if (messageText === ‘/digest’) {

        // Digest delay.

        // 45 sec for debug.

        // 43 200 for 12-hours.

        // 86 400 for 24-hours.

        // 172 800 for 48-hours.

        var hourDelay = 86400;

        var bSendDigest = false;

        if (globalStackListDigestMessages.length > 0) {

            // Delete all obsolete digest messages from globalStackListDigestMessages

            bSendDigest = deleteObsoleteDigestMessages(messageDate hourDelay);

        }

        // Generate Bot Answer

        if (bSendDigest) {

            ...

        } else {

            sendNoDigestMessages(messageChatId);

        }

    }

    ...

}

Формально обработчик можно разделить на две части, собственно, работу по актуализации стека и генерацию ответа на команду. Последнее мы рассмотрим немного позже. Как уже было сказано выше, здесь вводится задержка, в конкретном случае суточная, результат вычитания которой из даты принятого сообщения отправляется в функцию deleteObsoleteDigestMessages(), от возвращаемого значения которой зависит будет ли сгенерирован ответ, или же будет выполнена функция sendNoDigestMessages(), отправляющая в чат информацию об отсутствии актуальных сообщений на данный момент.

<< Перейти к содержанию

5.3. Функция deleteObsoleteDigestMessages()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

function deleteObsoleteDigestMessages(aObsoleteDate)

{

    var stackSize = globalStackListDigestMessages.length;

    var position = 0;

    for (var i = 0; i < stackSize; ++i) {

        if (globalStackListDigestMessages[i].s_date < aObsoleteDate) {

            position++;

        }

    }

    // All stack digest messages are obsolete.

    // Drop stack.

    if (position == stackSize) {

        globalStackListDigestMessages = [ ];

        return false;

    }

    // All stack digest messages are relevant.

    // Print them.

    if (position == 0) {

        return true;

    }

    // Replace current digest stack by sliced.

    globalStackListDigestMessages = globalStackListDigestMessages.slice(position);

    // Return true if stack not empty

    return stackSize > 0;

}

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

<< Перейти к содержанию

5.4. Генерация ответа бота на команду /digest

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

if (bSendDigest) {

    var botAnswer = »;

    var endLineString = ‘;n’;

    var stackSize = globalStackListDigestMessages.length;

    // Count of digest messages from one chat.

    var countOfDigestMessagesByChat = getCountDigestMessagesOfChat(messageChatId);

    // Append answer string.

    for (var i = 0; i < stackSize; ++i) {

        if (globalStackListDigestMessages[i].s_chatID === messageChatId) {

            botAnswer += catchPhrases.digestMarker + globalStackListDigestMessages[i].s_message + endLineString;

        }

    }

    // Delete last new line and semicolon characters (;n).

    botAnswer = botAnswer.substring(0, botAnswer.length 2);

    // Add dot to end of line.

    if (botAnswer.substr(botAnswer.length 1) !== ‘.’) {

        botAnswer += ‘.’;

    }

    // Check countOfDigestMessagesByChat.

    if (countOfDigestMessagesByChat > 0) {

        // Send botAnswer to chat with catchPhrases chunks.

        sendMessageByBot(messageChatId, getDigestReportHeader() + botAnswer);

    } else {

        sendNoDigestMessages(messageChatId);

    }

}

Генерация ответа очень проста: в строку botAnswer в цикле добавляются все подходящие сообщения из стека, вместе с форматированием. Функция getCountDigestMessagesOfChat() возвращает в переменную countOfDigestMessagesByChat количество сообщений с тегом для чата из которого была получена команда. Условие внутри цикла регламентирует добавление в botAnswer лишь тех сообщений, id которых совпадает с id чата, из которого была получена команда /digest. Потом в конец botAnswer добавляется точка, если это нужно и botAnswer отправляется в чат, если переменная countOfDigestMessagesByChat больше нуля.

<< Перейти к содержанию

5.5. Заключение по дайджест-боту

Эти функции помогут понять устройство бота и подскажут, как реализовать его самостоятельно. Мою реализацию и полный исходный код вы можете посмотреть по этой ссылке. Там же найдёте и простую инструкцию по установке и разворачиванию. Бот Гаечка, описанный в первом пункте этой статьи, является усложнённой имплементацией дайджест-бота.

Update 06-MAR-2017: Прочитать ещё немного информации по поводу дайджест-бота Gadget Hackwrench можно в разделе этой статьи.

Далее перейдём к описанию простого валютного бота.

<< Перейти к содержанию

6. Реализация валютного бота на JavaScript

Смысл валютного бота состоит в том, чтобы брать актуальные валютные котировки с сайта ЦБ РФ и отправлять их в чат. Создадим файл «Currency.js» в директории ~/Deploy/ и заполним его следующим содержимым:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

var TelegramBot = require(‘node-telegram-bot-api’);

var http = require(‘http’);

var token = ‘WRITE_YOUR_TOKEN_HERE’;

var botOptions = {

    polling: true

};

var bot = new TelegramBot(token, botOptions);

var options = {

    host: «www.cbr.ru»,

    port: 80,

    path: «/scripts/XML_daily.asp?»

};

var content = «»;

bot.getMe().then(function(me)

{

    console.log(‘Hello! My name is %s!’, me.first_name);

    console.log(‘My id is %s.’, me.id);

    console.log(‘And my username is @%s.’, me.username);

});

bot.on(‘text’, function(msg)

{

    var messageChatId = msg.chat.id;

    var messageText = msg.text;

    var messageDate = msg.date;

    var messageUser = msg.from.username;

    if (messageText.indexOf(‘/currency’) === 0) {

        updateGlobalCurrencyList(messageChatId);

    }

});

function sendMessageByBot(aChatId, aMessage)

{

    bot.sendMessage(aChatId, aMessage, { caption: ‘I’m a cute bot!’ });

}

function updateGlobalCurrencyList(aMessageChatId)

{

    var req = http.request(options, function(res) {

        res.setEncoding(«utf8»);

        res.on(«data», function(chunk) {

            content += chunk;

        });

        res.on(«end», function() {

            sendMessageByBot(aMessageChatId, shittyParseXML(content));

        });

    });

    req.end();

}

function generateBotAnswer(aCurrencyList)

{

    var currencyTable = ‘CURRENCY:n’;

    currencyTable += ‘1 USD = ‘ + aCurrencyList.USD + ‘ ‘ + ‘RUB’ + ‘;n’;

    currencyTable += ‘1 EUR = ‘ + aCurrencyList.EUR + ‘ ‘ + ‘RUB’ + ‘;n’;

    currencyTable += ‘1 UAH = ‘ + aCurrencyList.UAH + ‘ ‘ + ‘RUB’ + ‘;n’;

    currencyTable += ‘1 KZT = ‘ + aCurrencyList.KZT + ‘ ‘ + ‘RUB’ + ‘;n’;

    currencyTable += ‘1 BYR = ‘ + aCurrencyList.BYR + ‘ ‘ + ‘RUB’ + ‘;n’;

    currencyTable += ‘1 GBP = ‘ + aCurrencyList.GBP + ‘ ‘ + ‘RUB’ + ‘.’;

    return currencyTable;

}

function shittyParseXML(aAllXml)

{

    var currencyList = {

        ‘USD’: 0.0,

        ‘EUR’: 0.0,

        ‘UAH’: 0.0,

        ‘KZT’: 0.0,

        ‘BYR’: 0.0,

        ‘GBP’: 0.0

    };

    currencyList.USD = getCurrentValue(‘USD’, aAllXml);

    currencyList.EUR = getCurrentValue(‘EUR’, aAllXml);

    currencyList.UAH = getCurrentValue(‘UAH’, aAllXml);

    currencyList.KZT = getCurrentValue(‘KZT’, aAllXml);

    currencyList.BYR = getCurrentValue(‘BYR’, aAllXml);

    currencyList.GBP = getCurrentValue(‘GBP’, aAllXml);

    return generateBotAnswer(currencyList);

}

function getCurrentValue(aCurrency, aString)

{

    var nominal = parseFloat(replaceCommasByDots(getStringBelow(aString.indexOf(aCurrency), 1, aString)));

    var value = parseFloat(replaceCommasByDots(getStringBelow(aString.indexOf(aCurrency), 3, aString)));

    return (value / nominal).toFixed(4);

}

function removeTags(aString)

{

    return aString.replace(/(<([^>]+)>)/ig, »);

}

function getStringBelow(aStart, aBelow, aString)

{

    var textSize = aString.length;

    var countOfLineEndings = 0;

    var getLineWith = 0;

    for (var i = aStart; i < textSize; ++i) {

        if (countOfLineEndings === aBelow) {

            getLineWith = i;

            break;

        }

        if (aString[i] === ‘n’) {

           countOfLineEndings++;

        }

    }

    return getLineFromXml(getLineWith, aString);

}

function replaceCommasByDots(aString)

{

    return aString.replace(‘,’, ‘.’);

}

function getLineFromXml(aStart, aString)

{

    var textSize = aString.length;

    var targetString = »;

    for (var i = aStart; i < textSize; ++i) {

        if (aString[i] === ‘n’) {

            break;

        }

        targetString += aString[i];

    }

    return removeTags(targetString.trim());

}

Конечно же не забываем вместо WRITE_YOUR_TOKEN_HERE вписать свой токен. Далее сохраним файл и пройдёмся по коду с комментариями.


Демонстрация работы валютного бота, ответ на команду /currency.

Во-первых, нам нужно подключить пакет http, поскольку потребуется получить XML-файл с котировками, расположенный на сервере ЦБ РФ по адресу http://www.cbr.ru/scripts/XML_daily.asp?. Опции доступа к этому хосту описаны в переменной options. В глобальную переменную content мы будем сохранять ответ сервера, содержащий XML. Далее по коду отлично видно, что бот мониторит все сообщения и в том случае, если кто-то отправит команду /currency, начнёт выполняться функция updateGlobalCurrencyList(). В ней создаётся асинхронный HTTP-запрос, в результате выполнения которого в переменную content загрузятся XML-данные. По окончанию запроса необходимо распарсить XML, и отправить его в чат, что и происходит в функции res.on(«end», …). К сожалению, в языке программирования JavaScript и фреймворке Node.js отсутствуют стандартные средства для работы с XML. Поэтому для парсинга я решил не тянуть лишнюю зависимость в Node.js, а попытаться найти закономерности в файле и распарсить его костылём. Предупреждаю сразу, что лучше всего всё сделать по уму и воспользоваться библиотекой. Функция shittyParseXML() принимает в качестве единственного аргумента сырые XML-данные и работает следующим образом: нам требуется в XML найти какие-нибудь уникальные значения, чтобы привязаться к ним и работать от них. Такие данные действительно есть, это поле «CharCode», которое характеризует уникальный идентификатор валюты. Если от строки, содержащей идентификатор отступить вниз на одну, мы получим валютный номинал, а если отступить на три, то получим значение. Разделив значение на валютный номинал, мы получим другое значение, которое будет соответствовать эквиваленту одной какой-нибудь валюты. Пройдя по цепочке вызовов из shittyParseXML() обозначим наиболее интересные функции и их описание:

  • getStringBelow(i, j, data_string) — собственно, спуститься от строки «i» вниз на «j» в буфере «data_string»;
  • getLineFromXml(i, data_string) — возвращает строку под номером «i» в буфере «data_string»;
  • removeTags(string) — принимает строку «string» с тегами и возвращает строку без тегов;
  • replaceCommasByDots(string) — функция заменяет в строке «string» запятые на точки, что очень важно для глобальной функции parseFloat().

Интересный факт: этот велосипедный парсер отлично справился с XML-кой, содержащей котировки похожего формата, полученной с одного украинского финансового сайта. Но это скорее всего счастливая случайность и совпадение, чем ожидаемое поведение.

Теперь можно запустить валютного бота на исполнение. Для запуска, находясь в директории ~/Deploy/, набираем команду:

nodejs Currency

Если завести диалог с ботом и послать ему команду /currency, то в ответ он должен отправить в чат курс валют сегодняшнего дня по ЦБ РФ (см. изображение выше). Выключить бота можно сочетанием клавиш «Ctrl + C» в окне терминала.

Далее следует реализация ещё одного простенького дайджест-бота на языке программирования Python. Если вам это нисколько не интересно, можете полностью пропустить следующий раздел.

<< Перейти к содержанию

7. Реализация упрощённого дайджест-бота на Python

Один из участников конференции MotoFan.Ru, скрывающийся под ником @J()KER, попросил меня разобраться с twx.botapi и накидать реализацию какого-нибудь бота на языке программирования Python; twx.botapi — одна из двух популярных реализаций Telegram Bot API, которая максимально использует ООП (объектно-ориентированное программирование), но, к сожалению, имеет весьма скудную документацию. Вторая реализация называется pyTelegramBotAPI, она несколько проще для понимания и её документация снабжена примерами, хорошо демонстрирующими ту или иную фичу реализации. К сожалению, о pyTelegramBotAPI я узнал уже после того, как написал бота на twx.botapi. Но выбор подходящей реализации Telegram Bot API, это скорее всего дело обычного вкуса; кому-то twx.botapi может понравится больше, следовательно наш бот будет использовать именно его.

Я не в первый раз сталкиваюсь с языком программирования Python, раньше я работал с ним вкупе с технологией PyQt. Это очень приятный и выразительный язык, хотя меня немного напрягает неявная типизация совмещённая со строгой и зависимость от отступов. Мои знания Python весьма поверхностны, однако SODD (Stack Overflow Driven Development) и всеобъемлющая документация помогают очень быстро разобраться и сделать работающий прототип буквально за 20-30 минут. Просто портируем основную логику JavaScript дайджест-бота, написанного ранее, на язык программирования Python. Естественно, будет использоваться Polling-режим.

Реализация twx.botapi позволяет использовать как Python второй версии, так и третьей. Мы для написания бота будем использовать Python 3, для запуска которого требуется немного настроить окружение (далее предполагается что вы работаете в deb-based дистрибутиве). В начале устанавливаем собственно сам Python 3 и его пакетный менеджер:

sudo aptget install python3 python3pip

Затем с помощью Python’овского пакетного менеджера устанавливаем пакет twx.botapi:

pip3 install twx.botapi

Теперь можно зайти в любую удобную директорию, например, в ~/Deploy/ и создать в ней текстовой файл с именем «DigestBot.py», в который вставить и сохранить следующий код:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

#!/usr/bin/python

# -*- coding: utf-8 -*-

from __future__ import unicode_literals

from twx.botapi import TelegramBot

import traceback

class DigestBot(object):

    token = ‘WRITE_YOUR_TOKEN_HERE’

    stack_list = []

    admin = ‘exlmoto’

    def __init__(self):

        self.bot = TelegramBot(self.token)

        self.bot.get_me()

        last_updates = self.bot.get_updates(offset=0).wait()

        try:

            self.last_update_id = list(last_updates)[1].update_id

        except IndexError:

            self.last_update_id = None

        print(‘last update id: {0}’.format(self.last_update_id))

    def process_message(self, message):

        text = message.message.text

        chat = message.message.chat

        text = text.strip()

        digest_tag = ‘#digest’

        print(‘Got message: 33[0;32m{0}33[0m from chat: {1}’.format(text, chat))

        try:

            if text == ‘/digest’:

                bot_answer = ‘There is your digest:n’

                try:

                    for struct in self.stack_list:

                        if struct[‘chat_id’] == chat.id:

                            bot_answer += struct[‘chat_message’]

                            bot_answer += ‘n’

                    bot_answer = bot_answer[:1]

                    bot_answer += ‘.’

                    self.bot.send_message(chat.id, bot_answer)

                except Exception:

                    self.bot.send_message(chat.id, ‘Unknow error. Sorry.’)

            if text == ‘/stackView’:

                list_answer = ‘There is my stack list:n’

                try:

                    if message.message.sender.username == self.admin:

                        for (index, d) in enumerate(self.stack_list):

                            list_answer += str(index + 1)

                            list_answer += ‘ ‘ + str(d[‘chat_id’])

                            list_answer +=‘ ‘ + d[‘chat_message’]

                            list_answer += ‘n’

                        list_answer = list_answer[:1]

                        self.bot.send_message(chat.id, list_answer)

                    else:

                        raise Exception(‘You do not access for this function.’)

                except Exception as ex_acc:

                    answer = ex_acc.args

                    self.bot.send_message(chat.id, answer)

            if digest_tag in text:

                try:

                    text = text.replace(digest_tag, »)

                    text = text.strip()

                    struct = { ‘chat_id’: chat.id, ‘chat_message’: text }

                    self.stack_list.append(struct.copy())

                    self.bot.send_message(chat.id, ‘Done. I append your digest-message in my stack list.’)

                except Exception:

                    self.bot.send_message(chat.id, ‘There is error. Sorry.’)

        except Exception:

            pass

    def run(self):

        print(‘Main loop started’)

        while True:

            updates = self.bot.get_updates(offset=self.last_update_id).wait()

            try:

                for update in updates:

                    if int(update.update_id) > int(self.last_update_id):

                        self.last_update_id = update.update_id

                        self.process_message(update)

            except Exception as ex:

                print(traceback.format_exc())

if __name__ == ‘__main__’:

    try:

        DigestBot().run()

    except KeyboardInterrupt:

        print(‘Exiting…’)

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

Строка from __future__ import unicode_literals говорит о том, что в нашей программе будет использоваться Unicode; это действительно так: сообщения из чата могут приходить на различных языках. Далее идёт подключение пакета twx.botapi и если скрипт запущен как независимая программа (выражение if __name__ == ‘__main__’), начинается построение класса DigestBot с полями token, admin и листом stack_list. Первый метод, который проинициализирует должным образом переменные, называется __init__(self), он является неким аналогом конструктора, но называть его конструктором несколько неправильно, так как к моменту вызова этого метода объект уже будет создан и вы будете иметь ссылку на созданный экземпляр класса. В этом методе в API отправляется ваш токен, вызывается метод get_me(), тестирующий авторизационный токен вашего бота и с помощью метода get_updates() в переменную last_updates возвращается массив объектов обновления. Если этот массив не пустой, то в поле класса last_update_id устанавливается update_id последнего элемента массива last_updates.

Далее у экземпляра класса вызывается метод run(), в котором реализован главный бесконечный цикл, в теле которого: в переменную updates возвращается массив объектов обновления начиная со значения переменной last_update_id определённой в __init__(self), затем во вложенном цикле выполняется проверка значений различных update_id, и если update_id прилетевшего события больше, чем тот, что был сохранён в поле класса, то поле класса будет обновлено, а сообщение обработано методом process_message(self, message). В теле которого в различные переменные выдирается сообщение и происходят стандартные преобразования, описанные выше в разделе про создание дайджест-бота на JavaScript: при получении тега #digest в лист добавляется структура с информацией о сообщении; при получении команды /digest идёт процесс формирования ответа. В этой версии дайджест-бота стек-лист никем не модифицируется, но при желании, конечно, можно реализовать аналог того, что было написано на JavaScript; просто я решил не раздувать листинги исходного кода. Дату сообщения, судя по документации twx.botapi, можно выдрать с помощью message.message.date в аналогичном UNIX-формате. Ещё стоит упомянуть обработку команды /stackView, которая отображает всё содержимое листа с данными изо всех чатов. Поэтому этой командой может воспользоваться только администратор, ник которого прописан в поле класса admin.

Для запуска дайджест-бота в консоли следует перейти в директорию с файлом «DigestBot.py» и набрать следующую команду в терминале:

python3 DigestBot.py

Завершить процесс можно сочетанием клавиш «Ctrl + C» в окне терминала.

Далее будет описано создание бота на JavaScript, который отправляет случайную цитату в чат с bash.im, главного цитатника Рунета.

<< Перейти к содержанию

8. Реализация бота, отправляющего случайную цитату с bash.im, на JavaScript

Пользователи конференций часто хотят развлечься и прочитать случайную цитату из главного цитатника Рунета, сайта bash.im. Давайте реализуем такой функционал у бота. Сперва в директории ~/Deploy/ создадим файл с именем «Bash.js» и вставим в него следующее содержимое:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

var TelegramBot = require(‘node-telegram-bot-api’);

var http = require(‘http’);

var iconv = require(‘iconv-lite’);

var token = ‘WRITE_YOUR_TOKEN_HERE’;

var botOptions = {

    polling: true

};

var bot = new TelegramBot(token, botOptions);

var options = {

    host: «bash.im»,

    port: 80,

    path: «/forweb/»

};

bot.getMe().then(function(me)

{

    console.log(‘Hello! My name is %s!’, me.first_name);

    console.log(‘My id is %s.’, me.id);

    console.log(‘And my username is @%s.’, me.username);

});

bot.on(‘text’, function(msg)

{

    var messageChatId = msg.chat.id;

    var messageText = msg.text;

    var messageDate = msg.date;

    var messageUser = msg.from.username;

    if (messageText.indexOf(‘/bash’) === 0) {

        sendRandomBashImQuote(messageChatId);

    }

});

function sendRandomBashImQuote(aMessageChatId)

{

    http.get(options, function(res) {

        res.pipe(iconv.decodeStream(‘win1251’)).collect(function(err, decodedBody) {

            var content = getQuoteBlockFromContent(decodedBody);

            content = removeAllMarkUp(content[1]);

            sendMessageByBot(aMessageChatId, content);

        });

    });

}

function removeAllMarkUp(aString)

{

    var cleanQuote = replaceAll(aString, «<‘ + ‘br>», ‘n’);

    cleanQuote = replaceAll(cleanQuote, «<‘ + ‘br />», ‘n’);

    cleanQuote = replaceAll(cleanQuote, ‘»‘, ‘»‘);

    cleanQuote = replaceAll(cleanQuote, ‘<‘, ‘<‘);

    cleanQuote = replaceAll(cleanQuote, ‘>’, ‘>’);

    return cleanQuote;

}

function replaceAll(aString, aFingString, aReplaceString)

{

    return aString.split(aFingString).join(aReplaceString);

}

function getQuoteBlockFromContent(aString)

{

    var quoteBlock = aString.replace(‘<‘ + ‘div id=»b_q_t» style=»padding: 1em 0;»>’, ‘__the_separator__’);

    quoteBlock = quoteBlock.replace(‘<‘ + ‘/div><‘ + ‘small>’, ‘__the_separator__’);

    return quoteBlock.split(‘__the_separator__’);

}

function sendMessageByBot(aChatId, aMessage)

{

    bot.sendMessage(aChatId, aMessage, { caption: ‘I’m a cute bot!’ });

}

Естественно, WRITE_YOUR_TOKEN_HERE заменяем своим токеном. Сохраним файл и немного рассмотрим его.


Демонстрация бота, отправляющего случайную цитату с bash.im

Случайную цитату можно получить по ссылке bash.im/forweb/. К сожалению, необходимая информация выдаётся в кодировке Windows-1251, поэтому нам нужно преобразовать ответ сервера в UTF-8. Для работы с кодировками существует несколько пакетов, например, node-iconv, но нам подойдёт самый компактный из них — iconv-lite. Устанавливаем его в директорию ~/Deploy/ с помощью пакетного менеджера Node.js:

npm install iconvlite

В листинге кода выше, этот пакет подключается третьей строкой. Далее всё достаточно стандартно: при отправке команды /bash в чат, бот вызывает у себя функцию sendRandomBashImQuote(), в которой создаёт запрос и конвертирует полученную информацию в UTF-8 (см. документацию для более подробного изучения работы этой функции). Далее из результата ответа сервера, хранящегося в переменной decodedBody уже в правильной кодировке, вычленяется блок, отвечающий за саму цитату с помощью функции getQuoteBlockFromContent(). Эта функция возвращает массив, который сохраняется в переменную content, второй элемент которого (по индексу [1]) отправляется в функцию removeAllMarkUp, отвечающую за удаление всей HTML-разметки. Результат выполнения функции снова записывается в content и после отправляется в чат.

Для запуска бота, находясь в директории ~/Deploy/, следует выполнить команду:

nodejs Bash

Теперь, если завести диалог с ботом и написать команду /bash в чат, то в ответ он должен отправить случайную цитату с вышеупомянутого сайта (см. изображение выше). Если часто отсылать команду /bash, то можно заметить, что цитата не изменилась. За выдачу рандомной цитаты отвечает сервер bash.im, поэтому вряд ли что-то здесь можно сделать. Разве что прикрутить задержку. Выключить бота можно нажав сочетание клавиш «Ctrl + C» в окне терминала.

В следующем разделе статьи будут описаны примеры исходного кода JavaScript-ботов, работающих с такими объектами, как изображения, видео, аудио, стикеры и интерактивные кнопки.

<< Перейти к содержанию

9. Реализация JavaScript-ботов, работающих со стикерами, мультимедийными объектами и интерактивными кнопками

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

<< Перейти к содержанию

9.1. Бот, отправляющий в ответ на стикер свой стикер.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

// StickerBot.js

var TelegramBot = require(‘node-telegram-bot-api’);

var token = ‘WRITE_YOUR_TOKEN_HERE’;

var botOptions = {

    polling: true

};

var bot = new TelegramBot(token, botOptions);

var stickersList = [

    ‘BQADAgADfgADEag0Bb5mxH0gvtktAg’,

    ‘BQADAgADowADEag0BQs_xQSkcIFKAg’,

    ‘BQADAgAD1wADEag0BTEYGb09JERjAg’,

    ‘BQADAgAD5wADEag0BZAwDWvpwGrtAg’,

    ‘BQADAgADxQADEag0BRBpCE1JOT4sAg’,

    ‘BQADAgADwwADEag0BbGlUZ12nxZ8Ag’,

    ‘BQADAgADvwADEag0Bf5nBjEjQyUYAg’,

    ‘BQADAgADyQADEag0BYauZXVnHFqOAg’

];

bot.getMe().then(function(me)

{

    console.log(‘Hello! My name is %s!’, me.first_name);

    console.log(‘My id is %s.’, me.id);

    console.log(‘And my username is @%s.’, me.username);

});

bot.on(‘sticker’, function(msg)

{

    var messageChatId = msg.chat.id;

    var messageStickerId = msg.sticker.file_id;

    var messageDate = msg.date;

    var messageUsr = msg.from.username;

    sendStickerByBot(messageChatId, stickersList[getRandomInt(0, stickersList.length)]);

    console.log(msg);

});

function getRandomInt(aMin, aMax)

{

    return Math.floor(Math.random() * (aMax aMin + 1)) + aMin;

}

function sendStickerByBot(aChatId, aStickerId)

{

    bot.sendSticker(aChatId, aStickerId, { caption: ‘I’m a cute bot!’ });

}

У каждого стикера, загруженного на серверы Telegram, существует его уникальный идентификатор file_id, который можно увидеть, выведя объект msg в консоль. Отправляя этот идентификатор в качестве одного из аргументов функции bot.sendSticker(), мы по сути отправляем этот стикер в чат с помощью бота. Логика программы простая: в ответ на любой стикер, полученный из чата, бот отправит в ответ случайный стикер из листа stickersList, где перечислены их уникальные идентификаторы. Заметьте, что аргументом API-метода может быть и подходящий под понятие стикера файл (например, формата webp с разрешением 512×512).

<< Перейти к содержанию

9.2. Бот, отправляющий в ответ на команду мультимедийный объект в чат.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

// MultimediaBot.js

var TelegramBot = require(‘node-telegram-bot-api’);

var request = require(‘request’);

var token = ‘WRITE_YOUR_TOKEN_HERE’;

var botOptions = {

    polling: true

};

var bot = new TelegramBot(token, botOptions);

bot.getMe().then(function(me)

{

    console.log(‘Hello! My name is %s!’, me.first_name);

    console.log(‘My id is %s.’, me.id);

    console.log(‘And my username is @%s.’, me.username);

});

bot.on(‘text’, function(msg)

{

    var messageChatId = msg.chat.id;

    var messageText = msg.text;

    if (messageText === ‘/photo’) {

        var photo = request(‘http://www.google.com/images/srpr/logo3w.png’);

        bot.sendPhoto(messageChatId, photo, { caption: ‘Image:’ });

    }

    if (messageText === ‘/audio’) {

        var audio = __dirname + ‘/audio.ogg’;

        bot.sendAudio(messageChatId, audio, { caption: ‘Audio:’ });

    }

    if (messageText === ‘/file’) {

        var url2 = ‘http://exlmoto.ru/wp-content/Packages/stransball2.mgx’;

        var file = request(url2);

        bot.sendDocument(messageChatId, file, { caption: ‘Document:’ });

    }

});

Telegram Bot API позволяет отправлять как локальные мультимедийные объекты и файлы, так и удалённые. Для того, чтобы иметь возможность отправлять удалённые объекты, полученные по URL, требуется подключить пакет request, о котором и говорилось в начале статьи. Список всех доступных send-методов можно посмотреть здесь. Помимо этого можно скачать файл в любую удобную директорию, например, рядом с js-файлом и потом уже отправить его оттуда, как это реализовано здесь.

<< Перейти к содержанию

9.3. Бот, работающий с интерактивными кнопками.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

// KeysBot.js

var TelegramBot = require(‘node-telegram-bot-api’);

var token = ‘WRITE_YOUR_TOKEN_HERE’;

var botOptions = {

    polling: true

};

var bot = new TelegramBot(token, botOptions);

bot.getMe().then(function(me)

{

    console.log(‘Hello! My name is %s!’, me.first_name);

    console.log(‘My id is %s.’, me.id);

    console.log(‘And my username is @%s.’, me.username);

});

bot.on(‘text’, function(msg)

{

    var messageChatId = msg.chat.id;

    var messageText = msg.text;

    if (messageText === ‘/keys’) {

        var opts = {

            reply_to_message_id: msg.message_id,

            reply_markup: JSON.stringify({

                keyboard: [

                    [‘Yes’],

                    [‘No’]

                ]

            })

        };

        bot.sendMessage(messageChatId, ‘Do you love me?’, opts);

    }

    if (messageText === ‘Yes’) {

        bot.sendMessage(messageChatId, ‘I’m too love you!’, { caption: ‘I’m bot!’ });

    }

    if (messageText === ‘No’) {

        bot.sendMessage(messageChatId, ‘:(‘, { caption: ‘I’m bot!’ });

    }

});

Бот в ответ на команду /keys отправляет специальное сообщение-ответ с особым параметром-клавиатурой. Пользователь может нажать на какую-нибудь из интерактивных кнопок, тем самым отправляя текст этой кнопки в чат, после чего бот снова обработает сообщение и в зависимости от варианта ответа произведёт какие-либо действия. Подобный режим весьма полезен для ботов, которые работают не с групповыми чатами, а с отдельными пользователями в индивидуальных диалогах. Выскакивающая клавиатура может раздражать пользователей в конференциях, поэтому используйте эту функциональность осторожно.


Демонстрация работы валютного бота @RubBot, использующего интерактивные кнопки.

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

<< Перейти к содержанию

10. Заключение, полезные ссылки и ресурсы

В этой статье были описаны варианты создания различных ботов на языках программирования JavaScript и Python. Я буду рад, если материал поможет вам разобраться во всех тонкостях работы с Telegram Bot API и поспособствует реализации ваших идей. Как было сказано в самом начале статьи, с помощью ботов можно организовать удобное получение и обработку различной информации. Для тех, кто заинтересовался этой темой, я предлагаю воспользоваться полезными ссылками, опубликованными ниже. Небольшой совет: обязательно читайте документацию реализации Telegram Bot API, используемой вами, и множество вопросов отпадут сами собой. Хочу выразить огромную благодарность создателю Telegram-конференции сообщества MotoFan.Ru — @ZorgeR‘у, который помог мне в имплементации различных аспектов дайджест-бота Гаечки и не раз наставлял меня на правильный и верный путь.

  1. Репозиторий с исходным кодом дайджест-бота на JavaScript и инструкцией по его установке;
  2. Исходный код простого дайджест-бота на Python;
  3. Официальная документация Telegram Bot API;
  4. Документация и официальный репозиторий реализации Telegram Bot API на языке JavaScript под Node.js — node-telegram-bot-api;
  5. Документация реализации Telegram Bot API на языке Python — twx.botapi;
  6. Официальный репозиторий реализации Telegram Bot API на языке Python — twx.botapi;
  7. Документация и официальный репозиторий реализации Telegram Bot API на языке Python — pyTelegramBotAPI;
  8. Отличная статья про реализацию JavaScript-ботов на Node.js и node-telegram-bot-api от Catethysis.

Update 18-MAR-2016: Официальное Telegram Bot API теперь предоставляет возможность использования специальных inline-ботов, которые могут искать различную информацию в Интернете и позволять пользователю выбирать подходящие варианты. Простой пример такого бота можно посмотреть здесь (исходный код), у него должен быть особый атрибут inline-бота, установить который можно с помощью команды /setinline, которую следует отправить @BotFather боту.

<< Перейти к содержанию

Понравилась статья? Поделить с друзьями:
  • Как написать чат бот на нейросети
  • Как написать часы на питоне
  • Как написать часы на python
  • Как написать часы на java
  • Как написать частушку про школу