From 1f3ed304714a5ba8b9d60db85c5a3224bde13923 Mon Sep 17 00:00:00 2001 From: pilot <657434@03b.ru> Date: Thu, 6 Aug 2026 22:51:32 +0800 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B2=D0=BE=D0=B6=D0=BC=D0=BE=D0=B6=D0=BD?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B8=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BA=D0=BD=D0=BE=D0=BF=D0=BA=D0=B8?= =?UTF-8?q?=20=D0=B1=D0=B5=D0=B7=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5=D0=BD?= =?UTF-8?q?=D1=82=D0=B0=20-=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=20=D1=83?= =?UTF-8?q?=D1=85=D0=BE=D0=B4=D0=B8=D1=82=20=D0=B2=20AI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Внедрение PROMO QR --- restoran_max_bot/max_bot/views.py | 9 ++- .../restoran_max_bot/bot_message.py | 77 ++++++++++--------- .../restoran_max_bot/bot_started.py | 12 +-- restoran_max_bot/restoran_max_bot/common.py | 2 +- 4 files changed, 57 insertions(+), 43 deletions(-) diff --git a/restoran_max_bot/max_bot/views.py b/restoran_max_bot/max_bot/views.py index f20441f..c51d5d3 100644 --- a/restoran_max_bot/max_bot/views.py +++ b/restoran_max_bot/max_bot/views.py @@ -8,7 +8,7 @@ from max_bot.max_api import maxbot_send_text_message from max_bot.models import Partner, Integration, Client, BonusTransaction, App 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.bot_message import bot_message, bot_promo from restoran_max_bot.common import common_get_contact from restoran_max_bot.settings import DEBUG from restoran_max_bot.utils import is_json, has_key @@ -72,6 +72,13 @@ def api_start_max_v1(request, token, **kwargs): rt = {'success': False, 'error': 'data update_type not found', 'data': ''} return JsonResponse(rt, status=200) + # обработчик промо кодов с запросов + # https://dev.max.ru/docs/chatbots/bots-coding/prepare + # https://max.ru/id032606883607_2_bot?start=source_site + if data.get("payload", None): + print(data['payload']) + bot_promo(client=client, message=data, settings_max=settings_max) + # получение сообщения из бота if data['update_type'] == 'message_created': bot_message(client=client, message=data, settings_max=settings_max, message_type='message_created') diff --git a/restoran_max_bot/restoran_max_bot/bot_message.py b/restoran_max_bot/restoran_max_bot/bot_message.py index b059a21..1ecae07 100644 --- a/restoran_max_bot/restoran_max_bot/bot_message.py +++ b/restoran_max_bot/restoran_max_bot/bot_message.py @@ -1,7 +1,7 @@ # bot_message.py import re import qrcode -from ai_agent.api_common import get_ai_agent, call_ai_agent, get_contact_meta, set_contact_meta, is_valid_name +from ai_agent.api_common import get_ai_agent, call_ai_agent, get_contact_meta from max_bot.max_api import * from restoran_max_bot.bot_started import check_registration from restoran_max_bot.common import * @@ -106,45 +106,14 @@ def bot_message(client: Client, message: dict, settings_max: dict, message_type) # ---------- проверка и запрос имени ---------- meta = get_contact_meta(contact) - real_name = meta.get('real_name') - name_asked = meta.get('name_asked', False) - - # Если имя ещё не запрашивали и нет реального имени - if not real_name and not name_asked: - # Проверяем имя, которое пришло из мессенджера (contact.name) - if is_valid_name(contact.name): - # Если валидное, сохраняем как реальное - set_contact_meta(contact, 'real_name', contact.name.strip()) - real_name = contact.name.strip() - else: - # Если невалидное — запрашиваем - maxbot_send_text_message(chat_id, settings_max['token'], - "Как мне к вам обращаться? Напишите ваше имя, чтобы я мог обращаться к вам лично.") - set_contact_meta(contact, 'name_asked', True) - # Завершаем обработку, ждём ответ - return True - - # Если имя уже запрашивали, но пользователь не ответил, а сейчас прислал сообщение - if name_asked and not real_name: - potential_name = message['message']['body']['text'].strip() - if is_valid_name(potential_name): - set_contact_meta(contact, 'real_name', potential_name) - real_name = potential_name - maxbot_send_text_message(chat_id, settings_max['token'], - f"Приятно познакомиться, {potential_name}! Чем могу помочь?") - # После приветствия продолжаем обработку (не завершаем) - else: - maxbot_send_text_message(chat_id, settings_max['token'], - "Пожалуйста, напишите ваше настоящее имя (от 2 символов).") - return True # ---------- обработка стандартных команд (меню, бонусы и т.п.) ---------- data = None if message_type == 'message_created': data = common_get_data(client=client, key=str(message['message']['body']['text']).lower()) elif message_type == 'message_callback': - payload = json.loads(message['callback']['payload']) - data = common_get_data(client=client, key=str(payload['data']).lower()) + data_payload = json.loads(message['callback']['payload']) + data = common_get_data(client=client, key=str(data_payload['data']).lower()) if data: for dt in data: @@ -188,6 +157,10 @@ def bot_message(client: Client, message: dict, settings_max: dict, message_type) maxbot_send_menu_button(chat_id=chat_id, max_token=settings_max['token'], message='👇 Выберите раздел', client=client) return True + else: + # если при нажатии на кнопку небыл найден контент, тогда для AI передаем имя кнопки + if message_type == 'message_callback': + message['message']['body']['text'] = str(data_payload['data']).lower() # ---------- обработка через AI ---------- # Проверяем, есть ли AI-агент у клиента @@ -197,12 +170,13 @@ def bot_message(client: Client, message: dict, settings_max: dict, message_type) message='👇 Выберите раздел', client=client) return True + real_name = contact.name.strip() # Вызываем AI-агента через универсальную функцию, передавая реальное имя response = call_ai_agent( client=client, session_id=str(chat_id), user_query=message['message']['body']['text'], - contact_name=real_name # передаём имя для персонализации + contact_name=real_name # передаём имя для персонализации ) # ---------- обработка ответа AI ---------- @@ -280,4 +254,35 @@ def bot_message(client: Client, message: dict, settings_max: dict, message_type) # всегда отправляем меню после ответа maxbot_send_menu_button(chat_id=chat_id, max_token=settings_max['token'], message='👇 Выберите раздел', client=client) - return True \ No newline at end of file + return True + + +def bot_promo(client: Client, message: dict, settings_max: dict): + chat_id = message['chat_id'] + promo = message['payload'].lower() + data = common_get_data(client=client, key=promo) + + if data: + # Генерация qr кода URL в параметрах телефон, промокод + url_promo = f"https://maxbot.telefon-ip.ru/promo/?promo={promo}&chat-id={chat_id}" + img = qrcode.make(url_promo) + file_name = f"{promo}-{chat_id}.png" + img.save(f"{STATICFILES_DIRS[0]}/client_qr/{file_name}") + url = f"https://maxbot.telefon-ip.ru/static/client_qr/{file_name}" + maxbot_send_img_message(chat_id=chat_id, max_token=settings_max['token'], img=url, + message='Ваш QR-код') + # Отправка данных + 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_max['token'], img=url, message=dt.descr) + + if dt.title: + maxbot_send_text_message(chat_id=chat_id, max_token=settings_max['token'], message=dt.descr) + + if dt.url: + maxbot_send_text_message(chat_id=chat_id, max_token=settings_max['token'], message=dt.url) + + # сохранение в meta информации о коде + # ПРОВЕРКА НА РЕГИСТРАЦИЮ ??? + return True diff --git a/restoran_max_bot/restoran_max_bot/bot_started.py b/restoran_max_bot/restoran_max_bot/bot_started.py index f585016..0cb8f30 100644 --- a/restoran_max_bot/restoran_max_bot/bot_started.py +++ b/restoran_max_bot/restoran_max_bot/bot_started.py @@ -16,12 +16,13 @@ def bot_started(client: Client, message: dict, settings: dict): else: maxbot_send_text_message(chat_id=chat_id, max_token=settings['token'], message=dt.descr) - # отправка меню - maxbot_get_phone(chat_id=chat_id, max_token=settings['token'], text='Согласен на обработку персональных данных.') + # запрос номера телефона + maxbot_get_phone(chat_id=chat_id, max_token=settings['token'], + text='Согласен на обработку персональных данных.') return True -# проверка есть ли регистрация клиента +# проверка есть ли регистрация клиента номер телефона def get_registration_phone(client: Client, chat_id: str, settings: dict): contact = common_get_contact(client=client, uid_client=chat_id) if not contact: @@ -41,7 +42,7 @@ def get_registration_phone(client: Client, chat_id: str, settings: dict): return contact -# проверка есть ли регистрация клиента +# проверка есть ли регистрация клиента день рождение def get_registration_birthday(client: Client, chat_id: str, settings: dict): contact = common_get_contact(client=client, uid_client=chat_id) if not contact: @@ -65,6 +66,7 @@ def get_registration_birthday(client: Client, chat_id: str, settings: dict): return contact +# проверка регистрации в боте (что все данные получены) def check_registration(client: Client, chat_id: str, message: dict, settings: dict): contact = get_registration_phone(client=client, chat_id=chat_id, settings=settings) if not contact: @@ -99,7 +101,7 @@ def check_registration(client: Client, chat_id: str, message: dict, settings: di message='system_reg_month') if not dt: maxbot_send_month_button(client=client, chat_id=chat_id, max_token=settings['token'], - message='👇 Выберите месяц') + message='👇 Выберите месяц') else: maxbot_send_month_button(client=client, chat_id=chat_id, max_token=settings['token'], message='👇') return False diff --git a/restoran_max_bot/restoran_max_bot/common.py b/restoran_max_bot/restoran_max_bot/common.py index cedbfd7..ed8eda0 100644 --- a/restoran_max_bot/restoran_max_bot/common.py +++ b/restoran_max_bot/restoran_max_bot/common.py @@ -9,7 +9,7 @@ from max_bot.models import Client, ProductCategory, Product, Contact, Integratio 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).order_by('id') + data = Product.objects.filter(up=product_category.pk, status=1, client=client).order_by('id') else: data = None return data