pilot 3 months ago
commit 24dd7f0af4

@ -0,0 +1,5 @@
Django~=5.2.13
requests
mysqlclient
qrcode
django-environ

@ -0,0 +1,22 @@
#!/usr/bin/env python
"""Django's command-line utility for administrative tasks."""
import os
import sys
def main():
"""Run administrative tasks."""
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'restoran_max_bot.settings')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == '__main__':
main()

@ -0,0 +1,3 @@
from django.contrib import admin
# Register your models here.

@ -0,0 +1,6 @@
from django.apps import AppConfig
class MaxBotConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'max_bot'

@ -0,0 +1,21 @@
import json
import requests
def maxbot_send_text_message(chat_id: str, max_token: str, message: str):
url = f"https://platform-api.max.ru/messages?chat_id={chat_id}"
payload = json.dumps({
"text": message
})
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

@ -0,0 +1,556 @@
from django.db import models
# Create your models here.
class Client(models.Model):
objects = None
title = models.CharField(max_length=300, blank=True)
title_full = models.CharField(max_length=300, blank=True)
token = models.CharField(max_length=255, blank=True)
status = models.BooleanField(default=True)
params = models.TextField(null=True)
type = models.IntegerField(null=True)
manager_id = models.IntegerField(null=True)
partner = models.BooleanField(null=True)
code = models.CharField(max_length=50, verbose_name='Код клиента в таблице cdr')
brand = models.CharField(max_length=300, verbose_name='Код клиента в таблице cdr')
logo = models.CharField(max_length=300)
email = models.CharField(max_length=50, blank=True)
server = models.CharField(max_length=200, verbose_name='сервер на котором работает клиент')
phone = models.CharField(max_length=12, blank=True)
dt = models.DateTimeField(auto_now_add=True)
managment = models.CharField(max_length=300)
tz = models.CharField(max_length=50, blank=True)
balancecontrol = models.FloatField(null=True)
promised_payment = models.DateTimeField(auto_now_add=True)
details = models.TextField(null=True)
class Meta:
db_table = 'lk_client'
class Billing(models.Model):
objects = None
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
submit_fd = models.DateTimeField(auto_now_add=True, verbose_name='Время начала действия записи')
submit_td = models.DateTimeField(verbose_name='Время завершения действия записи')
balance = models.FloatField(verbose_name='Баланс пользователя', default=10)
payment = models.FloatField(default=10)
class Meta:
db_table = 'lk_billing'
class BillingOrder(models.Model):
objects = None
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
paysys = models.CharField(max_length=100)
descr = models.CharField(max_length=300)
amount = models.FloatField()
status = models.SmallIntegerField()
error = models.CharField(max_length=100)
payment_id = models.CharField(max_length=100)
payment = models.TextField()
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Время начала действия записи')
updated_at = models.DateTimeField(verbose_name='Время завершения действия записи')
control_status = models.SmallIntegerField(blank=False)
class Meta:
db_table = 'lk_billing_order'
class AuthAccess(models.Model):
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Время начала действия записи')
ip_address = models.CharField(max_length=30, verbose_name='ip адрес сети')
ip_netmask = models.IntegerField(verbose_name='Маска подсети', default=32)
status = models.BooleanField(default=True, verbose_name='включен или нет')
class Meta:
db_table = 'au_access'
class AuthPhone(models.Model):
phone = models.CharField(max_length=11, verbose_name='Номер телефона для аутификации')
data_last = models.DateTimeField(auto_now_add=True, verbose_name='Время последнего использования', null=True)
code_auth = models.CharField(max_length=6, verbose_name='Код аутификации', null=True)
status = models.BooleanField(default=True, verbose_name='Включение номера')
operator = models.CharField(max_length=6, verbose_name='Оператор', null=True)
server = models.CharField(max_length=6, verbose_name='ссылка на сервер', null=True)
phone_type = models.CharField(max_length=20, verbose_name='Используется для определенного типа авторизации',
null=True)
counter = models.IntegerField(verbose_name='счетчик звонков', default=0)
device_info = models.CharField(max_length=255, verbose_name='ссылка на сервер', null=True)
device_prefix = models.CharField(max_length=255, verbose_name='ссылка на сервер', null=True)
call_error = models.IntegerField(verbose_name='счетчик ошибок', default=0)
call_limit = models.IntegerField(verbose_name='лимит запросов в день', default=0)
data_last_auth = models.DateTimeField(verbose_name='Время последнего использования обратной авторизации', null=True)
user_blocking = models.BooleanField(default=True, verbose_name='Включение номера')
creation_date = models.DateTimeField(auto_now_add=True)
closing_date = models.DateTimeField(auto_now_add=False)
class Meta:
db_table = 'au_phone'
class AuthLog(models.Model):
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Время создание записи')
auth_phone = models.ForeignKey(AuthPhone, verbose_name='Данные аутификации', on_delete=models.CASCADE, null=True)
code_auth = models.CharField(max_length=6, verbose_name='Код аутификации', null=True)
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
status = models.IntegerField(
verbose_name='Статус выполнения запроса 0 - не выполнен, 1 - отправлен на выполнение, 2 - подтвержден',
default=0)
status_info = models.CharField(max_length=200, null=True)
status_sms = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=11, null=True, verbose_name='Номер телефона которому отправлен код дозвона')
auth_billing = models.ForeignKey(Billing, verbose_name='Сылка на билинг', on_delete=models.CASCADE, null=True)
price = models.FloatField(verbose_name='Стоимость услуги', default=0)
uid = models.CharField(max_length=100, null=True, verbose_name='Индификатор отправки сообщения')
auth_type = models.CharField(max_length=11, null=True, verbose_name='Тип авторизации')
web_hook = models.TextField(null=True)
web_hook_status = models.TextField(null=True)
sms_send = models.BooleanField(verbose_name='Отправка смс если не прошел звонок')
operator = models.CharField(max_length=250, verbose_name='Имя оператора')
class Meta:
db_table = 'au_log'
class AuthPayment(models.Model):
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Время создание записи')
partner_id = models.IntegerField(verbose_name='Данные партнера')
payment = models.FloatField(verbose_name='Сумма платежа')
source = models.CharField(verbose_name='Источник платежа', max_length=10, default='api')
info = models.CharField(verbose_name='Дополнительная информация', max_length=500, null=True)
class Meta:
db_table = 'lk_payment'
class Users(models.Model):
objects = None
name = models.CharField(max_length=50, null=True)
avatar = models.CharField(max_length=300, null=True)
surname = models.CharField(max_length=50, null=True)
phone = models.CharField(max_length=11, null=True, default='89000000000', verbose_name='Номер телефона')
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
status = models.BooleanField(default=True, verbose_name='Включение номера')
role = models.IntegerField(default=2)
uid = models.CharField(max_length=50)
email = models.CharField(max_length=50)
passwd = models.CharField(max_length=100)
dt = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'lk_usr'
# Список контактов чате
class Contact(models.Model):
up = models.IntegerField()
group = models.IntegerField()
client = models.ForeignKey(to='Client', on_delete=models.PROTECT, verbose_name=' id client')
surname = models.CharField(max_length=100, null=True)
name = models.CharField(max_length=100, null=True)
patronymic = models.CharField(max_length=100, null=True)
phone = models.CharField(max_length=40, null=True)
telegram = models.CharField(max_length=100, null=True)
maxx = models.CharField(max_length=100, null=True)
status = models.IntegerField(default=1)
dt = models.DateTimeField(auto_now_add=True)
qr_menu = models.BooleanField(default=False)
webast_bot = models.BooleanField(default=False)
descr = models.CharField(max_length=500, null=True)
class Meta:
db_table = 'lk_contact'
class CdrRecord(models.Model):
objects = None
calldate = models.DateTimeField(null=True)
src = models.CharField(max_length=80, null=True)
dst = models.CharField(max_length=80, null=True)
billsec = models.IntegerField(default=0, null=True)
accountcode = models.CharField(max_length=20, null=True)
uniqueid = models.CharField(max_length=32)
disposition = models.CharField(max_length=45)
duration = models.IntegerField(null=True)
userfield = models.CharField(max_length=32)
dstchannel = models.CharField(max_length=80)
category_call = models.CharField(max_length=50)
send_sms = models.BooleanField()
filename = models.CharField(max_length=250)
channel = models.CharField(max_length=80)
lastdata = models.TextField()
lastapp = models.TextField()
class Meta:
db_table = 'cdr'
class QueueTime(models.Model):
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
src = models.CharField(max_length=20, verbose_name='Номер абонента')
dst = models.CharField(max_length=20, verbose_name='Номер агента')
calldate = models.DateTimeField(auto_now_add=True, verbose_name='Время записи')
billsec = models.IntegerField(verbose_name='Время ожидания', default=0)
agent_code = models.IntegerField(verbose_name='Время ожидания')
sla = models.IntegerField(
verbose_name='параметр качества обслуживания 10 - до 10 секунд, 15 - до 15 сек, 20, 30, 100 более 30 секунд',
default=0)
class Meta:
db_table = 'lk_queue_time'
class SmsConfig(models.Model):
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
user = models.CharField(max_length=40, verbose_name='Имя пользователя')
password = models.CharField(max_length=40, verbose_name='Пароль')
url = models.CharField(max_length=255, verbose_name='Ссылка')
type = models.CharField(max_length=10, verbose_name='тип рассылки')
params = models.CharField(max_length=255, verbose_name='Ссылка')
class Meta:
db_table = 'lk_sms_config'
class EmailBase(models.Model):
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Время создание записи')
email = models.CharField(max_length=11, verbose_name='email')
mac_address = models.CharField(max_length=20, blank=True, verbose_name='mac')
description = models.CharField(max_length=50, verbose_name='Дополнительная информация')
class Meta:
db_table = 'lk_emails'
class Operator(models.Model):
prefix = models.CharField(max_length=11, verbose_name='Префикс оператора сети')
operator = models.CharField(max_length=11, verbose_name='Оператор')
class Meta:
db_table = 'au_operator'
class DefCode(models.Model):
code_def = models.IntegerField()
code_from = models.IntegerField()
code_to = models.IntegerField()
container = models.IntegerField()
operator = models.CharField(max_length=255, verbose_name='Оператор')
inn = models.IntegerField()
region = models.CharField(max_length=255, verbose_name='Оператор')
class Meta:
db_table = 'au_defcode'
class Term(models.Model):
objects = None
up = models.IntegerField()
term = models.CharField(max_length=200)
val = models.CharField(max_length=100)
vali = models.IntegerField()
html = models.TextField()
params = models.TextField()
status = models.BooleanField()
dt = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'lk_term'
class App(models.Model):
objects = None
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
name = models.CharField(max_length=255)
param = models.TextField()
descr = models.CharField(max_length=255)
type = models.CharField(max_length=100)
status = models.SmallIntegerField()
dt = models.DateTimeField(auto_now_add=True, verbose_name='Время создание записи')
update_at = models.DateTimeField(verbose_name='Время обновления записи')
app = models.CharField(max_length=255, verbose_name='приложение обработки')
class Meta:
db_table = 'lk_app'
class Task(models.Model):
objects = None
app = models.ForeignKey(App, verbose_name='Сылка на приложение', on_delete=models.CASCADE)
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
name = models.CharField(max_length=255)
mess = models.TextField()
status = models.IntegerField()
prev_status = models.IntegerField()
reason = models.CharField(max_length=255)
priority = models.IntegerField()
dt_start = models.DateTimeField(auto_now_add=True, verbose_name='Время запуска приложения')
dt = models.DateTimeField(auto_now_add=True, verbose_name='Время создание записи')
class Meta:
db_table = 'lk_task'
class TaskDetail(models.Model):
objects = None
task = models.ForeignKey(Task, verbose_name='Сылка на приложение', on_delete=models.CASCADE)
contact = models.ForeignKey(Contact, verbose_name='Данные пользователя', on_delete=models.CASCADE)
subject = models.CharField(max_length=255)
mess = models.TextField()
cnt = models.IntegerField()
status = models.IntegerField()
reason = models.CharField(max_length=255)
dt = models.DateTimeField(verbose_name='Время создание записи')
update_at = models.DateTimeField(verbose_name='Время обновления записи')
external_id = models.CharField(max_length=255)
class Meta:
db_table = 'lk_task_detail'
class Price(models.Model):
objects = None
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
price = models.FloatField()
description = models.CharField(max_length=255)
service = models.CharField(max_length=255)
category = models.CharField(max_length=255)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Время начала действия записи')
class Meta:
db_table = 'lk_price'
class Partner(models.Model):
objects = None
name = models.CharField(max_length=100)
title = models.CharField(max_length=100)
logo = models.CharField(max_length=100)
descr = models.CharField(max_length=300)
status = models.IntegerField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
slug = models.CharField(max_length=30)
setting = models.TextField()
token_partner = models.CharField(max_length=50)
token_api = models.CharField(max_length=50)
application_id = models.IntegerField()
class Meta:
db_table = 'lk_integration_partner'
class Integration(models.Model):
objects = None
client = models.ForeignKey(Client, on_delete=models.CASCADE)
partner = models.ForeignKey(Partner, on_delete=models.CASCADE)
token = models.CharField(max_length=100)
setting = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
status = models.IntegerField()
updated_at = models.DateTimeField(auto_now=True)
partner_client = models.CharField(max_length=255)
class Meta:
db_table = 'lk_integration'
class SipTrunk(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
provider = models.CharField(max_length=50)
phone = models.CharField(max_length=50)
passwd = models.CharField(max_length=50)
status = models.BooleanField()
dt = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'lk_sip_trunk'
class Balance(models.Model):
objects = None
client = models.ForeignKey(to='Client', on_delete=models.PROTECT)
type = models.CharField(max_length=50)
accountcode = models.CharField(max_length=100)
domain = models.CharField(max_length=100)
login = models.CharField(max_length=50)
secret = models.CharField(max_length=100)
balance = models.FloatField()
status = models.IntegerField()
params = models.CharField(max_length=500)
description = models.CharField(max_length=500)
error = models.CharField(max_length=300)
dt = models.DateTimeField(auto_now_add=True)
informing_blocking = models.DateTimeField()
informing_balance = models.DateTimeField()
balance_save = models.FloatField()
class Meta:
db_table = 'lk_balance'
class SipPeer(models.Model):
objects = None
client = models.ForeignKey(to='Client', on_delete=models.PROTECT)
num = models.CharField(max_length=100)
secret = models.CharField(max_length=100)
ipaddress = models.CharField(max_length=100)
ipport = models.CharField(max_length=100)
accountcode = models.CharField(max_length=100)
description = models.CharField(max_length=100)
type = models.CharField(max_length=100)
status = models.BooleanField()
op_position = models.CharField(max_length=100)
op_fio = models.CharField(max_length=100)
op_email = models.CharField(max_length=100)
dt = models.DateTimeField(auto_now_add=True)
cfg_server = models.CharField(max_length=50)
cfg_port = models.CharField(max_length=10)
operator = models.CharField(max_length=100)
control_password = models.DateTimeField()
class Meta:
db_table = 'lk_sip_peer'
class BillingLog(models.Model):
objects = None
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
price = models.ForeignKey(Price, verbose_name='Данные пользователя', on_delete=models.CASCADE, null=True)
billing = models.ForeignKey(Billing, verbose_name='Данные пользователя', on_delete=models.CASCADE, null=True)
created_at = models.DateTimeField(verbose_name='Время начала действия записи')
accruals = models.FloatField()
function_init = models.CharField(max_length=255)
description = models.CharField(max_length=255)
class Meta:
db_table = 'lk_billing_log'
class SmsLog(models.Model):
objects = None
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Время создание записи')
phone = models.CharField(max_length=20, verbose_name='Номер телефона')
text = models.TextField(blank=True, verbose_name='Текст')
status = models.IntegerField(default=False, verbose_name='Статус')
status_info = models.CharField(max_length=300, blank=True, verbose_name='Информация о статусе')
uid = models.CharField(max_length=50, verbose_name='Индификатор сообщения от оператора')
price = models.FloatField()
provider = models.CharField(max_length=50, verbose_name='Индификатор сообщения от оператора')
user_answer = models.CharField(max_length=255, null=True, verbose_name='ответ на сообщение')
task = models.ForeignKey(Task, null=True, verbose_name='Данные пользователя', on_delete=models.CASCADE)
class Meta:
db_table = 'lk_sms_log'
class BillingService(models.Model):
objects = None
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True, verbose_name='Время начала действия записи')
updated_at = models.DateTimeField(auto_now=True, verbose_name='Дата проведения билинга')
price = models.ForeignKey(Price, on_delete=models.CASCADE)
status = models.IntegerField(default=True, verbose_name='Статус')
periodicity = models.CharField(max_length=255, verbose_name='Частотан начисления date, month')
app = models.ForeignKey(App, null=True, on_delete=models.CASCADE)
is_blocked = models.IntegerField(default=False, verbose_name='Статус блокировки услуги')
blocked_at = models.DateTimeField(auto_now=True, verbose_name='Дата блокировки')
class Meta:
db_table = 'lk_billing_service'
class SmsSession(models.Model):
sms_log = models.ForeignKey(SmsLog, verbose_name='Данные пользователя', on_delete=models.CASCADE)
submit_fd = models.DateTimeField(auto_now_add=True, verbose_name='Время создание записи')
submit_td = models.DateTimeField(verbose_name='Время создание записи')
phone = models.CharField(max_length=11, verbose_name='Номер телефона')
app = models.ForeignKey(App, on_delete=models.CASCADE)
class Meta:
db_table = 'lk_sms_session'
class SmsAnswer(models.Model):
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
app = models.ForeignKey(App, on_delete=models.CASCADE)
request = models.CharField(max_length=255, verbose_name='Номер телефона')
answer = models.TextField()
constantly = models.BooleanField(default=False)
class Meta:
db_table = 'lk_sms_answer'
class HotelBooking(models.Model):
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
uid = models.IntegerField()
arrival = models.DateTimeField()
departure = models.DateTimeField()
regdate = models.DateTimeField()
upddate = models.DateTimeField()
folio = models.BigIntegerField()
name = models.CharField(max_length=100)
phone = models.CharField(max_length=11)
email = models.CharField(max_length=50)
summa = models.FloatField()
uid_bitrix = models.IntegerField()
status_booking = models.IntegerField()
contact_id = models.BigIntegerField()
class Meta:
db_table = 'lk_hotel_booking'
class WP(models.Model):
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
host = models.CharField(max_length=100)
port = models.IntegerField()
session = models.CharField(max_length=50)
status = models.IntegerField()
created_at = models.DateTimeField()
updated_at = models.DateTimeField()
phone = models.CharField(max_length=50)
class Meta:
db_table = 'lk_whapsapp'
class DialplanConfig(models.Model):
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
webhook = models.CharField(max_length=255)
tg_send_contact = models.BooleanField
tg_send_missed = models.BooleanField
class Meta:
db_table = 'lk_sip_dialplan_config'
class ServerConfig(models.Model):
name = models.CharField(max_length=50)
server_type = models.CharField(max_length=10)
class Meta:
db_table = 'lk_sip_server'
class MessageTemplate(models.Model):
objects = None
client = models.ForeignKey(Client, verbose_name='Данные пользователя', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
type = models.CharField(max_length=100)
html = models.TextField()
params = models.JSONField()
app_id = models.IntegerField()
dt = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = 'vi_mess_template'

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

@ -0,0 +1,8 @@
from django.contrib import admin
from django.urls import path
from max_bot.views import api_start_max_v1
urlpatterns = [
path('api/v1/<str:token>', api_start_max_v1),
]

@ -0,0 +1,65 @@
import json
from django.http import JsonResponse
from max_bot.max_api import maxbot_send_text_message
from max_bot.models import Partner, Integration, Client
from restoran_max_bot.utils import is_json
def api_decorator(func):
def wrapper_api_decorator(*args, **kwargs):
# получаем информацию по токену клиента и делаем проверку
client = Client.objects.filter(token=kwargs['token']).first()
if not client:
rt = {'success': False, 'error': 'Unauthorized token', 'data': {}}
return JsonResponse(rt, status=401)
# проверяем заблокирован ли пользователь
if not client.status:
rt = {'success': False, 'error': 'client is blocked', 'data': {}}
return JsonResponse(rt, status=401)
# проверка на интеграцию с максом
partner = Partner.objects.filter(slug='max_bot').first()
integration = Integration.objects.filter(client=client, partner=partner, status=True).first()
if not integration:
rt = {'success': False, 'error': 'not found max bot integration', 'data': ''}
return JsonResponse(rt, status=404)
if not is_json(integration.setting):
rt = {'success': False, 'error': 'not found max bot settings', 'data': ''}
return JsonResponse(rt, status=404)
settings_max = json.loads(integration.setting)
kwargs['client'] = client
kwargs['integration'] = integration
kwargs['settings_max'] = settings_max
return func(*args, **kwargs)
return wrapper_api_decorator
@api_decorator
def api_start_max_v1(request, token, **kwargs):
data = json.loads(request.body.decode('utf-8'))
print(data)
client = kwargs['client']
settings_max = kwargs['settings_max']
# получение сообщения
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')
rt = {'success': True, 'error': '', 'data': ''}
return JsonResponse(rt, status=200)

@ -0,0 +1,16 @@
"""
ASGI config for restoran_max_bot project.
It exposes the ASGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.2/howto/deployment/asgi/
"""
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'restoran_max_bot.settings')
application = get_asgi_application()

