У нашего бота есть один недостаток: Как только мы прервём выполнение скрипта, то бот перестанет работать. Поэтому неплохо было бы опубликовать его на каком-нибудь сервере, который поддерживает работу с Node.JS. В этой заметке будет описана работа с AWS . Я предполагаю, что Вы уже зарегистрировались на этом ресурсе, у Вас все секретные ключи. Если нет, то вот здесь описано, как его получить. У меня есть безплатный ключ скором на один год, а дальше посмотрим, как сложится.
После получения ключа установите пакет
npm install -g serverless
Запишите этот ключ:
serverless config credentials --provider provider --key key --secret secret
Следующий шаг: создание функции AWS Lambda, которая будет запускаться через Telegram HTTP webhook. Эта функция будет отвечать за вызов Telegram API отправку результата пользователю. Чтобы создать лямбда-функцию, просто создайте новую папку на компьютере, перейдите внутрь нее, откройте окно терминала и введите следующее:
serverless create --template aws-nodejs
Как вы, вероятно, догадались, это создаст очень простой шаблон для будущих функций Node.js . Шаблон фактически состоит из двух файлов: handler.js и serverless.yml. handler.js - точка ввода кода функции, а serverless.yml - файл конфигурации сервера, в котором можно объявить триггер сервера и другие параметры. Больше прочитать о конфигурации - ссылка .
Вот как я предлагаю настроить будущий сервер:
service: short-bot
useDotenv: true
plugins:
- serverless-dotenv-plugin
frameworkVersion: "2"
provider:
name: aws
runtime: nodejs12.x
region: eu-west-1
apiGateway:
shouldStartNameWithService: true
lambdaHashingVersion: "20201221"
functions:
hello:
handler: handler.hello
events:
- http:
path: webhook
method: post
cors: true
В каталоге этого проекта сделайте команды:
npm init -y
npm i --save dotenv node-fetch telegraf
npm i --save-dev serverless serverless-dotenv-plugin
Мы сейчас сделали очень многое: сделали шаблон проекта, который можно будет опубликовать на амазоне. Для публикации нам понадобится пакет serverless, а для разработки - serverless-dotenv-plugin, который поможет нам во время развертывания подхватывать переменные из файла .env.
Теперь в этот проект скопируйте все файлы из каталога, где у нас был телеграм-бот и давайте немного изменим файл handler.js:
"use strict";
const { bot } = require("./bot.js");
const { getResponseHeaders } = require("./lib/common");
exports.getResponseHeaders = () => {
return {
"Access-Control-Allow-Origin": "*",
};
};
/**
* Вебхук для бота
*/
module.exports.hello = async (event) => {
try {
let body =
event.body[0] === "{"
? JSON.parse(event.body)
: JSON.parse(Buffer.from(event.body, "base64"));
await bot.handleUpdate(body);
return { statusCode: 200, body: "" };
} catch (err) {
return {
statusCode: err.statusCode ? err.statusCode : 500,
headers: getResponseHeaders(),
body: JSON.stringify({
error: err.name ? err.name : "Exception",
message: err.message ? err.message : "Unknown error",
}),
};
}
};
/**
* Устновка веб-хука.
* Если вызвать этот метод, то хук вступит в силу
*/
module.exports.setWebhook = async (event) => {
try {
const url = `https://${event.headers.Host}/${event.requestContext.stage}/webhook`;
await bot.telegram.setWebhook(url);
return {
statusCode: 200,
headers: getResponseHeaders(),
body: JSON.stringify({ url }),
};
} catch (err) {
return {
statusCode: err.statusCode ? err.statusCode : 500,
headers: getResponseHeaders(),
body: JSON.stringify({
error: err.name ? err.name : "Exception",
message: err.message ? err.message : "Unknown error",
}),
};
}
};
Функция getResponseHeaders формирует заголовки ответа.
Функция hello, о которой говорилось в файле serverless.yml это и есть тот самый веб-хук, который будет отвечать за работу нашего бота.
Функция setWebhook - это метод, который привязывает веб-хук к боту. Как вы поняли, ключевые строки в нём это
1 const url = `https://${event.headers.Host}/${event.requestContext.stage}/webhook`;
2 bot.telegram.setWebhook(url);
В первой строке мы получаем url нашего метода, когда он будет опубликован, вторая вызывает метод API телеграмм-бота.
Для публикации нужно слегка изменить файл bot.js. Поскольку наш бот будет теперь запущен не на локальной машине, нужно закомментировать строку bot.launch();
и ниже написать:
module.exports = {
bot,
};
У себя в проекте файл bot.js я переместил в каталог telegramBot, изменил пути в require.
Далее в секции scripts в package.json добавим:
{
"deploy": "sls deploy",
"logs": "sls logs --function hello -t"
}
С помощью команды npm run local
можно будет запустить функцию локально, deploy
- задеплоить в amazon, logs
- для вывода потока логов в консоль.
Деплой
Командой npm run deploy
можно задеплоить функцию в AWS. В терминале вы будете видеть весь процесс деплоя лямбды (все файлы складываются в zip архив и заливаются в S3). В итоге вы получите постоянный эндпоинт, что-то типа: https://sg2bxp8khj.execute-api.us-east-2.amazonaws.com/dev/, его нужно установить в качестве вебхука для телеграма.
Для установки хука нужно отправить POST-запрос на адрес функции SetWebhook, который мы получили после развёртывания:
Запрос можно отправить используя команду curl -X POST https://address
либо используя программу Postman. Если всё прошло без ошибок, то Ваш бот теперь обосновался на сервере амазон, поздравляю!
Ссылки
Вот какие материалы мне помогли в развёртывании на амазоне:
Top comments (0)