Skip to content

Instantly share code, notes, and snippets.

@glukki
Last active January 13, 2023 14:25
Show Gist options
  • Save glukki/50ddfd6a99ee3fd634b1 to your computer and use it in GitHub Desktop.
Save glukki/50ddfd6a99ee3fd634b1 to your computer and use it in GitHub Desktop.
Telegram Bots @ Node.js

Telegram

Оглавление:

Как работают боты

  • код бота исполняется на вашем сервере
  • бот общается с сервером Telegram по http + json
  • первое сообщение должен отправить пользователь
  • бота можно пригласить в группу

Как завести бота

  • написать боту @BotFather сообщение /newbot
  • задать отображаемое имя нового бота
  • задать логин бота (должен оканчиваться на bot, регистр не важен)
  • сохранить полученный токен

Как начать получать сообщения ботом

  • адрес всех методов https://api.telegram.org/bot<token>/METHOD_NAME
  • передавать параметры в url или json (application/json)
  • ответ в json

/getMe

Вернет боту информацию о самом себе

{
    "ok": true,
    "result": {
        "id": 1234567890,
        "first_name": "Example Bot",
        "username": "example_bot"
    }
}

/getUpdates?offset=K&limit=N&timeout=T

Вернет боту список непрочитанных событий

  • начиная с события K (сервер станет считать, что события менее K прочитаны),
  • в количестве максимум N элементов,
  • с long polling таймаутом T.
{
    "ok": true,
    "result": [
        {
            "update_id": 1234567890,
            "message": {
                "message_id": 77,
                "from": {
                    "id": 12345,
                    "first_name": "Vitaliy",
                    "last_name": "Meshchaninov",
                    "username": "glukki"
                },
                "chat": {
                    "id": 123456789,
                    "first_name": "Vitaliy",
                    "last_name": "Meshchaninov",
                    "username": "glukki"
                },
                "date": 1442074306,
                "text": "test"
            }
        }
    ]
}

/sendMessage?chat_id=ID&text=TEXT

Отправляет сообщение пользователю.

{
  "ok": true,
  "result": {
    "message_id": 37,
    "from": {
      "id": 1234567890,
      "first_name": "Example Bot",
      "username": "example_bot"
    },
    "chat": {
      "id": 1234567891,
      "first_name": "glukki",
      "last_name": "",
      "username": "glukki"
    },
    "date": 1437595975,
    "text": "Hello world!"
  }
}

Документация

Пример бота

  1. скачать файлы index.js и package.json в отдельную директорию;
  2. подставить в index.js токен своего бота в переменную TOKEN;
  3. в директории с файлами выполнить npm install (установит модули указанные в package.json);
  4. запустить бота командой npm start или npm run-script watch (будет перезапускать бота при изменении кода).

Некоторые источники данных

Погода по городу/координатам

http://openweathermap.org/api

http://api.openweathermap.org/data/2.5/weather?lat=59.955800&lon=30.328257

Город по координатам

https://developers.google.com/maps/documentation/geocoding/intro#ReverseGeocoding

https://maps.googleapis.com/maps/api/geocode/json?latlng=59.955800,30.328257

Часовой пояс по координатам

https://developers.google.com/maps/documentation/timezone/intro

https://maps.googleapis.com/maps/api/timezone/json?location=59.955800,30.328257&timestamp=1443344339

Рандомная картинка с котиком

http://random.cat

http://random.cat/meow

Открытые issue github репозитория

https://developer.github.com/v3/issues/

https://api.github.com/repos/nodeschool/spb/issues?sort=created&state=open

Ближайшие кафе к координатам

https://developers.google.com/places/web-service/search

https://maps.googleapis.com/maps/api/place/nearbysearch/json?location=59.955800,30.328257&radius=500&key=XXX

Последние твиты аккаунта

Требует регистрации
https://dev.twitter.com/rest/reference/get/statuses/user_timeline

'use strict';
var path = require('path');
var request = require('request');
var TOKEN = 'токен вашего бота';
var baseRequest = request.defaults({
baseUrl: 'https://api.telegram.org/bot' + TOKEN + '/'
});
var noop = function (err) {
if(err) { console.log(err); }
};
var callMethod = function (methodName, params, cb) {
cb = cb || noop;
var req = {uri: methodName, method: 'POST'};
if (Object.keys(params).length) {
req.formData = params;
}
baseRequest(req, function (err, response, body) {
// console.log(err, body);
if (err) {
return cb(err);
}
cb(err, JSON.parse(body));
});
};
var getUpdatesOffset = 0;
var getUpdates = function (cb) {
var params = {offset: getUpdatesOffset, timeout: 60};
callMethod('getUpdates', params, function (err, data) {
if (err) {
return cb(err);
}
if (data.result.length) {
getUpdatesOffset = data.result[data.result.length - 1].update_id + 1;
}
cb(err, data);
});
}
var handlers = {
'/ping': function (message) {
callMethod('sendMessage', {chat_id: message.chat.id, text: 'pong'});
},
'/cat': function (message) {
request('http://random.cat/meow', function (err, res, body) {
if (err) {
console.log(err);
return callMethod('sendMessage', {chat_id: message.chat.id, text: 'Something went wrong, try again!'});
}
var imageUrl = JSON.parse(body).file;
var file = request(imageUrl);
var params = {
chat_id: message.chat.id,
caption: imageUrl
};
if (path.extname(imageUrl) === '.gif') {
callMethod('sendChatAction', {chat_id: message.chat.id, action: 'upload_document'});
params.document = file;
callMethod('sendDocument', params);
} else {
callMethod('sendChatAction', {chat_id: message.chat.id, action: 'upload_photo'});
params.photo = file;
callMethod('sendPhoto', params);
}
});
}
};
var commands = Object.keys(handlers);
var messageHandler = function (update) {
if (!update.message || !update.message.text) {
return console.log('unhandled update', update);
}
if (commands.indexOf(update.message.text) !== -1) {
return handlers[update.message.text](update.message);
}
var text = 'Sorry, I only understand commands' + commands.join(' ');
callMethod('sendMessage', {chat_id: update.message.chat.id, text: text});
};
var runBot = function () {
getUpdates(function (err, data) {
if (err) {
console.log(err);
return runBot();
}
if (!data.ok) {
console.log(data);
return runBot();
}
data.result.map(messageHandler);
runBot();
});
};
callMethod('getMe', {}, function (err, data) {
if (err) {
throw err;
}
runBot();
});
{
"name": "telegram-bot",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"request": "^2.64.0",
"supervisor": "^0.9.1"
},
"devDependencies": {},
"scripts": {
"start": "node index.js",
"watch": "./node_modules/.bin/supervisor -i node_modules index.js"
},
"license": "ISC"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment