0010_Executive Telegram Bot

The working version of my bot, according to the principle: “It works, and okay,” I’m not a programmer; I can do that this way. I will give explanations and an example of the work as soon as I have time.

# Version: 1.47
import os
import logging
import telebot
from telebot.types import KeyboardButton, ReplyKeyboardMarkup, InlineKeyboardMarkup, InlineKeyboardButton

# Telegram bot token and phone numbers of users in groups
TELEGRAM_TOKEN = '<YOUR TOKEN>'
USER_GROUPS = {
    'group1': ['+XXXXXXXXXXX', '1YYYYYYYYYYYY'],
    'group2': ['3HHHHHHHHHHH'],
    'group3': ['5GGGGGGGGGGG'],
}

# Initializing the bot
bot = telebot.TeleBot(TELEGRAM_TOKEN)

# Setting up logging
logging.basicConfig(filename='/SOME_FOLDER/telebot.log',
                    level=logging.DEBUG,
                    format='%(asctime)s - %(levelname)s - %(message)s')

# Dictionary for storing user contact information
user_contacts = {}

BASE_PATH = '/SOME_FOLDER/scripts'

def get_user_groups(phone_number):
    """Определяет группы, к которым принадлежит пользователь по его номеру телефона.
       Determines the groups a user belongs to by their phone number."""
    user_groups = [group for group, numbers in USER_GROUPS.items() if phone_number in numbers]
    return user_groups

@bot.message_handler(commands=['start'])
def start(message):
    """Отправляет запрос на контактные данные пользователя.
       Sends a request for the user's contact information."""
    markup = ReplyKeyboardMarkup(one_time_keyboard=True, resize_keyboard=True)
    contact_button = KeyboardButton(text="Отправить контакт", request_contact=True)
    markup.add(contact_button)
    bot.send_message(message.chat.id, "Please share your contact to continue.", reply_markup=markup)

@bot.message_handler(content_types=['contact'])
def handle_contact(message):
    """Проверяет, может ли пользователь взаимодействовать с ботом.
       Checks if the user is allowed to interact with the bot."""
    user_phone = message.contact.phone_number
    user_groups = get_user_groups(user_phone)
    
    if user_groups:
        bot.send_message(message.chat.id, f"Welcome! You belong to groups: {', '.join(user_groups)}")
        user_contacts[message.chat.id] = user_phone
        navigate_folders(message.chat.id, BASE_PATH, user_groups)
    else:
        bot.send_message(message.chat.id, "Доступ запрещен.")
        logging.warning(f"Unauthorized access attempt from {user_phone}")

def navigate_folders(chat_id, current_path, user_groups):
    """Навигация по папкам с учетом групп пользователя.
       Navigates folders considering the user's group permissions."""
    markup = InlineKeyboardMarkup()
    
    # The "Back" button if not in the root directory
    if current_path != BASE_PATH:
        markup.add(InlineKeyboardButton('Back', callback_data=f"nav:{os.path.dirname(current_path)}"))
    
    # List of directories and files
    for item in os.listdir(current_path):
        item_path = os.path.join(current_path, item)
        if item_path.startswith(BASE_PATH):  # Убедиться, что путь не выше BASE_PATH
            if os.path.isdir(item_path):
                markup.add(InlineKeyboardButton(f"[DIR] {item}", callback_data=f"nav:{item_path}"))
            elif os.path.isfile(item_path):
                # Checking the visibility of the file for the user
                if (item.startswith('100_') and 'group1' in user_groups) or \
                   (item.startswith('101_') and 'group2' in user_groups) or \
                   (item.startswith('111_') and 'group3' in user_groups):
                    markup.add(InlineKeyboardButton(item, callback_data=f"file:{item_path}"))
    
    bot.send_message(chat_id, f"Текущая директория: {current_path}", reply_markup=markup)

@bot.callback_query_handler(func=lambda call: call.data.startswith('nav:'))
def handle_navigation(call):
    """Обрабатывает навигацию по папкам.
       Handles folder navigation."""
    _, path = call.data.split(':')
    
    # Checking for folder access
    if path.startswith(BASE_PATH):
        user_phone = user_contacts.get(call.message.chat.id, None)
        if user_phone:
            user_groups = get_user_groups(user_phone)
            navigate_folders(call.message.chat.id, path, user_groups)
    else:
        bot.send_message(call.message.chat.id, "Доступ запрещен.")
        logging.warning(f"Попытка доступа к неразрешенной папке: {path}")

@bot.callback_query_handler(func=lambda call: call.data.startswith('file:'))
def handle_file_selection(call):
    """Запрашивает подтверждение для выполнения скрипта.
       Requests confirmation to execute the script."""
    _, file_path = call.data.split(':')
    confirm_markup = InlineKeyboardMarkup()
    confirm_markup.add(InlineKeyboardButton('Подтвердить', callback_data=f"run:{file_path}"))
    bot.send_message(call.message.chat.id, f"Вы хотите запустить {os.path.basename(file_path)}?", reply_markup=confirm_markup)

@bot.callback_query_handler(func=lambda call: call.data.startswith('run:'))
def handle_script_execution(call):
    """Выполняет скрипт после подтверждения.
       Executes the script after confirmation."""
    _, file_path = call.data.split(':')
    
    # Checking for file access
    if file_path.startswith(BASE_PATH):
        os.system(f"bash {file_path}")
        bot.send_message(call.message.chat.id, f"The script  {os.path.basename(file_path)}  is executed.")
        logging.info(f"The script is executed: {file_path}")
    else:
        bot.send_message(call.message.chat.id, "Доступ к файлу запрещен.")
        logging.warning(f"Attempt to execute an unresolved file: {file_path}")

# Launching the bot
bot.polling()