From 928ad79d9e6f463aeab940084eb519f3f4ee14db Mon Sep 17 00:00:00 2001 From: pilot <657434@03b.ru> Date: Wed, 15 Apr 2026 00:45:46 +0800 Subject: [PATCH] =?UTF-8?q?=D0=9F=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- restoran_max_bot/max_bot/max_api.py | 71 +++++++++++++++++++ restoran_max_bot/max_bot/models.py | 34 +++++++++ restoran_max_bot/max_bot/urls.py | 2 +- restoran_max_bot/max_bot/views.py | 51 ++++++++----- .../restoran_max_bot/bot_message.py | 21 ++++++ .../restoran_max_bot/bot_started.py | 10 +++ .../restoran_max_bot/bot_stopped.py | 10 +++ restoran_max_bot/restoran_max_bot/common.py | 11 +++ 8 files changed, 192 insertions(+), 18 deletions(-) create mode 100644 restoran_max_bot/restoran_max_bot/bot_message.py create mode 100644 restoran_max_bot/restoran_max_bot/bot_started.py create mode 100644 restoran_max_bot/restoran_max_bot/bot_stopped.py create mode 100644 restoran_max_bot/restoran_max_bot/common.py diff --git a/restoran_max_bot/max_bot/max_api.py b/restoran_max_bot/max_bot/max_api.py index 995f29b..b8b4be7 100644 --- a/restoran_max_bot/max_bot/max_api.py +++ b/restoran_max_bot/max_bot/max_api.py @@ -19,3 +19,74 @@ def maxbot_send_text_message(chat_id: str, max_token: str, message: str): rt = {'success': True, 'error': '', 'data': response} return rt + + +def maxbot_send_img_message(chat_id: str, max_token: str, message: str, img: str): + url = f"https://platform-api.max.ru/messages?chat_id={chat_id}" + + payload = json.dumps({ + "text": message, + "attachments": [ + {"type": "image", + "payload": {"url": img} + } + ] + + }) + headers = { + 'Authorization': f'{max_token}', + 'Content-Type': 'application/json' + } + response = requests.request("POST", url, headers=headers, data=payload) + rt = {'success': True, 'error': '', 'data': response} + + return rt + + +def maxbot_send_menu_button(chat_id: str, max_token: str, message: str, buton: list): + url = f"https://platform-api.max.ru/messages?chat_id={chat_id}" + + payload = json.dumps({ + "text": message, + "attachments": [ + {"type": "inline_keyboard", + "payload": { + "buttons": [ + [ + { + "type": "link", + "text": "Откройте сайт", + "url": "https://example.com" + }, + { + "type": "link", + "text": "Закройте сайт", + "url": "https://example.com" + } + ], + [ + { + "type": "link", + "text": "Откройте сайт", + "url": "https://example.com" + }, + { + "type": "link", + "text": " 🍺 Закройте сайт", + "url": "https://example.com" + } + ] + ] + } + } + ] + + }) + headers = { + 'Authorization': f'{max_token}', + 'Content-Type': 'application/json' + } + response = requests.request("POST", url, headers=headers, data=payload) + rt = {'success': True, 'error': '', 'data': response} + + return rt diff --git a/restoran_max_bot/max_bot/models.py b/restoran_max_bot/max_bot/models.py index 665882a..b796267 100644 --- a/restoran_max_bot/max_bot/models.py +++ b/restoran_max_bot/max_bot/models.py @@ -554,3 +554,37 @@ class MessageTemplate(models.Model): class Meta: db_table = 'vi_mess_template' + + +# Информация продукции +class Product(models.Model): + objects = None + client = models.ForeignKey(Client, on_delete=models.PROTECT) + up = models.IntegerField() + title = models.CharField(max_length=200, null=True, help_text='Наименование продукции') + descr = models.CharField(max_length=200, null=True, help_text='Описание продукции') + img = models.CharField(max_length=200, null=True, help_text='Картинка продукции') + price = models.FloatField(help_text='Стоимотсь продукции') + sku = models.CharField(max_length=100, null=True, help_text='идентификационный код товарной позиции у партнера') + status = models.IntegerField() + + class Meta: + db_table = 'lk_product' + + +# Информация о категории товара +class ProductCategory(models.Model): + objects = None + client = models.ForeignKey(Client, on_delete=models.PROTECT, verbose_name='id client') + emojii = models.CharField(max_length=20, null=True, help_text='Картинка товара') + title = models.CharField(max_length=250, null=True, help_text='Наименование категории') + slug = models.CharField(max_length=250, null=True, help_text='Наименование категории') + descr = models.CharField(max_length=200, null=True, help_text='Описание') + src = models.IntegerField( + help_text='для кого сделана категория 01-1 telegram, 10-2-qrmenu, 11-3 qrmenu and telegram') + status = models.BooleanField(default=0, help_text='отображать или нет категорию') + ord = models.IntegerField(help_text='порядок отображения') + dt = models.DateTimeField(help_text='дата создания') + + class Meta: + db_table = 'lk_product_category' diff --git a/restoran_max_bot/max_bot/urls.py b/restoran_max_bot/max_bot/urls.py index 53b2327..98b98b3 100644 --- a/restoran_max_bot/max_bot/urls.py +++ b/restoran_max_bot/max_bot/urls.py @@ -4,5 +4,5 @@ from django.urls import path from max_bot.views import api_start_max_v1 urlpatterns = [ - path('api/v1/', api_start_max_v1), + path('api/v1', api_start_max_v1), ] diff --git a/restoran_max_bot/max_bot/views.py b/restoran_max_bot/max_bot/views.py index d9a3895..3fd5c75 100644 --- a/restoran_max_bot/max_bot/views.py +++ b/restoran_max_bot/max_bot/views.py @@ -1,14 +1,28 @@ import json from django.http import JsonResponse -from max_bot.max_api import maxbot_send_text_message +from django.views.decorators.csrf import csrf_exempt from max_bot.models import Partner, Integration, Client -from restoran_max_bot.utils import is_json +from restoran_max_bot.bot_started import bot_started +from restoran_max_bot.bot_stopped import bot_stopped +from restoran_max_bot.bot_message import bot_message +from restoran_max_bot.utils import is_json, has_key def api_decorator(func): def wrapper_api_decorator(*args, **kwargs): + if 'X-Max-Bot-Api-Secret' in args[0].headers: + token = args[0].headers['X-Max-Bot-Api-Secret'] + token = '71232b71-dacc-4586-95d0-0f352d9d09c3' + else: + rt = {'success': False, 'error': 'Unauthorized token', 'data': {}} + return JsonResponse(rt, status=401) + + if not is_json(args[0].body.decode('utf-8')): + rt = {'success': False, 'error': 'data not JSON', 'data': ''} + return JsonResponse(rt, status=200) + # получаем информацию по токену клиента и делаем проверку - client = Client.objects.filter(token=kwargs['token']).first() + client = Client.objects.filter(token=token).first() if not client: rt = {'success': False, 'error': 'Unauthorized token', 'data': {}} return JsonResponse(rt, status=401) @@ -30,6 +44,7 @@ def api_decorator(func): return JsonResponse(rt, status=404) settings_max = json.loads(integration.setting) + settings_max['token'] = integration.token kwargs['client'] = client kwargs['integration'] = integration @@ -40,26 +55,28 @@ def api_decorator(func): return wrapper_api_decorator +@csrf_exempt @api_decorator -def api_start_max_v1(request, token, **kwargs): +def api_start_max_v1(request, **kwargs): data = json.loads(request.body.decode('utf-8')) - print(data) - client = kwargs['client'] settings_max = kwargs['settings_max'] - # получение сообщения + if not has_key(data, 'update_type'): + rt = {'success': False, 'error': 'data update_type not found', 'data': ''} + return JsonResponse(rt, status=200) + + # получение сообщения из бота if data['update_type'] == 'message_created': - print(data) - chat_id = data['message']['recipient']['chat_id'] - chat_type = data['message']['recipient']['chat_type'] - text = str(data['message']['body']['text']).lower() - maxbot_send_text_message(chat_id=chat_id, max_token=settings_max['token'], message=text) - - # добавление бота в группу - if data['update_type'] == 'bot_added': - chat_id = data['chat_id'] - maxbot_send_text_message(chat_id=chat_id, max_token=settings_max['token'], message='bot_added') + bot_message(client=client, message=data, settings=settings_max) + + # start - запуск бота + if data['update_type'] == 'bot_started': + bot_started(client=client, message=data, settings=settings_max) + + # выход из бота + if data['update_type'] == 'bot_stopped': + bot_stopped(client=client, message=data, settings=settings_max) rt = {'success': True, 'error': '', 'data': ''} return JsonResponse(rt, status=200) diff --git a/restoran_max_bot/restoran_max_bot/bot_message.py b/restoran_max_bot/restoran_max_bot/bot_message.py new file mode 100644 index 0000000..2ad1d2c --- /dev/null +++ b/restoran_max_bot/restoran_max_bot/bot_message.py @@ -0,0 +1,21 @@ +from max_bot.max_api import maxbot_send_text_message, maxbot_send_img_message, maxbot_send_menu_button +from max_bot.models import Client +from restoran_max_bot.common import common_get_data + + +def bot_message(client: Client, message: dict, settings: dict): + chat_id = message['message']['recipient']['chat_id'] + chat_type = message['message']['recipient']['chat_type'] + text = str(message['message']['body']['text']).lower() + data = common_get_data(client=client, key=text) + if data: + for dt in data: + if dt.img: + url = f"https://cdn.telefon-ip.ru/{dt.img}?thumb=600" + maxbot_send_img_message(chat_id=chat_id, max_token=settings['token'], img=url, message=dt.descr) + else: + maxbot_send_text_message(chat_id=chat_id, max_token=settings['token'], message=dt.descr) + # отправка меню + rs = maxbot_send_menu_button(chat_id=chat_id, max_token=settings['token'], message='test', buton=[]) + print(rs['data'].text) + return True diff --git a/restoran_max_bot/restoran_max_bot/bot_started.py b/restoran_max_bot/restoran_max_bot/bot_started.py new file mode 100644 index 0000000..6cc6787 --- /dev/null +++ b/restoran_max_bot/restoran_max_bot/bot_started.py @@ -0,0 +1,10 @@ +from max_bot.max_api import maxbot_send_text_message +from max_bot.models import Client + + +def bot_started(client: Client, message: dict, settings: dict): + chat_id = message['message']['recipient']['chat_id'] + chat_type = message['message']['recipient']['chat_type'] + text = str(message['message']['body']['text']).lower() + maxbot_send_text_message(chat_id=chat_id, max_token=settings['token'], message=text) + return True diff --git a/restoran_max_bot/restoran_max_bot/bot_stopped.py b/restoran_max_bot/restoran_max_bot/bot_stopped.py new file mode 100644 index 0000000..2d1b940 --- /dev/null +++ b/restoran_max_bot/restoran_max_bot/bot_stopped.py @@ -0,0 +1,10 @@ +from max_bot.max_api import maxbot_send_text_message +from max_bot.models import Client + + +def bot_stopped(client: Client, message: dict, settings: dict): + chat_id = message['message']['recipient']['chat_id'] + chat_type = message['message']['recipient']['chat_type'] + text = str(message['message']['body']['text']).lower() + maxbot_send_text_message(chat_id=chat_id, max_token=settings['token'], message=text) + return True diff --git a/restoran_max_bot/restoran_max_bot/common.py b/restoran_max_bot/restoran_max_bot/common.py new file mode 100644 index 0000000..016827b --- /dev/null +++ b/restoran_max_bot/restoran_max_bot/common.py @@ -0,0 +1,11 @@ +# функция поиска контента по ключевому слову +from max_bot.models import Client, ProductCategory, Product + + +def common_get_data(client: Client, key: str) -> Product: + product_category = ProductCategory.objects.filter(client=client, status=1, title=key, src=1).first() + if product_category: + data = Product.objects.filter(up=product_category.pk, status=1) + else: + data = None + return data