проект HR_bot
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
.venv/
|
||||
тест.py
|
||||
Generated
+3
@@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
Generated
+10
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
Generated
+7
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.8 (Bot_for_clinic)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8 (Bot_for_clinic)" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
Generated
+8
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/Bot_for_clinic.iml" filepath="$PROJECT_DIR$/.idea/Bot_for_clinic.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"type": "service_account",
|
||||
"project_id": "botforclinic-436512",
|
||||
"private_key_id": "0c117dd103a890d20705d9e66bbfde56f9d65a05",
|
||||
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC4XOtHBzxPR4lb\nqiX8grd2XBfBxXZLgLKTkz4WRcncgBpACXKms5AtKF707uKCvgUD8SwTpzvfY3oz\nvzLQs0uZoM9RALw5ui9dlimdoYQGsuH5LAUX68w0oPyour36XeBqacxNoEeO5C2F\nbb4+ql4gC2qJT86aBt2kwKpTxnTPZxvYoKZ0TwsmN8gj9vNckONbSSZteMKpQA50\nRqpoLM0EpsB64HRSiu8mH+bkdLK9ZMEZGmOG7pNDijctGkgAy9rK9vurH4PRgIMt\n7j+q/EeBQDuZX2SSVIaMkiFkDhHVGd84CFzcodBIYOSiCDer7aIcv8SrcYGZ0QJD\nnIzTqZMrAgMBAAECggEAW3HHR2dI3D/s2xkVl15U1nHOXM/vIXsX2EgH2y9JdUPb\nAVlOU24sPKHSG6YjltrejPqCNMtV0LM8SU90Sn0sKerP+esl8XIujTpusN+Mp2/x\n0tApRJiyJIaXW6+ojHck2VNZwUUXSUJXa9+npdiGMFnJQYtivBZcuJvRwBTnGnm/\ntuwQUcQREPy8IaaX5j+xPf390KeXqNOopULW7FtItkHthM18fr6706X1GQ77ua23\nzz1DT2PfIxOu2e3uPJ1O1CsQ8UiTIAm3J0nNgbpau1nP2+ea62vCrjmuqcyn5dfb\nhpgGD7Qe8uRvU+EICr67sOW47ikjAqkM38lZFgufuQKBgQDmypfFTYke7oDTZ8GE\nZFHZKn+ri5s94pDzjeeb8HxmeEC85cA6+jOr6f1QncwHON+tD2FRO7HHp/yVVyZY\nU2RSxaLaFleRL4CwlQkiMoqynLFWbqQthqdeJx2onNyGoO8uBDqfMJVBhOjwb8jI\n3SZt1Z6BJ076CMMOiLI7moZsWQKBgQDMgBdWND+uTR0SHXWqF1hj/+UgwHBqQKio\nyWbnIO28uFyMscfBAgh7JJbqcJIh6A+M9NdD4TveqZWoYBaUHkMBg5VGcmWrCH+L\nJOlAVJmhy4GgpE2nkYE0ZgDd0qlViYeTOKaLSKchPrLxRKNI9eeWkKqrk/a7wBHh\nsGJbt8p7IwKBgQCvFYaqAbZCpwFIX/ApNcn6DAmq5FAzVIxOmJrabEiTnCrQoyOA\nGovUocCwxeUgnX7i1UYo0DaAlupBiUnnu+vh91kiRczMsdLZI1c4gEtEUScfwPQA\nLaUPAnG3lrid0b1hlYe7eKnieKgWr1cNOuiKboK+zElX2gnQHtfH6+SKkQKBgDYW\nsxVz4FwDvWqrLBH+9rwMVNgizhjsXS+3hWYgiYDe6mu0IfdkyEV52gjMGXqqXGKV\n59HmYuVzyUetkos+rc5atULawxVHvCRbcO448iGfJ/wLORbXH2tyh0wkifE73QYN\nd89jOgFLCh1SYDXOBKEIRnv3OM1T8ebVtk44AHAtAoGAfOprlkWEDyVnfHQjGxxx\nTrxhEAjw3+ikM+wQJj7vumnpg91eAFNcwRUa/ykbVOmj6z/fBnStAbsG7mMQwa1M\nyIVPTvUogrsTHvf9GaG0IaAVJn/Su2DVNqQeL/ZpDmu2+wC959g8z665BKLzm3S8\nFc0eV1a7FN4GOpKNvXuDMBc=\n-----END PRIVATE KEY-----\n",
|
||||
"client_email": "clinic-chats-bot@botforclinic-436512.iam.gserviceaccount.com",
|
||||
"client_id": "105253150604049743778",
|
||||
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
|
||||
"token_uri": "https://oauth2.googleapis.com/token",
|
||||
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
|
||||
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/clinic-chats-bot%40botforclinic-436512.iam.gserviceaccount.com",
|
||||
"universe_domain": "googleapis.com"
|
||||
}
|
||||
@@ -0,0 +1,442 @@
|
||||
from googleapiclient.discovery import build
|
||||
from google.oauth2.service_account import Credentials
|
||||
import asyncio
|
||||
from aiogram.types import WebAppInfo
|
||||
import logging
|
||||
from aiogram import Bot, Dispatcher, types
|
||||
from aiogram.utils import executor
|
||||
from aiogram.types import ChatType
|
||||
from aiogram.utils.exceptions import BadRequest
|
||||
from aiogram.types import ReplyKeyboardMarkup, KeyboardButton
|
||||
from aiogram.utils.exceptions import MessageCantBeDeleted
|
||||
import gspread
|
||||
from datetime import datetime
|
||||
from google.oauth2 import service_account
|
||||
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton, WebAppInfo, ReplyKeyboardMarkup, KeyboardButton
|
||||
import sentry_sdk
|
||||
|
||||
|
||||
|
||||
sentry_sdk.init(
|
||||
dsn="https://697d3f2b6cb54a78202eeae0cb8c1f65@sentry.pirogov.ai/15",
|
||||
# Set traces_sample_rate to 1.0 to capture 100%
|
||||
# of transactions for performance monitoring.
|
||||
traces_sample_rate=1.0,
|
||||
)
|
||||
|
||||
|
||||
# Настройки бота
|
||||
API_TOKEN = '7414018470:AAGYF77aCd1BQpRnf38ys05ijkYJ25sNBuU'
|
||||
ADMIN_ID = 766945900 # ID администратора, которому будет приходить уведомление
|
||||
SPREADSHEET_ID = '128R3An6fb2PFGlzYMKb4SvEaSYCWUHHFVvial7llGno' # ID вашей Google Таблицы
|
||||
RANGE_NAME = 'Лист1!A1:O' # Диапазон данных в таблице
|
||||
CHAT_IDS = [-1002306913175, -1002266505101] # Замените на ID чатов, где бот администратор
|
||||
|
||||
# Логирование
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
bot = Bot(token=API_TOKEN)
|
||||
dp = Dispatcher(bot)
|
||||
|
||||
# Настройки для Google Sheets API
|
||||
SCOPES = ['https://www.googleapis.com/auth/spreadsheets']
|
||||
SERVICE_ACCOUNT_FILE = 'botforclinic-436512-0c117dd103a8.json'
|
||||
|
||||
credentials = Credentials.from_service_account_file(SERVICE_ACCOUNT_FILE, scopes=SCOPES)
|
||||
service = build('sheets', 'v4', credentials=credentials)
|
||||
|
||||
# Настройка API для работы с документами
|
||||
SCOPES = ['https://www.googleapis.com/auth/documents', 'https://www.googleapis.com/auth/drive']
|
||||
SERVICE_ACCOUNT_FILE = 'botforclinic-436512-0c117dd103a8.json'
|
||||
|
||||
credentials = service_account.Credentials.from_service_account_file(
|
||||
SERVICE_ACCOUNT_FILE, scopes=SCOPES)
|
||||
|
||||
docs_service = build('docs', 'v1', credentials=credentials)
|
||||
drive_service = build('drive', 'v3', credentials=credentials)
|
||||
|
||||
# Идентификатор Google Документа (шаблона трудового договора)
|
||||
TEMPLATE_DOC_ID = '1xi4YiPNBEDvODS0SaVb0wgKZ_b_OBkas'
|
||||
|
||||
# Словарь для хранения сотрудников, которых уже обработали
|
||||
known_employees = set()
|
||||
|
||||
def create_contract_google(employee_data):
|
||||
# Копирование шаблона
|
||||
file_metadata = {
|
||||
'name': f"ТД_{employee_data[0]}_{datetime.now().strftime('%Y%m%d%H%M%S')}",
|
||||
'mimeType': 'application/vnd.google-apps.document',
|
||||
'parents': ['1fyA5btnwCQC-juE40T-uLSVHVIB-I2Ny']
|
||||
}
|
||||
copied_file = drive_service.files().copy(
|
||||
fileId=TEMPLATE_DOC_ID, body=file_metadata).execute()
|
||||
document_id = copied_file['id']
|
||||
|
||||
# Замены текста в шаблоне
|
||||
replacements = {
|
||||
"{{ФИО}}": employee_data[0],
|
||||
"{{Серия паспорта}}": employee_data[3],
|
||||
"{{Номер паспорта}}": employee_data[4],
|
||||
"{{Кем выдан}}": employee_data[5],
|
||||
"{{Дата выдачи}}": employee_data[6],
|
||||
"{{Адрес}}": employee_data[8],
|
||||
"{{Дата рождения}}": employee_data[12],
|
||||
"{{ИНН}}": employee_data[11],
|
||||
"{{СНИЛС}}": employee_data[10],
|
||||
}
|
||||
|
||||
requests = [{"replaceAllText": {
|
||||
"containsText": {"text": key, "matchCase": True},
|
||||
"replaceText": value
|
||||
}} for key, value in replacements.items()]
|
||||
|
||||
docs_service.documents().batchUpdate(
|
||||
documentId=document_id, body={'requests': requests}).execute()
|
||||
|
||||
return f"https://docs.google.com/document/d/{document_id}/edit"
|
||||
|
||||
|
||||
|
||||
# Словарь с соответствием специальности и ссылки на чат
|
||||
specialty_chat_links = {
|
||||
"Врачи": "https://t.me/botclinic",
|
||||
"Медсёстры": "https://t.me/+DcZn0yBO0RFjZTY6",
|
||||
"Санитарки": "https://t.me/joinchat/{chat_id_orderlies}",
|
||||
"Администраторы": "https://t.me/joinchat/{chat_id_admins}",
|
||||
"Операторы КЦ": "https://t.me/joinchat/{chat_id_operators}",
|
||||
"АУП": "https://t.me/joinchat/{chat_id_aap}"
|
||||
}
|
||||
|
||||
|
||||
# Функция для отправки сообщения о новом сотруднике с клавиатурой для выбора специальности
|
||||
async def notify_admin_about_new_employee(entry):
|
||||
full_name = entry[0] if entry else "Без имени"
|
||||
new_employee_id = entry[13] if len(entry) > 13 else None
|
||||
|
||||
if new_employee_id:
|
||||
# Отправляем уведомление админу о новом сотруднике с клавишами выбора специальности
|
||||
keyboard = create_employee_keyboard()
|
||||
|
||||
await bot.send_message(
|
||||
ADMIN_ID,
|
||||
f"Зарегистрирован новый сотрудник: {full_name}\nTelegram ID сотрудника: {new_employee_id}",
|
||||
reply_markup=keyboard
|
||||
)
|
||||
else:
|
||||
logging.error("Не удалось найти Telegram ID сотрудника.")
|
||||
|
||||
|
||||
# Функция для проверки новых сотрудников
|
||||
async def check_for_new_entries():
|
||||
sheet = service.spreadsheets()
|
||||
|
||||
while True:
|
||||
try:
|
||||
result = sheet.values().get(spreadsheetId=SPREADSHEET_ID, range=RANGE_NAME).execute()
|
||||
values = result.get('values', [])
|
||||
except Exception as e:
|
||||
logging.error(f"Ошибка при чтении таблицы: {e}")
|
||||
await asyncio.sleep(30) # Ждем перед следующей попыткой
|
||||
continue
|
||||
|
||||
# Проверяем каждую запись на наличие нового сотрудника
|
||||
for entry in values:
|
||||
full_name = entry[0] if entry else "Без имени"
|
||||
new_employee_id = entry[13] if len(entry) > 13 else None # Telegram ID сотрудника
|
||||
|
||||
if full_name and full_name not in known_employees:
|
||||
known_employees.add(full_name)
|
||||
|
||||
# Генерация трудового договора
|
||||
try:
|
||||
contract_url = create_contract_google(entry)
|
||||
|
||||
# Уведомление для администратора
|
||||
await bot.send_message(
|
||||
ADMIN_ID,
|
||||
f"Зарегистрирован новый сотрудник: {full_name}\nТрудовой договор: {contract_url}",
|
||||
)
|
||||
|
||||
# Уведомление для сотрудника
|
||||
if new_employee_id:
|
||||
welcome_message = f"Большое спасибо! Мы получили данные для заключения трудового договора с вами."
|
||||
await bot.send_message(
|
||||
new_employee_id,
|
||||
welcome_message,
|
||||
)
|
||||
|
||||
# Оповещаем админа и отправляем клавиатуру для выбора специальности
|
||||
await notify_admin_about_new_employee(entry)
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Ошибка при создании трудового договора: {e}")
|
||||
await bot.send_message(ADMIN_ID, "Произошла ошибка при создании трудового договора.")
|
||||
|
||||
await asyncio.sleep(10) # Проверяем таблицу каждые 10 секунд
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Функция отправки сообщения о прохождении инструктажа
|
||||
async def send_fire_safety_instructions(employee_id, full_name, employee_data):
|
||||
message_text = f"""
|
||||
{full_name}, добрый день. Вы приглашены на корпоративный канал Клиники в Telegram. В закрепленном сообщении на этом канале Вы сможете ознакомиться с такими разделами:
|
||||
|
||||
👉[Наши сотрудники](https://t.me/c/1414064442/5) - актуальный список всех сотрудников Клиники;
|
||||
👉[Контакты сотрудников](https://t.me/c/1414064442/39) - номера телефонов сотрудников для скачивания в телефонную книгу;
|
||||
👉[История клиники](https://t.me/c/1414064442/6)
|
||||
👉[Структура рабочих чатов](https://t.me/c/1414064442/10)
|
||||
👉[Инструктаж по пожарной безопасности в Клинике ухо, горло, нос](https://disk.yandex.ru/i/i1k41Z2SznfpOA)
|
||||
👉[Обратная связь](https://forms.gle/Dfjrb8K1NzzjmW5j7) - оставить предложение, пожелание или задать вопрос руководству (анонимно).
|
||||
|
||||
**ВАЖНО:**
|
||||
В разделе [Инструктаж по пожарной безопасности в Клинике ухо, горло, нос](https://disk.yandex.ru/i/i1k41Z2SznfpOA) Вам необходимо изучить материалы по Пожарной безопасности, уделить особое внимание теме - порядок действий и по каким номерам звонить в случае пожароопасной ситуации.
|
||||
|
||||
После этого пройти тестирование по данной теме (21 вопрос - зачет 70% правильных ответов):
|
||||
👉[Тестирование по пожарной безопасности](https://forms.gle/VLEx2Gf1h8grpXXu5)
|
||||
|
||||
**Срок обучения и прохождения тестирования** - до начала выполнения трудовой функции!
|
||||
|
||||
Спасибо!
|
||||
|
||||
С уважением,
|
||||
Жуланова Наталья Александровна,
|
||||
помощник генерального директора ООО "Клиника ухо, горло, нос им. проф. Е.Н.Оленевой" (г. Пермь)
|
||||
📞 +7 (902) 64-54-648
|
||||
"""
|
||||
try:
|
||||
# Отправка сообщения сотруднику
|
||||
await bot.send_message(employee_id, message_text, parse_mode="Markdown")
|
||||
logging.info(f"Сообщение о пожарной безопасности отправлено {full_name}.")
|
||||
|
||||
|
||||
except Exception as e:
|
||||
logging.error(f"Ошибка при отправке инструктажа или документа: {e}")
|
||||
await bot.send_message(ADMIN_ID, "Произошла ошибка при отправке инструктажа или документа.")
|
||||
|
||||
|
||||
# Обработчик нажатия на кнопки выбора специальности
|
||||
|
||||
@dp.message_handler(lambda message: message.text in specialty_chat_links.keys(), chat_type=types.ChatType.PRIVATE)
|
||||
async def handle_specialty_selection(message: types.Message):
|
||||
selected_specialty = message.text
|
||||
data = sheet.get_all_values()
|
||||
last_employee_row = len(data)
|
||||
|
||||
if last_employee_row < 2:
|
||||
await message.answer("В таблице пока нет сотрудников для назначения специальности.")
|
||||
return
|
||||
|
||||
new_employee_id = data[last_employee_row - 1][13]
|
||||
full_name = data[last_employee_row - 1][0]
|
||||
|
||||
if not new_employee_id:
|
||||
await message.answer("Не удалось найти Telegram ID сотрудника в таблице.")
|
||||
return
|
||||
|
||||
try:
|
||||
sheet.update_cell(last_employee_row, 16, selected_specialty)
|
||||
await message.answer(f"Специальность сотрудника обновлена на: {selected_specialty}")
|
||||
|
||||
chat_invite_link = specialty_chat_links.get(selected_specialty)
|
||||
if chat_invite_link:
|
||||
await bot.send_message(
|
||||
new_employee_id,
|
||||
f"Поздравляем! Вы были добавлены в нашу команду как {selected_specialty}. Вот ссылка на вашу беседу: {chat_invite_link}"
|
||||
)
|
||||
await message.answer(f"Ссылка на беседу отправлена сотруднику.")
|
||||
|
||||
# Отправка сообщения о прохождении инструктажа
|
||||
await send_fire_safety_instructions(new_employee_id, full_name, data[last_employee_row - 1])
|
||||
|
||||
except Exception as e:
|
||||
await message.answer(f"Ошибка при обновлении таблицы: {e}")
|
||||
|
||||
|
||||
|
||||
# Функция для генерации клавиатуры с кнопками типа сотрудника
|
||||
def create_employee_keyboard():
|
||||
keyboard = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=False)
|
||||
button_doctors = KeyboardButton("Врачи")
|
||||
button_nurses = KeyboardButton("Медсёстры")
|
||||
button_orderlies = KeyboardButton("Санитарки")
|
||||
button_admins = KeyboardButton("Администраторы")
|
||||
button_operators = KeyboardButton("Операторы КЦ")
|
||||
button_aap = KeyboardButton("АУП")
|
||||
|
||||
keyboard.add(button_doctors, button_nurses)
|
||||
keyboard.add(button_orderlies, button_admins)
|
||||
keyboard.add(button_operators, button_aap)
|
||||
|
||||
return keyboard
|
||||
|
||||
|
||||
# Обработчик команды /start
|
||||
@dp.message_handler(commands=['start'], chat_type=types.ChatType.PRIVATE)
|
||||
async def send_welcome(message: types.Message):
|
||||
user_id = message.from_user.id
|
||||
|
||||
# Отправка фото
|
||||
photo_path = r'D:\Users\Maxim\PycharmProjectsbot\Bot_for_clinic\start_foto.png'
|
||||
await bot.send_photo(user_id, types.InputFile(photo_path))
|
||||
|
||||
# Отправка текста с кнопкой
|
||||
await bot.send_message(
|
||||
user_id,
|
||||
"Добрый день, этот бот нужен Вам для начала прохождения процедуры трудоустройства в "
|
||||
"Общество с ограниченной ответственностью «Клиника ухо, горло, нос имени профессора Е.Н. Оленевой».\n"
|
||||
"Нажмите, пожалуйста, на команду 👉 /registration",
|
||||
reply_markup=get_registration_button()
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
# Обработчик команды регистрации
|
||||
@dp.message_handler(commands=['registration'], chat_type=types.ChatType.PRIVATE)
|
||||
async def send_welcome(message: types.Message):
|
||||
await message.answer(
|
||||
"▪️В соответствии с требованиями статьи 9 Федерального закона от 27.07.2006 г. «О персональных данных» № 152-ФЗ даю согласие на обработку своих персональных данных.\n"
|
||||
"▪️Наименование и адрес оператора, получающего согласие субъекта персональных данных: Общество с ограниченной ответственностью «Клиника ухо, горло, нос имени профессора Е.Н. Оленевой».\n"
|
||||
"▪️Цель обработки персональных данных: организация труда и осуществление иных, связанных с этим мероприятий.",
|
||||
reply_markup=get_consent_keyboard()
|
||||
)
|
||||
|
||||
# Обработчик ответа пользователя
|
||||
@dp.message_handler(lambda message: message.text in ["✅ Даю согласие на обработку своих персональных данных", "❌ Не даю согласие на обработку своих персональных данных"])
|
||||
async def process_consent(message: types.Message):
|
||||
user_id = message.from_user.id
|
||||
|
||||
if message.text == "✅ Даю согласие на обработку своих персональных данных":
|
||||
form_url = f"https://tgbotkugn.pirogov.ai/?user_id={user_id}"
|
||||
form_keyboard = InlineKeyboardMarkup().add(
|
||||
InlineKeyboardButton(
|
||||
text="Ввести персональные данные", web_app=WebAppInfo(url=form_url)
|
||||
)
|
||||
)
|
||||
await message.answer(
|
||||
"Спасибо за согласие! Нажмите кнопку ниже, чтобы ввести персональные данные:",
|
||||
reply_markup=form_keyboard
|
||||
)
|
||||
else:
|
||||
await message.answer(
|
||||
"Вы не дали согласие на обработку персональных данных.\n"
|
||||
"Вы не можете продолжить регистрацию.",
|
||||
reply_markup=get_consent_keyboard()
|
||||
)
|
||||
|
||||
@dp.message_handler(commands=['getchatid'], chat_type=[ChatType.GROUP, ChatType.SUPERGROUP])
|
||||
async def get_chat_id(message: types.Message):
|
||||
# Проверяем статус пользователя в чате
|
||||
chat_member = await bot.get_chat_member(message.chat.id, message.from_user.id)
|
||||
if chat_member.status not in ['administrator', 'creator']:
|
||||
# Отправляем предупреждение о недостатке прав
|
||||
warning_message = await message.answer("У вас нет прав на выполнение этой команды.")
|
||||
|
||||
# Удаляем команду /getchatid через 1 секунду
|
||||
await asyncio.sleep(1)
|
||||
try:
|
||||
await message.delete()
|
||||
except MessageCantBeDeleted:
|
||||
logging.warning("Не удалось удалить сообщение с командой /getchatid")
|
||||
|
||||
# Удаляем предупреждение через 5 секунд
|
||||
await asyncio.sleep(5)
|
||||
try:
|
||||
await warning_message.delete()
|
||||
except MessageCantBeDeleted:
|
||||
logging.warning("Не удалось удалить сообщение с предупреждением")
|
||||
return
|
||||
|
||||
# Отправляем ID и название чата администратору бота
|
||||
chat_id = message.chat.id
|
||||
chat_title = message.chat.title or "Без названия"
|
||||
await bot.send_message(ADMIN_ID, f"ID чата: {chat_id}\nНазвание чата: {chat_title}")
|
||||
|
||||
# Удаляем команду /getchatid через 1 секунду
|
||||
await asyncio.sleep(1)
|
||||
try:
|
||||
await message.delete()
|
||||
except MessageCantBeDeleted:
|
||||
logging.warning("Не удалось удалить сообщение с командой /getchatid")
|
||||
|
||||
|
||||
|
||||
# Инициализация доступа к Google Sheets
|
||||
gc = gspread.service_account(filename=SERVICE_ACCOUNT_FILE)
|
||||
sheet = gc.open_by_key(SPREADSHEET_ID).sheet1 # Открываем первую таблицу
|
||||
|
||||
|
||||
@dp.message_handler(commands=['kick'], chat_type=types.ChatType.PRIVATE)
|
||||
async def kick_user(message: types.Message):
|
||||
if message.from_user.id != ADMIN_ID:
|
||||
await message.answer("Эта команда доступна только администратору бота.")
|
||||
return
|
||||
|
||||
# Получаем ФИО из сообщения
|
||||
full_name = message.get_args().strip()
|
||||
if not full_name:
|
||||
await message.answer("Пожалуйста, укажите ФИО пользователя для кика.")
|
||||
return
|
||||
|
||||
# Поиск ID пользователя по ФИО в Google Таблице
|
||||
try:
|
||||
data = sheet.get_all_values() # Получаем все значения в таблице
|
||||
except Exception as e:
|
||||
await message.answer("Не удалось получить данные из таблицы.")
|
||||
return
|
||||
|
||||
user_id = None
|
||||
for row in data:
|
||||
if row and row[0] == full_name: # ФИО в первом столбце
|
||||
user_id = row[13] # ID в 14-м столбце (индекс 13)
|
||||
break
|
||||
|
||||
if user_id is None:
|
||||
await message.answer(f"Пользователь с ФИО '{full_name}' не найден в таблице.")
|
||||
return
|
||||
|
||||
errors = [] # Список для хранения ошибок
|
||||
for chat_id in CHAT_IDS:
|
||||
try:
|
||||
await bot.kick_chat_member(chat_id, user_id)
|
||||
except BadRequest as e:
|
||||
errors.append(f"Ошибка в чате {chat_id}: {e}")
|
||||
|
||||
# Отправляем сообщение админу один раз
|
||||
if errors:
|
||||
await bot.send_message(
|
||||
ADMIN_ID,
|
||||
f"Пользователь с ID {user_id} был исключён из чатов, "
|
||||
f"но произошли ошибки: {'; '.join(errors)}"
|
||||
)
|
||||
else:
|
||||
await bot.send_message(ADMIN_ID, f"Пользователь с ID {user_id} был исключён из всех чатов.")
|
||||
|
||||
await message.answer(f"Команда на кик пользователя с ФИО '{full_name}' отправлена во все чаты.")
|
||||
|
||||
|
||||
def get_registration_button():
|
||||
keyboard = ReplyKeyboardMarkup(resize_keyboard=True)
|
||||
registration_button = KeyboardButton("/registration")
|
||||
keyboard.add(registration_button)
|
||||
return keyboard
|
||||
|
||||
|
||||
def get_consent_keyboard():
|
||||
keyboard = ReplyKeyboardMarkup(resize_keyboard=True, one_time_keyboard=True)
|
||||
consent_button = KeyboardButton("✅ Даю согласие на обработку своих персональных данных")
|
||||
deny_button = KeyboardButton("❌ Не даю согласие на обработку своих персональных данных")
|
||||
keyboard.add(consent_button, deny_button)
|
||||
return keyboard
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Запускаем отслеживание таблицы и бота
|
||||
loop = asyncio.get_event_loop()
|
||||
loop.create_task(check_for_new_entries())
|
||||
executor.start_polling(dp, skip_updates=True)
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 246 KiB |
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user