Пишем телеграм бота на Go и AWS Lambda

GuDron

dumpz.ws
Admin
Регистрация
28 Янв 2020
Сообщения
7,564
Реакции
1,435
Credits
24,411
Что будем делать?
Будем писать простой телеграм бот, отвечающий тем же сообщением, что и отправили.

Пишем телеграм бота на Go и AWS Lambda


Пишем телеграм бота на Go и AWS Lambda

Почему AWS Lambda ?​

  1. Удобство деплоя, просто пишешь sls deploy, и lambda уже выгружена
  2. Платишь только за время, когда lambda работает
  3. Не надо настраивать никаких серверов, и беспокоиться о масштабировании

Что понадобится?​

  • Установленный go
  • Nodejs и npm для установки serverless
  • AWS аккаунт для деплоя

TLDR​

  • Клонируем репозиторий Для просмотра ссылки Войди или Зарегистрируйся
  • Устанавливаем в .env файле BOT_TOKEN переменную
  • Компилируем бинарник env GOOS=linux go build -o bin/webhook main.go
  • Выгружаем лямбду с помощью sls deploy
  • Устанавливаем webhook с помощью BOT_TOKEN

Регистрация в AWS​

  • Регистирируем пользователя в AWS Для просмотра ссылки Войди или Зарегистрируйся и получаем aws_access_key_id, и aws_secret_access_key и прописываем их в .aws/credentials файле
Вот как выглядит мой .aws/credentials

1
2
3
4
5
cat ~/.aws/credentials
[default]
aws_access_key_id = ADEFEFEFFEBDXK3
aws_secret_access_key = Zy6ewfir/zGaT1B2/o9JDWDSssdrla
region = us-west-1

Регистрация бота​

Для начала, нам надо зарегистировать бота в Для просмотра ссылки Войди или Зарегистрируйся. Идем по Для просмотра ссылки Войди или Зарегистрируйся, отправляем команду BotFather /newbot, придумываем имя боту, описание. В конце, BotFather вернет нам токен бота.Этот токен понадобится,нам для дальнейшей разработки.

Установка Serverless​

Serverless-это framework, облегчающий настройку, деплой AWS Lambda функций. Написан на node, поэтому для его установки понадобится nodejs и npm. Для просмотра ссылки Войди или Зарегистрируйся через npm
npm install -g serverless
После установки serverless проверяем, все ли установилось

1
2
3
4
5
sls -v
Framework Core: 2.35.0 (standalone)
Plugin: 4.5.3
SDK: 4.2.2
Components: 3.8.2
Теперь можно приступить к конфигурации serverless. Все настройки для serverless лежат в serverless.yml файле,который мы и создадим со следующим контентом

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
service: echoBot
useDotenv: true
configValidationMode: error # если в конфиге,чтото неправильно ,то ошибка
frameworkVersion: '>=1.28.0 <2.50.0'

provider:
region: "us-west-1"
lambdaHashingVersion: "20201221"
name: aws
runtime: go1.x
logRetentionInDays: 30 # сколько дней хранить логи
endpointType: regional
tracing: # включаем трейсинг для лямбды
apiGateway: true
lambda: true
iam:
role:
statements:
- Effect: "Allow"
Resource: "*"
Action:
- "xray:*"
package:
patterns:
- "bin/webhook" # деплоить только бинарник

functions:
webhook:
handler: bin/webhook
timeout: 15
description: simple echo bot
memorySize: 128 # размер памяти в мегабайтах для функции
environment:
BOT_TOKEN: ${env:BOT_TOKEN}
events:
- http:
path: /webhook
method: ANY
cors: false

Имлементация логики бота на Go​

  1. Устанавливаем библиотеки telebot.v2 и aws-lambda-go
1
2
3
4
5
6
7
➜ go mod init testBot
go: creating new go.mod: module testBot
➜ go get -u gopkg.in/tucnak/telebot.v2
go: gopkg.in/tucnak/telebot.v2 upgrade => v2.3.5
go: github.com/pkg/errors upgrade => v0.9.1
➜ go get github.com/aws/aws-lambda-go
go: github.com/aws/aws-lambda-go upgrade => v1.23.0
2. Создаем файл main.go с контентом

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
package main

import (
"encoding/json"
"fmt"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
tb "gopkg.in/tucnak/telebot.v2"
"os"
)

func main() {
settings := tb.Settings{
Token: os.Getenv("BOT_TOKEN"),
Synchronous: true,
Verbose: true,
}
tgBot, err := tb.NewBot(settings)
if err != nil {
fmt.Println(err)
panic("can't create bot")
}
tgBot.Handle(tb.OnText, func(m *tb.Message) {
message := m.Text
tgBot.Send(m.Sender, message)
})
lambda.Start(func(req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
var u tb.Update
if err = json.Unmarshal([]byte(req.Body), &u); err == nil {
tgBot.ProcessUpdate(u)
}
return events.APIGatewayProxyResponse{Body: "ok", StatusCode: 200}, nil

})
}
Текущая документация в tucnak/telebot.v2 немного устарела, и если просто написать return вместо return events.APIGatewayProxyResponse{Body: "ok", StatusCode: 200}, nil, то телеграм будет повторно отправлять сообщения к боту.

Deploy бота​

  • Создаем файл .env и вставляем API_TOKEN полученный от BotFather
1echo API_TOKEN={API_TOKEN_FROM_BOTFATHER} > .env
Проверяем serverlss конфиг с помощью команды. Не должно быть никаких ошибок.

1sls print
Потом собираем бинарник

1env GOOS=linux go build -o bin/webhook main.go
И выгружаем его с помощью serverless

1serverless deploy -v
При успешной выгрузке, мы получим в конце

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Service Information
service: echoBot
stage: dev
region: us-west-1
stack: echoBot-dev
resources: 11
api keys:
None
endpoints:
ANY - Для просмотра ссылки Войди или Зарегистрируйся
functions:
webhook: echoBot-dev-webhook
layers:
None
Для просмотра ссылки Войди или Зарегистрируйся=> этот эндпоинт и token бота нужен нам, чтобы установить webhook

Интеграция с telegram​

Осталось сообщить телеграму, какой эндпоинт дергать при получении сообщения. Делается это командой setWebhook

1curl Для просмотра ссылки Войди или Зарегистрируйся{YOUR_TOKEN}/setWebhook?url={YOUR_DEPLOYED_AWS_URL}
Проверка что webhook установлен, происходит с помощью getWebhookInfo

1
2
3
4
➜ ~ curl Для просмотра ссылки Войди или Зарегистрируйся Для просмотра ссылки Войди или Зарегистрируйся
{"ok":true,"result":true,"description":"Webhook was set"}
➜ ~ curl Для просмотра ссылки Войди или Зарегистрируйся
{"ok":true,"result":{"url":"Для просмотра ссылки Войди или Зарегистрируйся","has_custom_certificate":false,"pending_update_count":0,"max_connections":40,"ip_address":"184.169.148.254"}}

Ошибки​

Если что-то пошло не так,идем в Для просмотра ссылки Войди или Зарегистрируйся и смотрим логи,или же из консоли также можно посмотреть логи

1sls logs -f webhook