Внедрение яндекса

main
pilot639 7 hours ago
parent 5792993ca5
commit 5b7ad6da89

@ -4,3 +4,4 @@ mysqlclient
qrcode
django-environ
pillow
openai

@ -1,23 +1,43 @@
# api_common.py
import os
import json
import re
from datetime import datetime
from typing import Dict, Any, List
from max_bot.models import Client, ProductCategory, Product, Qr
from typing import Dict, Any, List, Optional
from django.core.cache import cache
from max_bot.models import Client, ProductCategory, Product, Qr, Partner, Integration
from restoran_max_bot import settings
# Кеш для базового промта
_BASE_PROMPT_CACHE = None
GLOBAL_ERROR_MSG = '⚠️ К сожалению, я не могу ответить на этот вопрос.'
AI_AGENT_REGISTRY = {
'yandexai': {
'slug': 'yandexai',
'module': 'api_yandex_ai',
'function': 'yandex_chat_structured',
'required_settings': ['yandex_folder_id'],
'default_model': 'yandexgpt',
},
'deepseek': {
'slug': 'deepseek',
'module': 'api_deepseek_ai',
'function': 'deepseek_chat_structured',
'required_settings': [],
'default_model': 'deepseek-chat',
},
}
def _log_dialogue(session_id: str, role: str, content: str, log_file: str = None) -> None:
"""
Записывает сообщение диалога в файл лога.
"""
if role.upper() == 'SYSTEM' and not getattr(settings, 'LOG_SYSTEM_PROMPT', False):
return
if log_file is None:
base_dir = os.path.dirname(os.path.abspath(__file__))
log_dir = os.path.join(base_dir, 'logs')
os.makedirs(log_dir, exist_ok=True)
log_file = os.path.join(log_dir, 'ai_dialogs.log') # общий лог для всех AI
log_file = os.path.join(log_dir, 'ai_dialogs.log')
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
log_entry = f"[{timestamp}] [{role.upper()}] [{session_id}]: {content}\n"
@ -31,7 +51,6 @@ def _log_dialogue(session_id: str, role: str, content: str, log_file: str = None
def _load_base_prompt() -> str:
"""Загружает базовый текст системного промта из файла."""
global _BASE_PROMPT_CACHE
if _BASE_PROMPT_CACHE is not None:
return _BASE_PROMPT_CACHE
@ -53,7 +72,11 @@ def _load_base_prompt() -> str:
def get_system_prompt(client: Client) -> str:
"""Генерирует системный промпт на основе данных клиента."""
cache_key = f"system_prompt_{client.id}"
cached = cache.get(cache_key)
if cached:
return cached
prompt = _load_base_prompt()
qr = Qr.objects.filter(client=client).first()
@ -89,34 +112,157 @@ def get_system_prompt(client: Client) -> str:
prompt += "\nМеню не загружено.\n"
prompt += """
При ответах на вопросы о меню используй только те блюда, которые перечислены выше.
Если клиент спрашивает о блюде, которого нет в списке, честно скажи об этом и предложи посмотреть другие позиции.
Всегда помни, что ты должен возвращать только JSON, без лишнего текста вне JSON.
"""
При ответах на вопросы о меню используй только те блюда, которые перечислены выше.
Если клиент спрашивает о блюде, которого нет в списке, честно скажи об этом и предложи посмотреть другие позиции.
Всегда помни, что ты должен возвращать только JSON, без лишнего текста вне JSON.
"""
cache.set(cache_key, prompt, 300)
return prompt
def parse_ai_response(assistant_content: str) -> Dict[str, Any]:
"""
Универсальный парсер для ответа AI (ожидается JSON с полями intent, message, entities, status).
Возвращает словарь с гарантированными ключами.
"""
content = re.sub(r'```(?:json)?\s*', '', assistant_content)
content = re.sub(r'\s*```', '', content)
content = content.strip()
try:
parsed = json.loads(assistant_content)
parsed = json.loads(content)
required = ["intent", "message", "entities", "status"]
if all(k in parsed for k in required):
return parsed
else:
return {
"intent": "general",
"message": assistant_content,
"message": content,
"entities": {},
"status": "complete"
}
except json.JSONDecodeError:
return {
"intent": "general",
"message": assistant_content,
"message": content,
"entities": {},
"status": "complete"
}
def get_ai_agent(client: Client) -> Dict[str, Optional[str]]:
for agent_slug, config in AI_AGENT_REGISTRY.items():
partner = Partner.objects.filter(slug=agent_slug).first()
if not partner:
continue
integration = Integration.objects.filter(
client=client,
partner=partner,
status=True
).first()
if integration:
try:
settings = json.loads(integration.setting) if integration.setting else {}
except json.JSONDecodeError:
settings = {}
required_settings = config.get('required_settings', [])
missing = [f for f in required_settings if f not in settings]
if missing:
_log_dialogue(str(client.id), 'ERROR',
f"AI agent {agent_slug} missing settings: {missing}")
continue
if not integration.token:
_log_dialogue(str(client.id), 'ERROR',
f"AI agent {agent_slug} missing token")
continue
result = {
'ai_agent': agent_slug,
'token': integration.token,
'client_prompt': settings.get('promt'),
'settings': settings,
}
if agent_slug == 'yandexai' and 'yandex_folder_id' in settings:
result['folder_id'] = settings['yandex_folder_id']
return result
return {
'ai_agent': None,
'token': None,
'client_prompt': None,
'settings': None,
'folder_id': None,
}
def call_ai_agent(client: Client, session_id: str, user_query: str) -> Dict[str, Any]:
agent_info = get_ai_agent(client)
ai_agent = agent_info.get('ai_agent')
if not ai_agent:
return {
"intent": "general",
"message": GLOBAL_ERROR_MSG,
"entities": {},
"status": "complete"
}
config = AI_AGENT_REGISTRY.get(ai_agent)
if not config:
return {
"intent": "general",
"message": f"Агент {ai_agent} не зарегистрирован.",
"entities": {},
"status": "complete"
}
try:
module = __import__(f"ai_agent.{config['module']}", fromlist=[config['function']])
func = getattr(module, config['function'])
except (ImportError, AttributeError) as e:
error_msg = f"Не удалось загрузить функцию для агента {ai_agent}: {e}"
_log_dialogue(session_id, 'ERROR', error_msg)
return {
"intent": "general",
"message": GLOBAL_ERROR_MSG,
"entities": {},
"status": "complete"
}
system_prompt = get_system_prompt(client)
client_prompt = agent_info.get('client_prompt')
if client_prompt:
system_prompt += f"\n\nДополнительная информация о ресторане:\n{client_prompt}"
kwargs = {
'session_id': session_id,
'system_prompt': system_prompt,
'user_query': user_query,
'api_token': agent_info.get('token'),
}
if ai_agent == 'yandexai':
folder_id = agent_info.get('folder_id')
if not folder_id:
return {
"intent": "general",
"message": "Ошибка конфигурации Yandex: не указан folder_id.",
"entities": {},
"status": "complete"
}
kwargs['folder_id'] = folder_id
# Можно задать модель из настроек или использовать default
model = agent_info.get('settings', {}).get('model', config.get('default_model', 'yandexgpt'))
kwargs['model'] = model
# Логируем вызов
_log_dialogue(session_id, 'DEBUG', f"Calling {ai_agent} with kwargs: {kwargs}")
try:
response = func(**kwargs)
return response
except Exception as e:
_log_dialogue(session_id, 'ERROR', f"Error calling {ai_agent}: {e}")
return {
"intent": "general",
"message": GLOBAL_ERROR_MSG,
"entities": {},
"status": "complete"
}
}

@ -1,7 +1,7 @@
# api_deepseek_ai.py
import requests
from typing import Dict, Any, List
from api_common import _log_dialogue, get_system_prompt, parse_ai_response
from ai_agent.api_common import _log_dialogue, parse_ai_response, GLOBAL_ERROR_MSG
# Хранилище контекстов для DeepSeek
_contexts: Dict[str, List[Dict[str, str]]] = {}
@ -55,7 +55,7 @@ def deepseek_chat_structured(
except requests.exceptions.HTTPError as e:
if e.response.status_code == 402:
user_message = "⚠️ К сожалению, я сейчас не могу отвечать на эти вопросы, попробуйте позже."
user_message = GLOBAL_ERROR_MSG
_log_dialogue(session_id, 'ERROR', f"Payment Required (402): {e}")
return {
"intent": "general",
@ -64,7 +64,7 @@ def deepseek_chat_structured(
"status": "complete"
}
else:
error_msg = "⚠️ Произошла ошибка при обращении к серверу. Попробуйте позже."
error_msg = GLOBAL_ERROR_MSG
_log_dialogue(session_id, 'ERROR', f"HTTP error: {e}")
return {
"intent": "general",
@ -73,7 +73,7 @@ def deepseek_chat_structured(
"status": "complete"
}
except Exception as e:
error_msg = "⚠️ Извините, произошла ошибка. Попробуйте позже."
error_msg = GLOBAL_ERROR_MSG
_log_dialogue(session_id, 'ERROR', f"DeepSeek error: {e}")
return {
"intent": "general",

@ -1,20 +1,19 @@
# api_yandex_ai.py
from typing import Dict, Any, List
from openai import OpenAI
from api_common import _log_dialogue, get_system_prompt, parse_ai_response
from ai_agent.api_common import _log_dialogue, parse_ai_response, GLOBAL_ERROR_MSG
# Хранилище контекстов для Yandex
_contexts: Dict[str, List[Dict[str, str]]] = {}
def yandex_chat_structured(
session_id: str,
api_key: str,
api_token: str,
folder_id: str,
system_prompt: str,
user_query: str,
model: str = "yandexgpt",
max_tokens: int = 1000,
model: str = "yandexgpt", # можно "yandexgpt-lite"
max_tokens: int = 500,
temperature: float = 0.3,
) -> Dict[str, Any]:
"""
@ -30,18 +29,21 @@ def yandex_chat_structured(
_contexts[session_id].append({"role": "user", "content": user_query})
try:
if not folder_id:
raise ValueError("folder_id is empty")
client = OpenAI(
api_key=api_key,
api_key=api_token,
base_url="https://ai.api.cloud.yandex.net/v1",
project=folder_id,
)
# Убираем response_format он может вызывать ошибку парсинга URI модели
response = client.chat.completions.create(
model=model,
messages=_contexts[session_id],
max_tokens=max_tokens,
temperature=temperature,
response_format={"type": "json_object"}
)
assistant_content = response.choices[0].message.content
@ -52,11 +54,11 @@ def yandex_chat_structured(
return parse_ai_response(assistant_content)
except Exception as e:
error_msg = "⚠️ Извините, произошла ошибка при обращении к Yandex GPT. Попробуйте позже."
error_msg = GLOBAL_ERROR_MSG
_log_dialogue(session_id, 'ERROR', f"Yandex GPT error: {e}")
return {
"intent": "general",
"message": error_msg,
"entities": {},
"status": "complete"
}
}

@ -50,21 +50,9 @@ def api_decorator(func):
settings_max = json.loads(integration.setting)
settings_max['token'] = integration.token
# проверка на интеграцию с максом
partner = Partner.objects.filter(slug='deepseek').first()
integration = Integration.objects.filter(client=client, partner=partner, status=True).first()
if not integration:
settings_deepseek = {'token': None, 'deepseek_system_prompt': None}
else:
deepseek_system_prompt = json.loads(integration.setting).get('system_prompt', None)
settings_deepseek = {'token': integration.token, 'deepseek_system_prompt': deepseek_system_prompt}
kwargs['client'] = client
kwargs['integration'] = integration
kwargs['settings_max'] = settings_max
kwargs['settings_deepseek'] = settings_deepseek
return func(*args, **kwargs)
return wrapper_api_decorator
@ -76,7 +64,6 @@ def api_start_max_v1(request, token, **kwargs):
data = json.loads(request.body.decode('utf-8'))
client = kwargs['client']
settings_max = kwargs['settings_max']
settings_deepseek = kwargs['settings_deepseek']
if DEBUG:
print(data)
@ -87,12 +74,10 @@ def api_start_max_v1(request, token, **kwargs):
# получение сообщения из бота
if data['update_type'] == 'message_created':
bot_message(client=client, message=data, settings_max=settings_max, settings_deepseek=settings_deepseek,
message_type='message_created')
bot_message(client=client, message=data, settings_max=settings_max, message_type='message_created')
if data['update_type'] == 'message_callback':
bot_message(client=client, message=data, settings_max=settings_max, settings_deepseek=settings_deepseek,
message_type='message_callback')
bot_message(client=client, message=data, settings_max=settings_max, message_type='message_callback')
# start - запуск бота
if data['update_type'] == 'bot_started':
@ -106,7 +91,7 @@ def api_start_max_v1(request, token, **kwargs):
return JsonResponse(rt, status=200)
#https://maxbot.telefon-ip.ru/max/iiko/webhook/71232b71-dacc-4586-95d0-0f352d9d09c3
# https://maxbot.telefon-ip.ru/max/iiko/webhook/71232b71-dacc-4586-95d0-0f352d9d09c3
@csrf_exempt
def iiko_webhook(request: WSGIRequest, token):
rt = {'success': False, 'data': ''}

@ -1,8 +1,9 @@
# bot_message.py
import re
from ai_agent.api_deepseek_ai import get_system_prompt, deepseek_chat_structured
from max_bot.max_api import *
import json
import qrcode
from ai_agent.api_common import get_system_prompt, get_ai_agent, call_ai_agent
from max_bot.max_api import *
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
@ -11,24 +12,24 @@ from restoran_max_bot.settings import STATICFILES_DIRS
from restoran_max_bot.utils import has_key, is_json
# отправка сообщения в группу администраторв по бронированию
def send_booking_to_crm(chat_id, date, time, people, contact):
# ---------- вспомогательные функции ----------
def send_booking_to_crm(chat_id, date, time, people, phone):
# TODO: реализовать отправку в CRM
return True
def send_contact_to_admin(chat_id, phone, contact_method, question, preferred_time, contact):
# TODO: реализовать отправку администратору
return True
# получение информации по интеграции с терминалом ikko, rkeeper
# ---------- получение бонусов ----------
def get_bonus(client: Client, phone: str, default_bonus: float, contact: Contact):
integration = common_get_integration(client=client)
bonus = 0
date = contact.field1
if len(date) < 2:
date = '0' + date
month = contact.field2
if len(month) < 2:
month = '0' + month
@ -39,23 +40,16 @@ def get_bonus(client: Client, phone: str, default_bonus: float, contact: Contact
customerinfo = customer_info(config['token'], phone, config['id_org'])
if not customerinfo:
birthday = f"1990-{month}-{date} 00:00:00.000"
dt = customer_create(api_key=config['token'], phone=phone, name=contact.name,
organization_id=config['id_org'], birthday=birthday)
dt = customer_info(config['token'], phone, config['id_org'])
customer_wallet(api_key=config['token'], iiko_wallet_id=dt['walletBalances'][0]['id'],
customer_id=dt['id'], organization_id=config['id_org'],
bonus=default_bonus)
bonus = default_bonus
else:
bonus = customerinfo['walletBalances']
bonus = bonus[0]['balance']
bonus = customerinfo['walletBalances'][0]['balance']
# http://192.168.9.186:8890/docs
if integration.partner.slug == 'rkeeper':
config = json.loads(integration.setting)
rs = rkiper_customer_info(rkiper_server=config['url'], rkiper_token=config['token'], phone=phone)
@ -72,26 +66,24 @@ def get_bonus(client: Client, phone: str, default_bonus: float, contact: Contact
return bonus
# получение вложения в сообщениях для их обработки (регистрация по номеру)
# ---------- получение вложений ----------
def get_attachments(message: dict):
chat_id = message['message']['recipient']['chat_id']
if 'attachments' in message['message']['body']:
if 'vcf_info' in message['message']['body']['attachments'][0]['payload']:
# Регулярное выражение: ищем всё после 'TEL;TYPE=cell:' до \r или конца строки
match = re.search(r'TEL;TYPE=cell:(\d+)',
message['message']['body']['attachments'][0]['payload']['vcf_info'])
if match:
phone_number = match.group(1)
return {'attachments_type': 'vcf_info', 'data': phone_number}
return {'attachments_type': False, 'data': ''}
def bot_message(client: Client, message: dict, settings_max: dict, settings_deepseek: dict, message_type):
# ---------- основной обработчик ----------
def bot_message(client: Client, message: dict, settings_max: dict, message_type):
chat_id = message['message']['recipient']['chat_id']
attachments = get_attachments(message=message)
# регистрируем по номеру телефона выдаем соответствующий контент
# регистрация по vcf
if attachments['attachments_type'] == 'vcf_info':
common_set_contact(client=client, uid_client=chat_id, name=message['message']['sender']['name'],
phone=attachments['data'])
@ -104,10 +96,11 @@ def bot_message(client: Client, message: dict, settings_max: dict, settings_deep
data = None
if message_type == 'message_created':
data = common_get_data(client=client, key=str(message['message']['body']['text']).lower())
if message_type == 'message_callback':
elif message_type == 'message_callback':
payload = json.loads(message['callback']['payload'])
data = common_get_data(client=client, key=str(payload['data']).lower())
# ---------- обработка стандартных команд (меню, бонусы и т.п.) ----------
if data:
for dt in data:
if dt.title == '##bonus##':
@ -116,28 +109,26 @@ def bot_message(client: Client, message: dict, settings_max: dict, settings_deep
url = f"https://maxbot.telefon-ip.ru/static/client_qr/{contact.phone}.png"
maxbot_send_img_message(chat_id=chat_id, max_token=settings_max['token'], img=url,
message='QR-код для начисления, списания бонусов.')
bonus = get_bonus(client=client, phone=contact.phone, default_bonus=float(dt.price), contact=contact)
maxbot_send_text_message(chat_id=chat_id, max_token=settings_max['token'],
message=f"💰 Ваш бонусный баланс: {bonus} руб")
if dt.title == '##feedback##':
maxbot_send_feedback_button(client=client, message='👇', chat_id=chat_id, max_token=settings_max['token'])
elif dt.title == '##feedback##':
maxbot_send_feedback_button(client=client, message='👇', chat_id=chat_id,
max_token=settings_max['token'])
return True
if dt.title == '##booking##':
elif dt.title == '##booking##':
maxbot_send_booking_count_people_button(client=client, message='👇',
chat_id=chat_id, max_token=settings_max['token'])
return True
# для более сложных функций
# сложные кнопки
if is_json(dt.title):
data = json.loads(dt.title)
if 'type' in dt.title:
if data['type'] == 'linkbutton':
maxbot_send_link_button(text=dt.descr, title_button=data['button'], link=dt.url,
chat_id=chat_id,
max_token=settings_max['token'])
data_json = json.loads(dt.title)
if 'type' in dt.title and data_json.get('type') == 'linkbutton':
maxbot_send_link_button(text=dt.descr, title_button=data_json['button'], link=dt.url,
chat_id=chat_id, max_token=settings_max['token'])
if dt.img:
url = f"https://cdn.telefon-ip.ru/{dt.img}?thumb=600"
@ -149,86 +140,79 @@ def bot_message(client: Client, message: dict, settings_max: dict, settings_deep
if dt.url and not is_json(dt.title):
maxbot_send_text_message(chat_id=chat_id, max_token=settings_max['token'], message=dt.url)
# отправка меню
maxbot_send_menu_button(chat_id=chat_id, max_token=settings_max['token'], message='👇 Выберите раздел',
client=client)
else:
# =========================== обработка сообщения через ИИ ===========================
if settings_deepseek.get('token', False):
text = message['message']['body']['text']
# Получаем системный промт из настроек
system_prompt = get_system_prompt(client)
if settings_deepseek.get('deepseek_system_prompt', False):
system_prompt = (system_prompt + "\n Дополнительная информация:\n" +
settings_deepseek.get('deepseek_system_prompt'))
# Отправляем запрос в DeepSeek
response = deepseek_chat_structured(
session_id=str(chat_id),
api_token=settings_deepseek.get('token'),
system_prompt=system_prompt,
user_query=text
)
intent = response.get('intent')
message_text = response.get('message', '')
entities = response.get('entities', {})
status = response.get('status', 'complete')
# Если общий вопрос — просто отвечаем
if intent == 'general':
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
elif intent == 'booking':
if status == 'need_more_info':
# Отправляем уточняющий вопрос
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
elif status == 'complete':
# Все данные собраны — передаём в CRM
date = entities.get('date')
time = entities.get('time')
people = entities.get('people')
phone = entities.get('phone')
if date and time and people:
# Вызываем функцию для отправки в CRM
success = send_booking_to_crm(chat_id, date, time, people, phone)
if success:
confirm_msg = f"✅ Бронирование на {date} в {time} на {people} чел. принято! " \
f"Администратор свяжется с вами для уточнения вопросов"
else:
confirm_msg = "Не удалось забронировать. Попробуйте позже."
maxbot_send_text_message(chat_id, settings_max['token'], confirm_msg)
else:
maxbot_send_text_message(chat_id, settings_max['token'], "⚠️ Не хватает данных для бронирования.")
return True
# ---------- обработка через AI ----------
# Проверяем, есть ли AI-агент у клиента
ai_agent = get_ai_agent(client)
if not ai_agent.get('ai_agent'):
maxbot_send_menu_button(chat_id=chat_id, max_token=settings_max['token'],
message='👇 Выберите раздел', client=client)
return True
# Вызываем AI-агента через универсальную функцию
response = call_ai_agent(
client=client,
session_id=str(chat_id),
user_query=message['message']['body']['text']
)
# ---------- обработка ответа AI ----------
intent = response.get('intent')
message_text = response.get('message', '')
entities = response.get('entities', {})
status = response.get('status', 'complete')
if intent == 'general':
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
elif intent == 'booking':
if status == 'need_more_info':
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
elif status == 'complete':
date = entities.get('date')
time = entities.get('time')
people = entities.get('people')
phone = entities.get('phone')
if date and time and people:
success = send_booking_to_crm(chat_id, date, time, people, phone)
if success:
confirm_msg = f"✅ Бронирование на {date} в {time} на {people} чел. принято! Администратор свяжется с вами."
else:
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
elif intent == 'contact_admin':
if status == 'need_more_info':
# Отправляем уточняющий вопрос
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
elif status == 'complete':
# Все данные собраны — передаём администратору
phone = entities.get('phone')
contact_method = entities.get('contact_method')
question = entities.get('question', '')
preferred_time = entities.get('preferred_time', '')
if phone and contact_method:
# Вызываем функцию отправки уведомления администратору
success = send_contact_to_admin(chat_id, phone, contact_method, question, preferred_time, contact)
if success:
confirm_msg = f"✅ Ваш запрос передан администратору. Способ связи: {contact_method}. Скоро с вами свяжутся."
else:
confirm_msg = "Не удалось отправить запрос. Попробуйте позже."
maxbot_send_text_message(chat_id, settings_max['token'], confirm_msg)
else:
maxbot_send_text_message(chat_id, settings_max['token'],
"⚠️ Не хватает данных для связи с администратором.")
confirm_msg = "Не удалось забронировать. Попробуйте позже."
maxbot_send_text_message(chat_id, settings_max['token'], confirm_msg)
else:
maxbot_send_text_message(chat_id, settings_max['token'], "⚠️ Не хватает данных для бронирования.")
else:
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
elif intent == 'contact_admin':
if status == 'need_more_info':
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
elif status == 'complete':
phone = entities.get('phone')
contact_method = entities.get('contact_method')
question = entities.get('question', '')
preferred_time = entities.get('preferred_time', '')
if phone and contact_method:
success = send_contact_to_admin(chat_id, phone, contact_method, question, preferred_time, contact)
if success:
confirm_msg = f"✅ Ваш запрос передан администратору. Способ связи: {contact_method}. Скоро с вами свяжутся."
else:
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
confirm_msg = "Не удалось отправить запрос. Попробуйте позже."
maxbot_send_text_message(chat_id, settings_max['token'], confirm_msg)
else:
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
maxbot_send_text_message(chat_id, settings_max['token'],
"⚠️ Не хватает данных для связи с администратором.")
else:
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
# После ответа отправляем меню (если нужно)
maxbot_send_menu_button(chat_id=chat_id, max_token=settings_max['token'],
message='👇 Выберите раздел', client=client)
else:
maxbot_send_text_message(chat_id, settings_max['token'], message_text)
# всегда отправляем меню после ответа
maxbot_send_menu_button(chat_id=chat_id, max_token=settings_max['token'],
message='👇 Выберите раздел', client=client)
return True

@ -125,3 +125,5 @@ STATICFILES_DIRS = [(os.path.join(BASE_DIR, "static"))]
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOG_SYSTEM_PROMPT = False # False - не логировать системный промт

Loading…
Cancel
Save