DEV Community

Stanislav Karol
Stanislav Karol

Posted on

3 1

Телеграм-бот на NodeJS. 4. Развёртывание на Amazon web service (AWS).

У нашего бота есть один недостаток: Как только мы прервём выполнение скрипта, то бот перестанет работать. Поэтому неплохо было бы опубликовать его на каком-нибудь сервере, который поддерживает работу с Node.JS. В этой заметке будет описана работа с AWS . Я предполагаю, что Вы уже зарегистрировались на этом ресурсе, у Вас все секретные ключи. Если нет, то вот здесь описано, как его получить. У меня есть безплатный ключ скором на один год, а дальше посмотрим, как сложится.
После получения ключа установите пакет

npm install -g serverless
Enter fullscreen mode Exit fullscreen mode

Запишите этот ключ:

serverless config credentials --provider provider --key key --secret secret
Enter fullscreen mode Exit fullscreen mode

Следующий шаг: создание функции AWS Lambda, которая будет запускаться через Telegram HTTP webhook. Эта функция будет отвечать за вызов Telegram API отправку результата пользователю. Чтобы создать лямбда-функцию, просто создайте новую папку на компьютере, перейдите внутрь нее, откройте окно терминала и введите следующее:

serverless create --template aws-nodejs
Enter fullscreen mode Exit fullscreen mode

Как вы, вероятно, догадались, это создаст очень простой шаблон для будущих функций 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

Enter fullscreen mode Exit fullscreen mode

В каталоге этого проекта сделайте команды:

npm init -y
npm i --save dotenv node-fetch telegraf
npm i --save-dev serverless serverless-dotenv-plugin
Enter fullscreen mode Exit fullscreen mode

Мы сейчас сделали очень многое: сделали шаблон проекта, который можно будет опубликовать на амазоне. Для публикации нам понадобится пакет 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",
      }),
    };
  }
};
Enter fullscreen mode Exit fullscreen mode

Функция getResponseHeaders формирует заголовки ответа.
Функция hello, о которой говорилось в файле serverless.yml это и есть тот самый веб-хук, который будет отвечать за работу нашего бота.
Функция setWebhook - это метод, который привязывает веб-хук к боту. Как вы поняли, ключевые строки в нём это

1 const url = `https://${event.headers.Host}/${event.requestContext.stage}/webhook`;
2 bot.telegram.setWebhook(url);
Enter fullscreen mode Exit fullscreen mode

В первой строке мы получаем url нашего метода, когда он будет опубликован, вторая вызывает метод API телеграмм-бота.
Для публикации нужно слегка изменить файл bot.js. Поскольку наш бот будет теперь запущен не на локальной машине, нужно закомментировать строку bot.launch(); и ниже написать:

module.exports = {
  bot,
};
Enter fullscreen mode Exit fullscreen mode

У себя в проекте файл bot.js я переместил в каталог telegramBot, изменил пути в require.
Далее в секции scripts в package.json добавим:

{
  "deploy": "sls deploy",
  "logs": "sls logs --function hello -t"
}
Enter fullscreen mode Exit fullscreen mode

С помощью команды npm run local можно будет запустить функцию локально, deploy - задеплоить в amazon, logs - для вывода потока логов в консоль.

Деплой

Командой npm run deploy можно задеплоить функцию в AWS. В терминале вы будете видеть весь процесс деплоя лямбды (все файлы складываются в zip архив и заливаются в S3). В итоге вы получите постоянный эндпоинт, что-то типа: https://sg2bxp8khj.execute-api.us-east-2.amazonaws.com/dev/, его нужно установить в качестве вебхука для телеграма.
Для установки хука нужно отправить POST-запрос на адрес функции SetWebhook, который мы получили после развёртывания:
setWebhook
Запрос можно отправить используя команду curl -X POST https://address либо используя программу Postman. Если всё прошло без ошибок, то Ваш бот теперь обосновался на сервере амазон, поздравляю!

Ссылки

Вот какие материалы мне помогли в развёртывании на амазоне:

AWS GenAI LIVE image

How is generative AI increasing efficiency?

Join AWS GenAI LIVE! to find out how gen AI is reshaping productivity, streamlining processes, and driving innovation.

Learn more

Top comments (0)

Postgres on Neon - Get the Free Plan

No credit card required. The database you love, on a serverless platform designed to help you build faster.

Get Postgres on Neon

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay