diff --git a/restoran_max_bot/max_bot/max_api.py b/restoran_max_bot/max_bot/max_api.py index ef6a3ae..ce029e8 100644 --- a/restoran_max_bot/max_bot/max_api.py +++ b/restoran_max_bot/max_bot/max_api.py @@ -1,12 +1,16 @@ import calendar import json +import os +from pathlib import Path import requests from max_bot.models import Client from restoran_max_bot.common import common_get_menu, common_get_data from restoran_max_bot.settings import DEBUG +BASE_DIR = Path(__file__).resolve().parent.parent +CACERT_PATH = os.path.join(BASE_DIR, 'cacert.pem') +max_verify = CACERT_PATH url_max = "https://platform-api2.max.ru" -max_verify = False def maxbot_send_text_message(chat_id: str, max_token: str, message: str): diff --git a/restoran_max_bot/max_bot/models.py b/restoran_max_bot/max_bot/models.py index b78cd4f..c172db3 100644 --- a/restoran_max_bot/max_bot/models.py +++ b/restoran_max_bot/max_bot/models.py @@ -644,6 +644,7 @@ class Qr(models.Model): class PromoCode(models.Model): + objects = None client = models.ForeignKey(Client, on_delete=models.CASCADE) promo = models.CharField(max_length=50, unique=True) chat_id = models.CharField(max_length=50) diff --git a/restoran_max_bot/max_bot/views.py b/restoran_max_bot/max_bot/views.py index 373bae5..8236997 100644 --- a/restoran_max_bot/max_bot/views.py +++ b/restoran_max_bot/max_bot/views.py @@ -12,6 +12,7 @@ from restoran_max_bot.bot_message import bot_message, bot_promo from restoran_max_bot.common import common_get_contact, common_check_registration from restoran_max_bot.settings import DEBUG from restoran_max_bot.utils import is_json, has_key +from django.shortcuts import render def api_decorator(func): @@ -61,6 +62,7 @@ def api_decorator(func): @csrf_exempt @api_decorator def api_start_max_v1(request, token, **kwargs): + # основной обработчик MAX-БОТ data = json.loads(request.body.decode('utf-8')) client = kwargs['client'] settings_max = kwargs['settings_max'] @@ -137,58 +139,22 @@ def iiko_send_message(request: WSGIRequest, token): return JsonResponse(rt, status=200) -def promo_status(request, promo_code, chat_id): +def promo_status(request, promo_code, chat_id, client_id): try: - promo = PromoCode.objects.get(promo=promo_code, chat_id=chat_id) + promo = PromoCode.objects.get( + promo=promo_code, + chat_id=chat_id, + client_id=client_id + ) except PromoCode.DoesNotExist: - return HttpResponse("Промокод не найден для данного чата", status=404) - - # Если промокод уже использован, просто показываем статус - if promo.used: - html = f""" - -
-ID чата: {promo.chat_id}
-Статус: Использован
-Время использования: {promo.used_at}
- - - """ - return HttpResponse(html) - - # Если не использован, показываем кнопку с запросом PIN-кода - html = f""" - - -ID чата: {promo.chat_id}
-Статус: Не использован
- - - - - """ - return HttpResponse(html) + return HttpResponse("Промокод не найден", status=404) + + context = {'promo': promo} + return render(request, 'max_bot/promo_status.html', context) + @csrf_exempt -def promo_activate(request, promo_code, chat_id): +def promo_activate(request, promo_code, chat_id, client_id): if request.method != 'POST': return JsonResponse({'error': 'Method not allowed'}, status=405) @@ -202,7 +168,12 @@ def promo_activate(request, promo_code, chat_id): return JsonResponse({'error': 'Неверный PIN-код'}, status=403) try: - promo = PromoCode.objects.get(promo=promo_code, chat_id=chat_id, used=False) + promo = PromoCode.objects.get( + promo=promo_code, + chat_id=chat_id, + client_id=client_id, + used=False + ) except PromoCode.DoesNotExist: return JsonResponse({'error': 'Промокод не найден или уже использован'}, status=404) @@ -210,13 +181,12 @@ def promo_activate(request, promo_code, chat_id): promo.used_at = datetime.now() promo.save() - # Отправляем уведомление клиенту integration = Integration.objects.filter(client=promo.client, partner__slug='max_bot', status=True).first() if integration: maxbot_send_text_message( chat_id=promo.chat_id, max_token=integration.token, - message="🎉 Ваш подарок активирован! Спасибо, что посетили нас." + message="🎉 Ваш QR код активирован! Спасибо, что посетили нас!" ) - return JsonResponse({'success': True, 'message': 'Промокод активирован, клиент получил уведомление'}) \ No newline at end of file + return JsonResponse({'success': True, 'message': 'Промокод активирован, клиент получил уведомление'}) diff --git a/restoran_max_bot/restoran_max_bot/bot_message.py b/restoran_max_bot/restoran_max_bot/bot_message.py index 01048f2..28eaeb3 100644 --- a/restoran_max_bot/restoran_max_bot/bot_message.py +++ b/restoran_max_bot/restoran_max_bot/bot_message.py @@ -3,11 +3,12 @@ import re import qrcode from ai_agent.api_common import get_ai_agent, call_ai_agent, get_contact_meta from max_bot.max_api import * +from max_bot.models import PromoCode from restoran_max_bot.bot_started import check_registration from restoran_max_bot.common import * from restoran_max_bot.iiko_api import customer_info, customer_create, customer_wallet from restoran_max_bot.rkiper_api import rkiper_customer_info, rkiper_customer_create -from restoran_max_bot.settings import STATICFILES_DIRS +from restoran_max_bot.settings import STATICFILES_DIRS, BASE_URL from restoran_max_bot.utils import has_key, is_json @@ -257,58 +258,70 @@ def bot_message(client: Client, message: dict, settings_max: dict, message_type) return True -from max_bot.models import PromoCode - def bot_promo(client: Client, message: dict, settings_max: dict): chat_id = message['chat_id'] promo = message['payload'].lower() messenger = 'max-bot' + client_id = client.id + + # Проверяем, существует ли промокод в системе (через common_get_data) + data = common_get_data(client=client, key=promo) + if not data: + # Если промокод не заведён – ничего не отправляем (скрываем факт) + return True - # Создаём запись, используя пару (promo, chat_id) как уникальный ключ + # Пытаемся найти или создать запись в БД promo_obj, created = PromoCode.objects.get_or_create( promo=promo, chat_id=chat_id, + client=client, defaults={ - 'client': client, 'messenger': messenger, 'used': False, } ) - if not created and promo_obj.used: - maxbot_send_text_message( - chat_id=chat_id, - max_token=settings_max['token'], - message="⚠️ Этот промокод уже был получен вами." - ) + # Если запись уже существовала + if not created: + if promo_obj.used: + # Уже использован – уведомляем + maxbot_send_text_message( + chat_id=chat_id, + max_token=settings_max['token'], + message="⚠️ Этот промокод уже был использован." + ) + else: + # QR-код уже был отправлен ранее – напоминаем + maxbot_send_text_message( + chat_id=chat_id, + max_token=settings_max['token'], + message="ℹ️ QR-код уже был отправлен." + ) return True - # Формируем ссылку с обоими параметрами - base_url = "https://maxbot.telefon-ip.ru/promo/status/" - url_promo = f"{base_url}{promo}/{chat_id}" - - # Генерируем QR-код + # Если запись создана впервые – генерируем QR-код + base_url = f"{BASE_URL}/promo/status/" + url_promo = f"{base_url}{promo}/{chat_id}/{client_id}" img = qrcode.make(url_promo) - file_name = f"{promo}-{chat_id}.png" + file_name = f"{promo}-{chat_id}-{client_id}.png" img.save(f"{STATICFILES_DIRS[0]}/client_qr/{file_name}") - qr_url = f"https://maxbot.telefon-ip.ru/static/client_qr/{file_name}" + qr_url = f"{BASE_URL}/static/client_qr/{file_name}" + maxbot_send_img_message( chat_id=chat_id, max_token=settings_max['token'], img=qr_url, - message='Ваш QR-код для получения подарка. Покажите его администратору.' + message='Ваш QR-код.' ) - # Отправка дополнительного контента (если есть) - data = common_get_data(client=client, key=promo) - if data: - for dt in data: - if dt.img: - 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=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) + # Отправляем дополнительный контент, если есть + for dt in data: + if dt.img: + 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=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) return True \ No newline at end of file diff --git a/restoran_max_bot/restoran_max_bot/settings.py b/restoran_max_bot/restoran_max_bot/settings.py index 7eee3cf..18cc9a3 100644 --- a/restoran_max_bot/restoran_max_bot/settings.py +++ b/restoran_max_bot/restoran_max_bot/settings.py @@ -21,6 +21,11 @@ if str(env('DEBUG')).lower() == 'false': else: DEBUG = True +if DEBUG: + BASE_URL = "https://home.telefon-ip.ru" +else: + BASE_URL = "https://maxbot.telefon-ip.ru" + ALLOWED_HOSTS = ['*'] @@ -53,7 +58,7 @@ ROOT_URLCONF = 'restoran_max_bot.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], + 'DIRS': [BASE_DIR / 'templates'], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ @@ -127,4 +132,4 @@ STATICFILES_DIRS = [(os.path.join(BASE_DIR, "static"))] DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' LOG_SYSTEM_PROMPT = False # False - не логировать системный промт -PROMO_ADMIN_PIN = os.environ.get('PROMO_ADMIN_PIN', '1111') \ No newline at end of file +PROMO_ADMIN_PIN = os.environ.get('PROMO_ADMIN_PIN', '1111') diff --git a/restoran_max_bot/restoran_max_bot/urls.py b/restoran_max_bot/restoran_max_bot/urls.py index 765521d..f71d750 100644 --- a/restoran_max_bot/restoran_max_bot/urls.py +++ b/restoran_max_bot/restoran_max_bot/urls.py @@ -7,6 +7,6 @@ urlpatterns = [ # path('admin/', admin.site.urls), path('max/', include('max_bot.urls')), path('content/', include('content_bot.urls')), - path('promo/status/