Тебе нужно дополнить этот код так, чтобы помимо того,что к нему можно обращаться напрямую в личных сообщениях и он ведет диалог с пользователем, можно было его добавить в группу и если обратившись к нему в этой группе, он так же отвечал на заданный ему вопрос, но через clientFree gpt-4. Вот код! Пожалуйста, не поломай его и просто дополни:
from telebot.async_telebot import AsyncTeleBot
import telebot
import asyncio
import os
import json
from userID import allowed_users
from work_user_data_async import create_user_data, load_user_data, save_user_data, save_user_data_gpt
from openai import OpenAI
import random
from colorama import Fore, Style
from config import path_files, telegram_bot_token, OPENAI_API_KEY, PROXY_URL
from work_with_text import escape_special_chars
from g4f.client import Client
from g4f.Provider import Bing
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())



# # Установить свой прокси
# proxy_url = PROXY_URL
# os.environ['G4F_PROXY'] = proxy_url
# os.environ['HTTP_PROXY'] = proxy_url
# os.environ['HTTPS_PROXY'] = proxy_url



# Тестовый бот
bot = AsyncTeleBot(telegram_bot_token)

# # Ключ API от OpenAI
client = OpenAI(api_key=OPENAI_API_KEY)


async def init_bot():
    # Устанавливаем собственные команды
    commands = [
        telebot.types.BotCommand('/start', 'Начать диалог и выбрать модель'),
        telebot.types.BotCommand('/reset', 'Сбросить диалог'),
    ]
    await bot.set_my_commands(commands)


# Начальное сообщение
@bot.message_handler(commands=['start'])
async def start_dialog(message):
    user_id = message.from_user.id
    user_nickname = message.from_user.username
    if user_id in allowed_users.values():
        # Данные для создания объекта
            user_id = message.from_user.id
            username = message.from_user.username if message.from_user.username else "unknown"

            # Формируем имя файла на основе user_id
            filename = f'{path_files}user_data/{user_id}.json'

            # Сохраняем данные пользователя
            await create_user_data(user_id, username, filename)

            # Создаем инлайн-кнопки
            gpt4omini = telebot.types.InlineKeyboardButton(text="GPT 4o mini 🤖", callback_data='gpt4omini')
            gpt4o = telebot.types.InlineKeyboardButton(text="GPT 4o 💪", callback_data='gpt4o')
            # gpt4 = telebot.types.InlineKeyboardButton(text="GPT 4 (Медленная (нестабильная, но умнее) 👽", callback_data='gpt4')

            keyboard = telebot.types.InlineKeyboardMarkup(row_width=1)
            # keyboard.add(gpt3,gpt4o,gpt4,bing_gpt4,сlaude3,geminipro)
            
            # Те, кому доступ есть к GPT4o
            # allowed_user_ids = [2106038134, 466164576, 1194816836, 358732, 2090974509, 5695613125, 1194816836, 719890408]
            allowed_user_ids = [466164576]
            if user_id in allowed_user_ids:
                keyboard.add(gpt4omini,gpt4o)
            else:
                keyboard.add(gpt4omini)

            # Отправялем текст
            await bot.send_message(message.chat.id, f"Привет, {user_nickname}! Выбери модель:", reply_markup=keyboard)
    else:
            await bot.send_message(message.chat.id, "Извините, но вам запрещено использовать этого бота.")
            print(user_id)

            
# Выбор модели LLM
async def choose_model(call, model_name, picture_name):
    # Загружаем данные пользователя из файла JSON
    filename = f'{path_files}user_data/{call.from_user.id}.json'
    user_data = await load_user_data(filename)

    # Сохраняем выбранную модель
    user_data['gpt_Version'] = model_name

    # Сохраняем данные в файл JSON
    await save_user_data(filename,user_data)

    # Отправляем картинку
    with open(f'{path_files}pictures/{picture_name}.png', 'rb') as photo:
        await bot.send_photo(call.message.chat.id, photo)

    simple_message = f"Вы выбрали модель *{model_name}*\n\n"

    # Отправляем сообщение 
    await bot.send_message(call.message.chat.id, simple_message, parse_mode='Markdown')

