test tg bot

This commit is contained in:
aarizona 2024-06-30 20:37:20 +03:00
parent 65b340b873
commit f89a1f365a
6 changed files with 174 additions and 64 deletions

View File

@ -27,7 +27,7 @@ SECRET_KEY = "django-insecure-ruo!wst&sb8(f9)j5u4rda-w!673lj_-c0a%gx_t@)ff*q*2ze
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
NGROK_TEMP = '357e-193-228-134-167.ngrok-free.app' NGROK_TEMP = "a44c-193-228-134-167.ngrok-free.app"
ALLOWED_HOSTS = [ ALLOWED_HOSTS = [
"localhost", "localhost",
NGROK_TEMP, NGROK_TEMP,

77
back/poetry.lock generated
View File

@ -22,6 +22,34 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin
test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"]
trio = ["trio (>=0.23)"] trio = ["trio (>=0.23)"]
[[package]]
name = "apscheduler"
version = "3.10.4"
description = "In-process task scheduler with Cron-like capabilities"
optional = false
python-versions = ">=3.6"
files = [
{file = "APScheduler-3.10.4-py3-none-any.whl", hash = "sha256:fb91e8a768632a4756a585f79ec834e0e27aad5860bac7eaa523d9ccefd87661"},
{file = "APScheduler-3.10.4.tar.gz", hash = "sha256:e6df071b27d9be898e486bc7940a7be50b4af2e9da7c08f0744a96d4bd4cef4a"},
]
[package.dependencies]
pytz = "*"
six = ">=1.4.0"
tzlocal = ">=2.0,<3.dev0 || >=4.dev0"
[package.extras]
doc = ["sphinx", "sphinx-rtd-theme"]
gevent = ["gevent"]
mongodb = ["pymongo (>=3.0)"]
redis = ["redis (>=3.0)"]
rethinkdb = ["rethinkdb (>=2.4.0)"]
sqlalchemy = ["sqlalchemy (>=1.4)"]
testing = ["pytest", "pytest-asyncio", "pytest-cov", "pytest-tornado5"]
tornado = ["tornado (>=4.3)"]
twisted = ["twisted"]
zookeeper = ["kazoo"]
[[package]] [[package]]
name = "asgiref" name = "asgiref"
version = "3.8.1" version = "3.8.1"
@ -541,17 +569,19 @@ cli = ["click (>=5.0)"]
[[package]] [[package]]
name = "python-telegram-bot" name = "python-telegram-bot"
version = "21.2" version = "21.3"
description = "We have made you a wrapper you can't refuse" description = "We have made you a wrapper you can't refuse"
optional = false optional = false
python-versions = ">=3.8" python-versions = ">=3.8"
files = [ files = [
{file = "python-telegram-bot-21.2.tar.gz", hash = "sha256:2ebb462a98f502727d108c00bb50c513a68ddaf9545298c42f13996a9acf8354"}, {file = "python-telegram-bot-21.3.tar.gz", hash = "sha256:1be3c8b6f2b7354418109daa3f23c522e82ed22e7fc904346bee0c7b4aab52ae"},
{file = "python_telegram_bot-21.2-py3-none-any.whl", hash = "sha256:af0f45d61521126de98f5bdc8a75a9df8b93d0c35d18b018181ca7648a38b017"}, {file = "python_telegram_bot-21.3-py3-none-any.whl", hash = "sha256:8f575e6da903edd1e78967b5b481455ee6b27f2804d2384029177eab165f2e93"},
] ]
[package.dependencies] [package.dependencies]
APScheduler = {version = ">=3.10.4,<3.11.0", optional = true, markers = "extra == \"job-queue\""}
httpx = ">=0.27,<1.0" httpx = ">=0.27,<1.0"
pytz = {version = ">=2018.6", optional = true, markers = "extra == \"job-queue\""}
[package.extras] [package.extras]
all = ["APScheduler (>=3.10.4,<3.11.0)", "aiolimiter (>=1.1.0,<1.2.0)", "cachetools (>=5.3.3,<5.4.0)", "cryptography (>=39.0.1)", "httpx[http2]", "httpx[socks]", "pytz (>=2018.6)", "tornado (>=6.4,<7.0)"] all = ["APScheduler (>=3.10.4,<3.11.0)", "aiolimiter (>=1.1.0,<1.2.0)", "cachetools (>=5.3.3,<5.4.0)", "cryptography (>=39.0.1)", "httpx[http2]", "httpx[socks]", "pytz (>=2018.6)", "tornado (>=6.4,<7.0)"]
@ -564,6 +594,17 @@ rate-limiter = ["aiolimiter (>=1.1.0,<1.2.0)"]
socks = ["httpx[socks]"] socks = ["httpx[socks]"]
webhooks = ["tornado (>=6.4,<7.0)"] webhooks = ["tornado (>=6.4,<7.0)"]
[[package]]
name = "pytz"
version = "2024.1"
description = "World timezone definitions, modern and historical"
optional = false
python-versions = "*"
files = [
{file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"},
{file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"},
]
[[package]] [[package]]
name = "requests" name = "requests"
version = "2.32.3" version = "2.32.3"
@ -585,6 +626,17 @@ urllib3 = ">=1.21.1,<3"
socks = ["PySocks (>=1.5.6,!=1.5.7)"] socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "six"
version = "1.16.0"
description = "Python 2 and 3 compatibility utilities"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
[[package]] [[package]]
name = "sniffio" name = "sniffio"
version = "1.3.1" version = "1.3.1"
@ -661,6 +713,23 @@ files = [
{file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"}, {file = "tzdata-2024.1.tar.gz", hash = "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd"},
] ]
[[package]]
name = "tzlocal"
version = "5.2"
description = "tzinfo object for the local timezone"
optional = false
python-versions = ">=3.8"
files = [
{file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"},
{file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
]
[package.dependencies]
tzdata = {version = "*", markers = "platform_system == \"Windows\""}
[package.extras]
devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"]
[[package]] [[package]]
name = "urllib3" name = "urllib3"
version = "2.2.1" version = "2.2.1"
@ -681,4 +750,4 @@ zstd = ["zstandard (>=0.18.0)"]
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "58528b70db47be1cef118b365a2830312668b023e992f3aff0674f834f3c7acc" content-hash = "b0a8df55d3a7a429a89e692c2f74d3f41144a44fb1da3b108105ac9353eab7db"

View File

@ -16,7 +16,7 @@ pillow = "^10.3.0"
python-dotenv = "^1.0.1" python-dotenv = "^1.0.1"
requests = "^2.32.2" requests = "^2.32.2"
django-cors-headers = "^4.3.1" django-cors-headers = "^4.3.1"
python-telegram-bot = "^21.2" python-telegram-bot = {extras = ["job-queue"], version = "^21.3"}
[tool.poetry.group.dev.dependencies] [tool.poetry.group.dev.dependencies]
taskipy = "^1.12.2" taskipy = "^1.12.2"

View File

@ -1,13 +1,48 @@
from asgiref.sync import async_to_sync
from django.apps import AppConfig from django.apps import AppConfig
import django.conf import asyncio
import requests import threading
import queue
import time
class TgbotConfig(AppConfig): class TgBotClass(AppConfig):
default_auto_field = "django.db.models.BigAutoField" default_auto_field = "django.db.models.BigAutoField"
name = "tgbot" name = "tgbot"
is_run = False
app = None
update_queue = None
my_queue = queue.Queue()
# @async_to_sync
async def init_bot(self):
from django.conf import settings
from .tgbot import TgBotApp
tgbot = TgBotApp()
app = await tgbot.init_tg()
await tgbot.set_webhook(f"https://{settings.TGBOT['base_url']}/api/tgbot/")
return app
def updater(self=None):
while True:
if not TgBotClass.my_queue.empty():
# Здесь нужно добавить код для обработки очереди
item = TgBotClass.my_queue.get()
print("Беру дело из очереди")
async_to_sync(TgBotClass.app.process_update, force_new_loop=True)(item)
TgBotClass.my_queue.task_done()
time.sleep(1) # Ждем 1 секунду перед следующей итерацией
def ready(self): def ready(self):
from django.conf import settings import os
requests.get(f"https://api.telegram.org/bot{settings.TGBOT['token']}/setWebhook?url=https://{settings.TGBOT['base_url']}/api/tgbot/&drop_pending_updates=true")
if os.environ.get("RUN_MAIN", None) != "true":
return
if TgBotClass.is_run:
return
TgBotClass.is_run = True
TgBotClass.app = async_to_sync(self.init_bot, force_new_loop=True)()
print(TgBotClass.update_queue)

51
back/tgbot/tgbot.py Normal file
View File

@ -0,0 +1,51 @@
from asgiref.sync import async_to_sync
from django.conf import settings
from telegram import ForceReply, Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters
from telegram.constants import ParseMode, ChatType
import logging
from .apps import TgBotClass
logger = logging.getLogger("root")
class TgBotApp:
_app = None
async def start(self, update, context):
user = update.effective_user
logger.info(update)
await update.message.reply_html(
rf"Hi {user.mention_html()}!",
# reply_markup=ForceReply(selective=True),
)
async def set_webhook(self, url):
if not self._app:
logger.error("no app")
return
app = self._app
await app.bot.set_webhook(url, allowed_updates=Update.ALL_TYPES)
async def init_tg(self):
self._app = (
Application.builder()
.token(settings.TGBOT["token"])
.concurrent_updates(True)
.updater(None)
.build()
)
self._app.add_handler(CommandHandler("start", self.start))
self._app.add_handler(MessageHandler(filters.ChatType.PRIVATE, self.start))
logger.info(
{
"app": self._app,
"bot": self._app.bot,
"handlers": self._app.handlers,
}
)
await self._app.initialize()
await self._app.start()
return self._app

View File

@ -1,15 +1,14 @@
import json import json
from django.conf import settings
from telegram import Update from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters
from telegram.constants import ParseMode, ChatType
from asgiref.sync import async_to_sync from asgiref.sync import async_to_sync
from rest_framework import viewsets from rest_framework import viewsets
from rest_framework.response import Response from rest_framework.response import Response
import time
from .apps import TgBotClass
from .models import Item from .models import Item
from .serializers import ItemSerializer from .serializers import ItemSerializer
@ -18,11 +17,6 @@ import logging
logger = logging.getLogger("root") logger = logging.getLogger("root")
async def start(update, context):
logger.info(update)
await update.message.reply_html(text="123")
class ItemViewSet(viewsets.ViewSet): class ItemViewSet(viewsets.ViewSet):
queryset = Item.objects.all() queryset = Item.objects.all()
serializer_class = ItemSerializer serializer_class = ItemSerializer
@ -30,49 +24,10 @@ class ItemViewSet(viewsets.ViewSet):
@async_to_sync @async_to_sync
async def create(self, request): async def create(self, request):
req = json.loads(request.body) req = json.loads(request.body)
logger.info(req)
logger.info(f"que len before put {ptb_application.update_queue.qsize()}") logger.info(TgBotClass.app.handlers)
update_item = Update.de_json(data=req, bot=ptb_application.bot) update_item = Update.de_json(data=req, bot=TgBotClass.app.bot)
await ptb_application.update_queue.put(update_item) # TgBotClass.my_queue.put(update_item)
logger.info(f"que len after put {ptb_application.update_queue.qsize()}") await TgBotClass.app.process_update(update_item)
# await self.ptb_application.bot.send_message( return Response({"result": "pass data to tgbot"})
# chat_id=req["message"]["from"]["id"],
# text=f'Вы прислали текст `{req["message"]["text"]}`',
# parse_mode=ParseMode.MARKDOWN_V2,
# reply_to_message_id=req["message"]["message_id"],
# )
# if req["message"]["chat"]["type"] != ChatType.PRIVATE:
# return Response()
# if req["message"]["text"] == "/add":
# await self.ptb_application.bot.send_message(
# chat_id=req["message"]["from"]["id"],
# text=f'Вы хотите создать новую инвентаризацию?',
# parse_mode=ParseMode.MARKDOWN_V2,
# reply_to_message_id=req["message"]["message_id"],
# )
return Response({"test": "create"})
async def init_tg():
ptb_application = (
Application.builder().token(settings.TGBOT["token"]).concurrent_updates(True).updater(None).build()
)
ptb_application.add_handler(CommandHandler("start", start))
ptb_application.add_handler(
MessageHandler(filters.ChatType.PRIVATE, callback=start)
)
logger.info(
{
"app": ptb_application,
"bot": ptb_application.bot,
"handlers": ptb_application.handlers,
}
)
await ptb_application.initialize()
await ptb_application.start()
return ptb_application
ptb_application = async_to_sync(init_tg)()