如何组织Telegram bot(Aiogram)和Flask同时运行?

问题描述 投票:0回答:2

我需要建议。

我有一个机器人(使用远程机器人编写)和一个 API(Flask),它们在两个线程中运行并同时安静地工作。该机器人通过轮询启动。

API 处理来自多个地址的传入 POST 请求。

现在我正在使用 aiogram 重写机器人。 我知道你不能混合异步和线程,但是这两个模块的同时操作存在困难。机器人或 API 都可以工作。

有哪些选项可以与 Flask 和 Aiogram 交朋友,或者我们应该放弃使用 Flask 并以不同的方式处理请求?

我还阅读了有关 webhooks 的选项,似乎你可以在那里捕获 POST 请求,然后不需要 Flask。

我尝试了在不同线程中运行的选项:

import threading
import time
from time import sleep
from flask import Flask,request
from flask_restful import Api, Resource
import config
import asyncio,hashlib,requests,threading,time
import logs
from aiogram import Bot, Dispatcher, executor, types
from asyncio import new_event_loop, set_event_loop

app = Flask(__name__)
api = Api(app)
dp = Dispatcher(Bot(token=config.bot_token))

@dp.message_handler(commands="start")
async def message_start(message: types.Message):
    await message.answer("HI")

@app.route('/test', methods=['POST'])
def get_test():
    data = request.get_json()
    print (data)
    return ("ok")

def app_run():
    while True:
        try:
            app.run()
        except Exception as ex:
            print(ex)

def bot_polling():
    try:
        executor.start_polling(dp, skip_updates=True)
        set_event_loop(new_event_loop())
    except Exception as ex:
        print(ex)

bot_thread = threading.Thread(target=bot_polling)
bot_thread.daemon = True
bot_thread.start()

app_thread = threading.Thread(target=app_run)
app_thread.daemon = True
app_thread.start()

if __name__ == "__main__":
    while True:
        try:
            sleep(1)
        except KeyboardInterrupt:
            break

我还尝试使用“on_startup”内置 aiogram 来使用异步:

import threading
import time
from time import sleep
from flask import Flask, jsonify, request
from flask_restful import Api, Resource
import config
import asyncio,hashlib,requests,threading,time
import logs
from aiogram import Bot, Dispatcher, executor, types
from asyncio import new_event_loop, set_event_loop

app = Flask(__name__)
api = Api(app)
dp = Dispatcher(Bot(token=config.bot_token))

@dp.message_handler(commands="start")
async def message_start(message: types.Message):
    print("hi")
    await message.answer("HI")

@app.route('/test', methods=['POST'])
def get_test():
    data = request.get_json()
    print (data)
    return ("ok")

async def is_enabled():
  while True:
    await app.run()

async def on_startup(x):
    asyncio.create_task(is_enabled())

if __name__ == '__main__':
    executor.start_polling(dispatcher=dp, skip_updates=True, on_startup=on_startup)
multithreading flask async-await telegram aiogram
2个回答
0
投票

最适合您的选择是 https://docs.aiogram.dev/en/latest/examples/webhook_example.html webhooks。

如果您将使用数据库的逻辑放在一个单独的模块中,我们将通过该模块与烧瓶和机器人进行通信,那么应该没有问题。然后用这样的拐杖运行它们:)

两个模块并行工作:

flask_api.py

def main():
    app = Flask(__name__)
    api = Api(app)
    api.init_app(app)
    app.run(port=PORT, host=HOST)


if __name__ == '__main__':
    main()

aiogram_bot.py

async def main():
    bot = Bot(token=TOKEN_TG)
    dp = Dispatcher(bot)
    
    await dp.skip_updates()
    await dp.start_polling()


if __name__ == '__main__':
    asyncio.run(main())

我这样运行它们:

app.py

import multiprocessing
import subprocess


api_process = multiprocessing.Process(
    target=subprocess.run,
    kwargs={
        'args': f'{PYTHON_PATH} flask_api.py',
        'shell': True
    })


bot_process = multiprocessing.Process(
    target=subprocess.run,
    kwargs={
        'args': f'{PYTHON_PATH} aiogram_bot.py',
        'shell': True
    })


if __name__ == '__main__':
    api_process.start()
    bot_process.start()

0
投票

我知道已经很晚了,但我是这样修复的:

import asyncio

async def start_raid_bot():
    dp_bot1 = Dispatcher()
    dp_bot1.include_router(raid_router)
    await dp_bot1.start_polling(bot1)

async def start_trend_bot():
    dp_bot2 = Dispatcher()
    dp_bot2.include_router(router_trend_bot)
    await dp_bot2.start_polling(bot2)

async def main():
    asyncio.create_task(confirm_payment_and_inform_user())
    task_bot1 = asyncio.create_task(start_raid_bot())
    task_bot2 = asyncio.create_task(start_trend_bot())
    await task_bot1
    await task_bot2

if __name__ == "__main__":
    asyncio.run(main())
© www.soinside.com 2019 - 2024. All rights reserved.