@bot.callback_query_handler(func=lambda call: call.data == 'gpt4omini')
async def gpt4omini(call):
    await choose_model(call, "GPT 4o mini", "gpt4omini")

@bot.callback_query_handler(func=lambda call: call.data == 'gpt4o')
async def choose_gpt4o(call):
    await choose_model(call, "GPT 4o", "gpt4o")

@bot.callback_query_handler(func=lambda call: call.data == 'gpt4')
async def choose_gpt4(call):
    await choose_model(call, "GPT 4", "gpt4")

@bot.callback_query_handler(func=lambda call: call.data == 'bing_gpt4')
async def choose_bing_gpt4(call):
    await choose_model(call, "Bing (GPT 4)", "bing_gpt4")

@bot.callback_query_handler(func=lambda call: call.data == 'сlaude3')
async def choose_сlaude3(call):
    await choose_model(call, "Claude 3 Opus", "сlaude3")

@bot.callback_query_handler(func=lambda call: call.data == 'geminipro')
async def choose_geminipro(call):
    await choose_model(call, "Gemini Pro", "geminipro")



# Функция для загрузки истории диалога из файла
async def load_dialog_history(user_id):
    history_path = f'{path_files}user_data/history/'
    filename = f'{history_path}{user_id}.json'
    if not os.path.exists(history_path):
        os.makedirs(history_path)
    if os.path.exists(filename):
        with open(filename, 'r', encoding='utf-8') as file:
            return json.load(file)
    else:
        # Создаем пустой файл истории, если его нет
        with open(filename, 'w', encoding='utf-8') as file:
            json.dump([], file, ensure_ascii=False)
        return []

# Функция для сохранения истории диалога в файл
async def save_dialog_history(user_id, conversation_history):
    history_path = f'{path_files}user_data/history/'
    filename = f'{history_path}{user_id}.json'
    if not os.path.exists(history_path):
        os.makedirs(history_path)
    with open(filename, 'w', encoding='utf-8') as file:
        json.dump(conversation_history, file, ensure_ascii=False, indent=4)



@bot.message_handler(commands=['reset'])
async def reset_dialog(message):
    user_id = message.from_user.id

    # Очищаем файл с историей диалога
    filename = f'{path_files}user_data/history/{user_id}.json'
    try:
        with open(filename, 'w', encoding='utf-8') as file:
            json.dump([], file)
        await bot.send_message(message.chat.id, "История диалога сброшена.")
    except FileNotFoundError:
        await bot.send_message(message.chat.id, "Ошибка: история диалога не найдена.")



# Удалятор кнопок после первого нажатия
@bot.callback_query_handler(func=lambda call: True)
async def callback_inline(call):
    if call.message:
        if call.data == 'retry_gpt':
            await bot.edit_message_reply_markup(call.message.chat.id, call.message.message_id)
            await repeat(call)


# Функция для получения ответа от GPT
async def get_gpt_answer(gpt_version, dialogue_history):
    clientFree = Client()
    # for attempt in range(4):
        # print(f"Попытка {attempt + 1}. Ждем {attempt * 1} секунд")
        # await asyncio.sleep(attempt * 10)
    try:
        loop = asyncio.get_event_loop()
        # Определяем модель GPT и получаем ответ
        if gpt_version == "GPT 4o mini":
            response = await loop.run_in_executor(None, lambda: client.chat.completions.create(
                model="gpt-4o-mini-2024-07-18", messages=dialogue_history))
        elif gpt_version == "GPT 4o":
            response = await loop.run_in_executor(None, lambda: client.chat.completions.create(
                model="gpt-4o-2024-08-06", messages=dialogue_history))
        elif gpt_version == "Bing (GPT 4)":
            clientFree = Client(provider=Bing)
            response = await loop.run_in_executor(None, lambda: clientFree.chat.completions.create(
                model="gpt-4", messages=dialogue_history, tone="Copilot", web_search=True))
        else:
            return None
        return response.choices[0].message.content
    except Exception as e:
        print(f"Произошла ошибка при получении ответа: {e}")
        # if attempt == 3:  # Если это была последняя попытка, возвращаем None
        return None
            


