基于flask和webhook的telegram 机器人
基于flask和webhook的telegram 机器人
2023-03-26 最新更新:懒了很长一段时间,最近回来重新折腾了。手头上的服务器多了,又开始折腾了起来。加上最近ChatGPT大火,想起了这个被我搁置很久的Telegram机器人。由于时间久远,之前的部署方式已经不能用了,便重新研究了起来,并且从python-telegram-bot这个库切换到了webhook+requests调用官方API的方式实现。
先用最简单的方式,实现一个能通过webhook响应的机器人吧,有了这个之后,后面的拓展其他功能,就是基于Python再进行开发了。 从去年开始,我的很多服务都尽量使用docker的方式进行部署,因为真的很方便,所以下面的很多步骤,需要提前安装好docker环境,会基本的docker操作。
1. 环境
服务器: Ubuntu 22.04 LTS
Python环境: Python 3.10
Flask
google-api-core
google-auth
google-cloud-core
google-cloud-translate
googleapis-common-protos
python-telegram-bot
requests
其中有google翻译api需要的库,但是后面的例子暂时没有用到
2. 前置条件
2.1. Docker 配置
本文部署方式使用的docker,需要提前配置好docker,并且使用的nginx作为代理,我使用的nginx-proxy-manager这个docker部署的nginx代理,配置非常方便。 为了方便docker之间的通信,建立一个docker bridge网络:
docker network create -d bridge nginx-proxy
然后将你的nginx-proxy-manager容器添加到这个网络,这样后面其他docker都加入这个网络,nginx-proxy-manager是可以用docker容器名字去访问其他docker的。
docker network connect nginx-proxy you_container
2.2. Telegram Bot
先根据telegram bot的教程,申请一个bot,并且拿到bot的token,之后,需要设置bot的webhook。
打开浏览器去这个url设置你的webhook:
https:/bot{token}/setWebhook?url=https://tg.yourdomain.com/111111:aaaa
其中,将{token}替换为你的bot的token,前面的bot
是必须保留的,url后面替换为你想设置的webhook。
强烈建议将webhook的url设置复杂点,推荐使用https://tg.youdomain.com/token ,这种,把你的bot token放到域名后面。
这里需要跟后面设置flask的route相对应。
3. 代码
app.py:
from flask import Flask
from flask import request
from flask import Response
from tgbot import TG
app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
msg = request.get_json()
tg_bot = TG()
tg_bot.parse_message(msg)
return Response('ok', status=200)
else:
return "<h1>Welcome!</h1>"
if __name__ == '__main__':
app.run(debug=True)
app.py里面主要是构建flask,以及将所有的消息处理交给TG这个类。
注意:route('/')这里跟你设置webhook有关,如果你的webhook是https://tg.youdomain.com/1111:aaaa ,那么这里应该是route('/1111:aaaa')
tgbot.py:
#!/usr/bin/env python
# coding=utf-8
import json
from flask import request
import requests
class TG():
def __init__(self):
with open('config/config.json', encoding='utf-8') as cf:
config = json.load(cf)
self.access_token = config["access_token"]
def help(self, chat_id, msg):
self.tel_send_message(chat_id=chat_id, text="/help 查看帮助\n")
def list2str(self, trains, tk):
# 用来存放最终合成的消息列表
text_list = []
for train in trains:
temp = []
for i in range(15):
# 当该列不为空时才合成
if train[i] != '':
temp.append(tk.columns[i] + ":" + train[i])
text_list.append(' | '.join(temp).upper())
text_ticket = '\n\n'.join(text_list).upper()
return text_ticket
def parse_message(self, message):
print("message-->",message)
chat_id = message['message']['chat']['id']
txt = message['message']['text']
print("chat_id-->", chat_id)
print("txt-->", txt)
if "/help" in txt:
self.help(chat_id, txt)
else:
text = 'Hello'
self.tel_send_message(chat_id=chat_id, text=text)
def tel_send_message(self, chat_id, text):
url = f'https://api.telegram.org/bot{self.access_token}/sendMessage'
payload = {
'chat_id': chat_id,
'text': text
}
r = requests.post(url,json=payload)
return r
这里面主要是定义了TG这个类,用来处理所有的消息,发送使用的官方的api。
4. 部署
首先在代码根目录中,建立Dockerfile.
4.1 Dockerfile
FROM tiangolo/uwsgi-nginx-flask
COPY ./requirements.txt /var/www/requirements.txt
RUN pip install -r /var/www/requirements.txt
之后下面docker run与docker compose方式二选一即可。
4.2 Option 1. Docker run
使用docker run 脚本:
#!/bin/bash
# . venv/bin/activate && uwsgi --socket 172.17.0.1:8000 -p -w app:app
app="tgbot"
docker build -t ${app} .
docker run -d --name=${app} -v $PWD:/app ${app} --network=nginx-proxy
这里需要用到前面提到的,docker bridge网络:nginx-proxy,方便nginx-proxy-manager能够直接识别这个docker.
tgbot你可以自己随便命名,但是要记住,后面要用。
4.2 Option 2. Docker Compose
或者使用docker compose 来启动
version: "3"
services:
app:
image: 'tgbot:v1.1'
build: .
container_name: tgbot
restart: unless-stopped
# ports:
# - '80:80' # Public HTTP Port
volumes:
- ./:/app
networks:
- nginx-proxy
networks:
nginx-proxy:
external: true
然后运行:
docker compose up -d # docker compose v2及以上
docker-compose up -d # docker-compose v2以下
上面都启动docker之后,可以使用docker ps -a查看容器运行情况,同时记得docker container的名字, 如果按照我前面做,名字是tgbot
.
下面配置Nginx-proxy-manager的代理
5. Nginx proxy
由于前面已经设置了nginx-proxy-manager与tgbot容器都在同一个网络nginx-proxy中。 所以这里配置代理就很简单,点击添加代理,代理协议http,代理地址:tgbot,端口:80. 之后添加ssl证书,即完成了nginx配置。
可以在telegram中跟你的bot聊天试试了!
具体代码内容见我的github: