import logging
import telebot
import os
from g4f.client import Client
import json
import boto3
import time
import multiprocessing

from g4f.Provider import RetryProvider, Phind, FreeChatgpt, Liaobots

TG_BOT_TOKEN = os.environ.get(“TG_BOT_TOKEN”)
TG_BOT_CHATS = os.environ.get(“TG_BOT_CHATS”).lower().split(“,”)
PROXY_API_KEY = os.environ.get(“PROXY_API_KEY”)
YANDEX_KEY_ID = os.environ.get(“YANDEX_KEY_ID”)
YANDEX_KEY_SECRET = os.environ.get(“YANDEX_KEY_SECRET”)
YANDEX_BUCKET = os.environ.get(“YANDEX_BUCKET”)
CHANNEL_ID_1 = os.environ.get(“CHANNEL_ID_1”)  # ID первого канала
CHANNEL_ID_2 = os.environ.get(“CHANNEL_ID_2”)  # ID второго канала
CHANNEL_LINK_1 = os.environ.get(“CHANNEL_LINK_1”)  # Ссылка на первый канал
CHANNEL_LINK_2 = os.environ.get(“CHANNEL_LINK_2”)  # Ссылка на второй канал

logger = telebot.logger
telebot.logger.setLevel(logging.INFO)

bot = telebot.TeleBot(TG_BOT_TOKEN, threaded=False)

client = Client(
    provider=RetryProvider([Phind, FreeChatgpt, Liaobots], shuffle=False)
)


@bot.message_handler(func=lambda message: True, content_types=["text"])
def echo_message(message):

    # Increment request count
    user_request_count[user_id] += 1
    typing_process = multiprocessing.Process(target=typing, args=(message.chat.id,))
    typing_process.start()

    user_id = message.from_user.id
    username = message.from_user.username

    if is_user_subscribed_to_channels(username, user_id):
        cringe_usr = True
    if has_exceeded_request_limit(user_id, username):
        send_subscription_reminder(message)
        return

    try:
        text = message.text
        ai_response = process_text_message(text, message.chat.id)
    except Exception as e:
        bot.reply_to(message, f'Error occurred, please try later! {e}')
        return

    typing_process.terminate()
    time.sleep(1)
    try:
        send_long_message(message.chat.id, ai_response)
    except Exception as e:
        time.sleep(1)
        bot.reply_to(message, f'Error occurred, please try later! {e}')







def get_s3_client():
    session = boto3.session.Session(
        aws_access_key_id=YANDEX_KEY_ID, aws_secret_access_key=YANDEX_KEY_SECRET
    )
    return session.client(
        service_name=“s3”, endpoint_url=“https://storage.yandexcloud.net”
    )

def typing(chat_id):
    while True:
        bot.send_chat_action(chat_id, “typing”)
        time.sleep(5)