@bot.message_handler(func=lambda message: True)
async def process_message(message):
    # Получаем идентификатор пользователя и его никнейм
    user_id = message.from_user.id
    username = message.from_user.username or "unknown"
    first_name = message.from_user.first_name or "unknown"
    last_name = message.from_user.last_name or "unknown"

    # Загружаем и инициализируем историю диалога для данного пользователя
    conversation_history = await load_dialog_history(user_id)

    # Получаем текст сообщения пользователя
    user_message = message.text
    print(f"Сообщение от {username} (id: {user_id}): {user_message}")

    if user_message == "/reset":
        await reset_dialog(message)
        return

    # Загружаем данные пользователя из файла и сохраняем сообщение
    filename = f'{path_files}user_data/{user_id}.json'
    user_data = await load_user_data(filename)
    user_data['user_message'] = user_message
    await save_user_data(filename, user_data)

    # Добавляем сообщение пользователя в историю диалога
    conversation_history.append({"role": "user", "content": user_message})
    await bot.send_chat_action(message.chat.id, 'typing')

    # Сохраняем историю диалога
    await save_dialog_history(user_id, conversation_history)

    # Получаем версию GPT
    gpt_version = user_data['gpt_Version']

    # Получаем ответ от GPT
    response_str = await get_gpt_answer(gpt_version, conversation_history)

    # Функция для разбивки строки на части
    def split_message(message, max_length=4096):
        return [message[i:i + max_length] for i in range(0, len(message), max_length)]

    # Проверяем ответ и отправляем его пользователю
    if response_str and response_str.strip() and not any(err in response_str for err in ["не удалось получить ответ", "не могу выполнить ваш запрос", "не могу продолжить этот разговор", "не могу выполнить этот запрос"]):
        print("Ответ из GPT:", response_str)

        # # Чтение сообщения из файла
        # message_file_path = os.path.join(path_files, 'message.txt')
        # with open(message_file_path, 'r', encoding='utf-8') as file:
        #     response_str = file.read()

        # Эмуляция печати текста
        await bot.send_chat_action(message.chat.id, 'typing')
        await asyncio.sleep(3)  # Настройка скорости печати

        # Добавляем ответ модели в историю диалога
        conversation_history.append({"role": "assistant", "content": response_str})

        # Сохраняем историю диалога
        await save_dialog_history(user_id, conversation_history)

        # Сохраняем данные запросов всех пользователей
        filename = f'{path_files}user_data/answers/answer GPT.json'
        await save_user_data_gpt(user_id, username, first_name, last_name, user_message, response_str, gpt_version, filename)

        # Отправляем ответ с форматированием
        response_str_formatted = await escape_special_chars(response_str)

        # Разбиваем отформатированное сообщение на части, если оно слишком длинное
        messages = split_message(response_str_formatted)

        for msg in messages:
            try:
                await bot.send_message(message.chat.id, msg, parse_mode='Markdown')
            except Exception as e:
                unformatted_messages = split_message(response_str)
                for unformatted_msg in unformatted_messages:
                    await bot.send_message(message.chat.id, unformatted_msg)
                    await bot.send_message(message.chat.id, "❗ При отправке этого сообщения возникла ошибка,возможно из-за какого-то символа, был отключен Markdown и отправлен тебе заново в уродском виде. Если эта хрень будет повторяться часто, то напиши Даньке. Если есть желание, то можешь ему помочь разобраться в этой хрени😏", parse_mode='Markdown')
    else:
        print(f"Ошибка при получении ответа от GPT: {response_str}")

        # Отправляем случайную анимацию при ошибке
        random_number = random.randint(1, 20)
        media_path = f'{path_files}pictures/GIF/{random_number}.gif'

        with open(media_path, 'rb') as media:
            if media_path.endswith('.gif'):
                await bot.send_animation(user_id, media)
            else:
                await bot.send_photo(user_id, media)

        # Создаем инлайн-кнопку для повтора запроса
        repeat_button = telebot.types.InlineKeyboardButton(text="Повторить запрос 🔄", callback_data='retry_gpt')
        keyboard = telebot.types.InlineKeyboardMarkup(row_width=1)
        keyboard.add(repeat_button)

        await bot.send_message(message.chat.id, "Ошибка при получении ответа..", reply_markup=keyboard, parse_mode='Markdown')


# Повторить запрос
@bot.callback_query_handler(func=lambda call: call.data == 'retry_gpt')
async def repeat(call):
    user_id = call.from_user.id
    username = call.from_user.username or "unknown"
    first_name = call.from_user.first_name or "unknown"
    last_name = call.from_user.last_name or "unknown"

    # Загружаем данные пользователя из файла
    filename = f'{path_files}user_data/{user_id}.json'
    user_data = await load_user_data(filename)
    user_message = user_data['user_message']
    print(f"Повторное сообщение от {username} (id: {user_id}): {user_message}")

    # Загружаем и инициализируем историю диалога для данного пользователя
    conversation_history = await load_dialog_history(user_id)

    # Добавляем сообщение пользователя в историю диалога
    conversation_history.append({"role": "user", "content": user_message})
    await bot.send_chat_action(call.message.chat.id, 'typing')

    # Сохраняем историю диалога
    await save_dialog_history(user_id, conversation_history)

    # Получаем версию GPT и ответ от модели
    gpt_version = user_data['gpt_Version']
    response_str = await get_gpt_answer(gpt_version, conversation_history)

    # Функция для разбивки строки на части
    def split_message(message, max_length=4096):
        return [message[i:i + max_length] for i in range(0, len(message), max_length)]

    # Проверяем ответ и отправляем его пользователю
    if response_str and response_str.strip() and not any(err in response_str for err in ["не удалось получить ответ", "не могу выполнить ваш запрос", "не могу продолжить этот разговор", "не могу выполнить этот запрос"]):
        print("Ответ из GPT:", response_str)

        await bot.send_chat_action(call.message.chat.id, 'typing')
        await asyncio.sleep(3)

        conversation_history.append({"role": "assistant", "content": response_str})

        # Сохраняем историю диалога
        await save_dialog_history(user_id, conversation_history)

        filename = f'{path_files}user_data/answers/answer GPT.json'
        await save_user_data_gpt(user_id, username, first_name, last_name, user_message, response_str, gpt_version, filename)

        response_str_formatted = await escape_special_chars(response_str)

        # Разбиваем отформатированное сообщение на части, если оно слишком длинное
        messages = split_message(response_str_formatted)

        for msg in messages:
            try:
                await bot.send_message(call.message.chat.id, msg, parse_mode='Markdown')
            except Exception as e:
                unformatted_messages = split_message(response_str)
                for unformatted_msg in unformatted_messages:
                    await bot.send_message(call.message.chat.id, unformatted_msg)
                    await bot.send_message(call.message.chat.id, "❗ При отправке этого сообщения возникла ошибка,возможно из-за какого-то символа, был отключен Markdown и отправлен тебе заново в уродском виде. Если эта хрень будет повторяться часто, то напиши Даньке. Если есть желание, то можешь ему помочь разобраться в этой хрени😏", parse_mode='Markdown')
    else:
        print(f"Ошибка при получении ответа от GPT: {response_str}")

        # Отправляем случайную анимацию при ошибке
        random_number = random.randint(1, 20)
        media_path = f'{path_files}pictures/GIF/{random_number}.gif'

        with open(media_path, 'rb') as media:
            if media_path.endswith('.gif'):
                await bot.send_animation(user_id, media)
            else:
                await bot.send_photo(user_id, media)

        repeat_button = telebot.types.InlineKeyboardButton(text="Повторить запрос 🔄", callback_data='retry_gpt')
        keyboard = telebot.types.InlineKeyboardMarkup(row_width=1)
        keyboard.add(repeat_button)

        await bot.send_message(call.message.chat.id, "Ошибка при получении ответа..", reply_markup=keyboard, parse_mode='Markdown')


    
async def main():
    await init_bot()
    # asyncio.create_task(bot.polling(none_stop=True))  # Запускаем polling в отдельной задаче
    asyncio.create_task(bot.infinity_polling(timeout=60))  # Запускаем infinity_polling в отдельной задаче
    while True:
        await asyncio.sleep(10)  # Бесконечный цикл, чтобы главная корутина не завершалась

asyncio.run(main())