Skip to main content

基于flask和webhook的telegram 机器人

SmartDeng...About 4 minFlaskPythonLinuxDebianNginxFlask

基于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://api.telegram.org/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:

mawwalker/Archbotopen in new window

Comments
  • Latest
  • Oldest
  • Hottest
Powered by Waline v3.1.3