def is_user_subscribed(user_id):
    for channel_id in [CHANNEL_ID_1, CHANNEL_ID_2]:
        try:
            await member_info = bot.get_chat_member(channel_id, user_id)
            if member_info.status in [‘left’, ‘kicked’]:
                return False
        except Exception as e:
            print(f"Error checking subscription: {e}“)
            return False
    return True

@bot.message_handler(commands=[“help”, “start”])
def send_welcome(message):
    if not is_user_subscribed(message.from_user.id):
        bot.reply_to(message, f"Чтобы использовать этого бота, вы должны быть подписаны на каналы: {CHANNEL_LINK_1} и {CHANNEL_LINK_2}.”)
        return
    bot.reply_to(
        message,
        (“Привет! Я ChatGPT бот. Спроси меня что-нибудь!”),
    )

@bot.message_handler(commands=[“new”])
def clear_history(message):
    if not is_user_subscribed(message.from_user.id):
        bot.reply_to(message, f"Чтобы использовать этого бота, вы должны быть подписаны на каналы: {CHANNEL_LINK_1} и {CHANNEL_LINK_2}.“)
        return
    clear_history_for_chat(message.chat.id)
    bot.reply_to(message, “История чата очищена!”)

@bot.message_handler(func=lambda message: True, content_types=[“text”])
def echo_message(message):
    if not is_user_subscribed(message.from_user.id):
        bot.reply_to(message, f"Чтобы использовать этого бота, вы должны быть подписаны на каналы: {CHANNEL_LINK_1} и {CHANNEL_LINK_2}.”)
        return

    typing_process = multiprocessing.Process(target=typing, args=(message.chat.id,))
    typing_process.start()

    try:
        text = message.text
        ai_response = process_text_message(text, message.chat.id)
    except Exception as e:
        bot.reply_to(message, f"Произошла ошибка, попробуйте позже! {e}“)
    finally:
        typing_process.terminate()

    bot.reply_to(message, ai_response)

def process_text_message(text, chat_id) -> str:
    model = “gpt-3.5-turbo”

    # read current chat history
    s3client = get_s3_client()
    history = []
    try:
        history_object_response = s3client.get_object(
            Bucket=YANDEX_BUCKET, Key=f”{chat_id}.json"
        )
        history = json.loads(history_object_response[“Body”].read())
    except:
        pass

    history.append({“role”: “user”, “content”: text})

    try:
        chat_completion = client.chat.completions.create(
            model=model, messages=history
        )
    except Exception as e:
        if type(e).name == “BadRequestError”:
            clear_history_for_chat(chat_id)
            return process_text_message(text, chat_id)
        else:
            raise e

    ai_response = chat_completion.choices[0].message.content
    history.append({“role”: “assistant”, “content”: ai_response})

    # save current chat history
    s3client.put_object(
        Bucket=YANDEX_BUCKET,
        Key=f"{chat_id}.json",
        Body=json.dumps(history),
    )

    return ai_response

def clear_history_for_chat(chat_id):
    try:
        s3client = get_s3_client()
        s3client.put_object(
            Bucket=YANDEX_BUCKET,
            Key=f"{chat_id}.json",
            Body=json.dumps([]),
        )
    except:
        pass

def handler(event, context):
    message = json.loads(event[“body”])
    update = telebot.types.Update.de_json(message)

    if (
        update.message is not None
        and update.message.from_user.username.lower() in TG_BOT_CHATS
    ):
        try:
            bot.process_new_updates([update])
        except Exception as e:
            print(e)

    return {
        “statusCode”: 200,
        “body”: “ok”,
    }
if not message.from_user.username in alwd_usrs:
    bot.reply_to(message,f"Чтобы использовать этого бота, вы должны быть подписаны на каналы: {CHANNEL_LINK_1} и {CHANNEL_LINK_2}.")

def is_user_subscribed(user_id):
    for channel_id in [CHANNEL_ID_1, CHANNEL_ID_2]:
        try:
            member_info = bot.get_chat_member(channel_id, user_id)
            if member_info.status in ["left", "kicked"]:
                return False
        except Exception as e:
            print(f"Error checking subscription: {e}")
            return False
    return True

if is_user_subscribed(callback.from_user.id)==True:
    alwd_usrs.append(callback.from_user.username)

    INITIAL_FREE_REQUESTS = 5
    init_cringe_requests = 15
    # Dictionary to track request counts per user
    user_request_count = defaultdict(int)

    # Channel IDs to verify subscription (for illustration)
    required_channels = {
        CHANNEL_ID_1: CHANNEL_LINK_1,
        CHANNEL_ID_2: CHANNEL_LINK_2
    }

    def has_exceeded_request_limit(user_id, username):

        if user_request_count[user_id] < INITIAL_FREE_REQUESTS:
            return False  # User is within free request limit
        else:
            if user_request_count[user_id] < init_cringe_requests and username in cringe_usrs:
                return False
        return not is_user_subscribed_to_channels(username)

    async def is_user_subscribed_to_channels(username, user_id):
        if username.lower() in alwd_usrs:
            return True
        if username.lower() in cringe_usrs:
            return
            # TODO: Implement actual check using the Telegram Bot API
        for channel in [CHANNEL_ID_1, CHANNEL_ID_2]:
            user_channel_status = await bot.get_chat_member(chat_id=channel, user_id=user_id)

        if user_channel_status["status"] != 'left':
            pass
        else:
            await bot.send_message(message.from_user.id, 'Вы еще не подписались!')
        cringe_usrs.append(username)
        # This function should return True if the user is subscribed to all required channels
        # For now, assume False - meaning user hasn’t subscribed
        return False

    def send_subscription_reminder(message):
        reminder_text = (
            "You have exhausted your free requests. "
            "Please subscribe to the following channels to continue:\n"
        )
        for channel_id, channel_link in required_channels.items():
            reminder_text += f"{channel_link}\n"

        bot.reply_to(message, reminder_text)

    @bot.message_handler(func=lambda message: True, content_types=["text"])
    def echo_message(message):
        user_id = message.from_user.id
        username = message.from_user.username
        lox_usrs.append(username)

        if has_exceeded_request_limit(user_id, username):
            send_subscription_reminder(message)
            return

        # Increment request count
        user_request_count[user_id] += 1

        typing_process = multiprocessing.Process(target=typing, args=(message.chat.id,))
        typing_process.start()

        try:
            text = message.text
            ai_response = process_text_message(text, message.chat.id)
        except Exception as e:
            bot.reply_to(message, f'Error occurred, please try later! {e}')
            return

        typing_process.terminate()
        bot.reply_to(message, ai_response)


я написал этот код для запуска на облачном сервисе, перепиши его используя библиотеку aiogram и так, чтобы я мог запустить его у себя на пк через google colab