@ -0,0 +1,122 @@
from pathlib import Path
from environ import environ
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
env = environ.Env()
env_file = f'{BASE_DIR}/.env'
env.read_env(env_file=env_file)
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
if str(env('DEBUG')).lower() == 'false':
DEBUG = False
else:
DEBUG = True
ALLOWED_HOSTS = ['*']
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'max_bot',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'restoran_max_bot.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'restoran_max_bot.wsgi.application'
# Database
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': env('DATABASE_NAME'),
'USER': env('DATABASE_USER'),
'PASSWORD': env('DATABASE_PASSWORD'),
'HOST': env('DATABASE_HOST'),
'PORT': env('DATABASE_PORT'),
'OPTIONS': {
'charset': 'utf8mb4',
'use_unicode': True, },
}
}
# Password validation
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/5.2/howto/static-files/
STATIC_URL = 'static/'
# Default primary key field type
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'

@ -0,0 +1,7 @@
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
# path('admin/', admin.site.urls),
path('max/', include('max_bot.urls'))
]

@ -0,0 +1,91 @@
import json
from datetime import datetime
def normalize_mobile_phone(phone: str) -> str:
"""
Приводит номер телефона к формату 7XXXXXXXXXX (11 цифр, начинается с 7).
Алгоритм:
1. Удаляет все нецифровые символы.
2. Если номер начинается с '8', заменяет на '7'.
3. Если начинается с '+7', убирает '+', оставляет '7'.
4. Если начинается с другой цифры (и не 8/7), добавляет '7' в начало.
5. Возвращает строку из 11 цифр, начинающуюся с 7.
Args:
phone (str): Исходный номер (может содержать пробелы, дефисы, скобки, + и т.п.).
Returns:
str: Нормализованный номер в формате 7XXXXXXXXXX.
"""
# Удаляем всё, кроме цифр
digits = ''.join(c for c in phone.strip() if c.isdigit())
if not digits:
return '7' + '0' * 10 # если цифр нет — возвращаем 70000000000
# Если начинается с 8 — заменяем на 7
if digits.startswith('8'):
digits = '7' + digits[1:]
# Если начинается с 7 — оставляем как есть
elif not digits.startswith('7'):
digits = '7' + digits # иначе добавляем 7 в начало
# Доводим до 11 цифр: если меньше — дополняем нулями справа; если больше — берём первые 11
if len(digits) < 11:
digits = digits.ljust(11, '0')
else:
digits = digits[:11]
return digits
def is_valid_datetime(text):
"""
Проверяет, соответствует ли строка формату %Y-%m-%dT%H:%M:%S.
:param text: строка для проверки
:return: bool True, если формат верный; False иначе
"""
try:
datetime.strptime(text, "%Y-%m-%dT%H:%M:%S")
return True
except (ValueError, TypeError):
return False
def has_key(json_data, key):
"""
Проверяет, есть ли указанный ключ в JSONобъекте (словаре).
:param json_data: dict или str (JSONстрока)
:param key: строка искомый ключ
:return: bool
"""
# Если на вход дана строка, преобразуем в словарь
if isinstance(json_data, str):
try:
json_data = json.loads(json_data)
except json.JSONDecodeError:
return False
return key in json_data
# проверяет json ли это
def is_json(myjson):
"""
Проверяет, является ли строка валидным JSON.
Args:
myjson (str): проверяемая строка
Returns:
bool: True, если строка валидный JSON, иначе False
"""
try:
json.loads(myjson)
except ValueError as e:
return False
return True

@ -0,0 +1,16 @@
"""
WSGI config for restoran_max_bot project.
It exposes the WSGI callable as a module-level variable named ``application``.
For more information on this file, see
https://docs.djangoproject.com/en/5.2/howto/deployment/wsgi/
"""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'restoran_max_bot.settings')
application = get_wsgi_application()
Loading…
Cancel
Save