启动django项目的telegram bot



我正在开发一个djnago项目,并想将一个电报机器人连接到它。我正在使用python-telegram-bot,但不知道如何在django服务器启动时启动机器人。

from django.apps import AppConfig
from .telegramBot import updater

class SocialMediaConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'memefinder'
def ready(self) -> None:
updater.start_polling()
pass

我将此代码添加到该项目的一个应用程序的apps.py文件中,但它不起作用。每次运行项目时都收到此错误消息telegram.error.Conflict: Conflict: terminated by other getUpdates request; make sure that only one bot instance is running

这是CCD_ 4文件的代码。这是一个非常简单的代码。

from telegram import Update, ForceReply
from telegram.ext import Updater, CommandHandler, MessageHandler, Filters, CallbackContext
updater = Updater("TOKEN")
dispatcher = updater.dispatcher
def start(update: Update, context: CallbackContext) -> None:
"""Send a message when the command /start is issued."""
user = update.effective_user
update.message.reply_markdown_v2(
fr'Hi {user.mention_markdown_v2()}!',
reply_markup=ForceReply(selective=True),
)
dispatcher.add_handler(CommandHandler("start", start))

实际上,这里最好的解决方案是将Telegram bot和web应用程序拆分为使用不同的进程(单独运行(。

这里的问题是,您试图在Djnago应用程序中运行电报处理程序循环。它不会工作,因为几个原因:

  1. Django运行多个工作程序,而您的telegram bot库似乎不支持运行并行工作程序
  2. Django同步运行代码,这意味着即使你成功地运行了Telegram bot代码,它也会因为Telegram bot处理程序中的无限循环而挂起web应用服务器

此外,现在您使用的是使用manage.py命令的Django开发服务器,但如果您要将应用程序部署到生产环境中,您的配置会有所不同:您应该使用一些生产就绪的解决方案,如gunicorn。在不同的环境中,网络服务器的不同配置将使编写正确且可扩展的代码更难为网络应用程序和Telegram机器人提供服务。

我知道你可能正在寻找一种方法,在Telegram机器人中从Django ORM获取数据,或者使用其他Django功能。如果是这样,您仍然可以从其他脚本访问django。您所需要做的就是指定DJANGO_SETTINGS_MODULE环境变量来帮助Django找到您的设置模块。

因此,创建一个单独的Python脚本(例如,应用程序根目录中的telegram_bot.py(来运行Telegram bot,并单独运行。

$ DJANGO_SETTINGS_MODULE=yourapp.settings telegram_bot.py

将运行你的机器人,同时你将能够导入Django模型并在该脚本中使用它们。

问题似乎是Django的自动重载程序。当运行manage.py runserver命令时,它会生成两个实例。一个文件监视进程,每当其中一个项目文件发生更改时,就会重新加载项目,另一个是主进程。你可以在这篇文章中阅读更多关于它的内容。

为了解决这个问题,您只需要在程序由主进程运行时检查并加载进程,这可以通过检查"run_main"环境变量来完成:

主页/apps.py:

from django.apps import AppConfig

class HomeConfig(AppConfig):
name = 'Home'
def ready(self):
import os
from . import jobs
# RUN_MAIN check to avoid running the code twice since manage.py runserver runs 'ready' twice on startup
if os.environ.get('RUN_MAIN', None) != 'true':
# Your function to run the bot goes here

上面的示例假设您有一个名为Home的应用程序,app.py位于其中。

最新更新