import asyncio
from telethon import TelegramClient, errors
from telethon.tl.functions.channels import JoinChannelRequest
from pytgcalls import PyTgCalls, idle
import random

api_id = '20530587'
api_hash = '44f1c9af70106897d8091ed022517c6d'
phone_numbers = [
                '+17079171335']

chat_id = -1001609081296
group_link = "https://t.me/+9HQ3vi1oSdo2OTBl"

async def join_group(client, group_identifier):
    try:
        if isinstance(group_identifier, str) and group_identifier.startswith('https://t.me/'):
            await client(JoinChannelRequest(group_identifier))
        else:
            await client(JoinChannelRequest(int(group_identifier)))
        me = await client.get_me()
        print(f"Successfully joined the group with {me.phone}")
    except errors.UserAlreadyParticipantError:
        me = await client.get_me()
        print(f"Already a member of the group with {me.phone}")
    except Exception as e:
        me = await client.get_me()
        print(f"Failed to join group with {me.phone}: {str(e)}")

async def main():
    clients = []
    pytgcalls_apps = []
    for phone_number in phone_numbers:
        session_file = f"session_{phone_number}"
        client = TelegramClient(session_file, api_id, api_hash)
        await client.start(phone_number)
        print(f"joining with {phone_number}\n")
        
        # Try to join the group
        if group_link:
            await join_group(client, group_link)
        else:
            await join_group(client, chat_id)
        
        clients.append(client)
        pytgcalls_app = PyTgCalls(client)
        pytgcalls_apps.append(pytgcalls_app)
    
    tasks = []
    for app in pytgcalls_apps:
        task = asyncio.create_task(app.start())
        tasks.append(task)
    await asyncio.gather(*tasks)
    
    for app in pytgcalls_apps:
        wait_time = random.randint(1, 2)
        print(f"Waiting for {wait_time} seconds before joining\n")
        await asyncio.sleep(wait_time)
        
        try:
            await app.play(chat_id)
            print(f"Successfully joined the group call")
        except Exception as e:
            print(f"Error joining group call: {e}")
    
    print("All clients have joined the group and attempted to join the call. Listening...")
    await idle()
    
    for client in clients:
        await client.disconnect()

if __name__ == '__main__':
    loop = asyncio.get_event_loop()
    loop.run_until_complete(main())


This is a script to make my userbot join a voicechat. I need it to get the chat details from the config file like the send text script does. How can I do that? This is the send text script:


from pyrogram import Client, filters, errors
import asyncio
import json
import random
import os
from time import sleep
from itertools import cycle
import re
from datetime import datetime, timezone
from pyrogram import raw
from pyrogram.types import Sticker
import sqlite3
import logging
from pyrogram.raw.functions.messages import SetTyping
from pyrogram.raw.types import SendMessageTypingAction
from pyrogram.errors import UserNotParticipant, ChatWriteForbidden, PeerIdInvalid, UserAlreadyParticipant, SessionRevoked, SessionPasswordNeeded
import secrets
import sqlite3
from pyrogram.raw.functions.messages import SetTyping
from pyrogram.raw.types import SendMessageTypingAction

#logging.basicConfig(level=logging.DEBUG)

async def create_new_session(phone, api_id, api_hash):
    session_file = f"sessions/{phone}.session"
    if os.path.exists(session_file):
        os.remove(session_file)
        print(f"Removed existing session file for {phone}")
    
    try:
        client = Client(f"sessions/{phone}", api_id=api_id, api_hash=api_hash, phone_number=phone)
        await client.start()
        print(f"New session created for {phone}")
        await client.stop()
        return True
    except SessionPasswordNeeded:
        print(f"Two-step verification is enabled for {phone}. Please handle this manually.")
        return False
    except Exception as e:
        print(f"Failed to create new session for {phone}: {str(e)}")
        return False

async def join_group_with_all_accounts(target_group):
    global all_accounts
    join_flag_file = f'{token}/join_flag.json'

    # Check if we've already joined
    try:
        with open(join_flag_file, 'r') as f:
            join_flag = json.load(f)
        if join_flag.get('joined', False):
            print("All accounts have already joined the group.")
            return
    except FileNotFoundError:
        pass

    print("Attempting to join the group with all accounts...")
    for account in all_accounts:
        try:
            async with Client(f"sessions/{account}", api_id=api_id, api_hash=api_hash, phone_number=account) as client:
                try:
                    if target_group.startswith('https://t.me/+') or target_group.startswith('https://t.me/joinchat/'):
                        # This is a private group invite link
                        await client.join_chat(target_group)
                    else:
                        # This is a public group link, we need to extract the username
                        username = target_group.split('/')[-1]
                        await client.join_chat(username)
                    print(f"Account {account} joined the group successfully.")
                except UserAlreadyParticipant:
                    print(f"Account {account} is already a member of the group.")
                except Exception as e:
                    print(f"Failed to join group with account {account}: {str(e)}")
        except Exception as e:
            print(f"Failed to start client for account {account}: {str(e)}")

    # Set and save the join flag
    os.makedirs(os.path.dirname(join_flag_file), exist_ok=True)
    with open(join_flag_file, 'w') as f:
        json.dump({'joined': True}, f)
    
    print("Finished attempting to join the group with all accounts.")

def get_command_type(command):
    if command.startswith('/'):
        return 'meme_pump'
    elif command == 'image':
        return 'image'
    elif command == 'sticker':
        return 'sticker'
    elif command == 'gif':
        return 'gif'
    elif command in filters:
        return 'filter'
    else:
        return 'long_command'

def clear_sent_long_commands():
    file_path = 'sent_long_commands.json'
    if os.path.exists(file_path):
        os.remove(file_path)
        print(f"Cleared {file_path}")
    else:
        print(f"{file_path} does not exist. Nothing to clear.")

#clear_sent_long_commands()

#CONFIG STARTS HERE

with open("StickID.json", "r") as file:
    stickers_data = json.load(file)

# Load the configuration
with open('config.json', 'r', encoding='utf-8') as f:
    config = json.load(f)

# Load the configuration
with open('Set1Config.json', 'r', encoding='utf-8') as f:
    setconfig = json.load(f)

image_count = setconfig.get('image_count')
sticker_count = setconfig.get('sticker_count')
long_command_count = setconfig.get('long_command_count')
meme_pump_command_count = setconfig.get('meme_pump_command_count')
keep_track_of_long_comments = setconfig.get('KeepTrackOfLongComments')

#/__________________________________________________________________PHASING

min_time = setconfig['min_time']
max_time = setconfig['max_time']
buy_reply_messages_general = config['buy_reply_messages_general']
buy_reply_messages_dump = config['buy_reply_messages_dump']
long_commands = config['long_commands']
long_commands_dump = config['long_commands_dump']
meme_dump_commands = config['meme_dump_commands']
meme_pump_commands = config['meme_pump_commands']

# Get the current phase
current_phase = config.get('current_phase')

def get_current_set():
    global buy_reply_messages, long_commands, meme_pump_commands, min_time, max_time
    
    if current_phase == 'dump':
        buy_reply_messages = buy_reply_messages_dump
        long_commands = long_commands_dump
        meme_pump_commands = meme_dump_commands
        min_time = setconfig['min_time_dump']
        max_time = setconfig['max_time_dump']

    else:  # default to general/pump phase
        buy_reply_messages = buy_reply_messages_general
        long_commands = long_commands
        #meme_pump_commands = meme_pump_commands

    print(f"We are using phase: {current_phase}")
    print(f"Long commands are from: {'dump' if current_phase == 'dump' else 'general'} phase")
    
    # You can add more print statements here to verify the content of the variables
    print(f"Sample meme command: {meme_pump_commands[0] if meme_pump_commands else 'No meme commands'}")
    print(f"Sample long command: {long_commands[0] if long_commands else 'No long commands'}")

# Call the function to set the global variables
get_current_set()
#/__________________________________________________________________PHASING


# default is to do all functions, but we specify which functions we want to run in the config by setting true, false flags
react_to_buybot_messages = config.get('react_to_buybot_messages')  # Default to True if not specified
send_messages = config.get('send_messages', True)

speed = 1

min_reactions = config['min_reactions']
max_reactions = config['max_reactions']
api_id = setconfig['api_id']
api_hash = setconfig['api_hash']

target_group = setconfig['join_group']



filters = config['filters']
prelaunch_commands = config['meme_pump_commands']

all_accounts = setconfig['accounts']
token = setconfig['token']
capital_token_name = setconfig['capital_token']
capital_token = setconfig['capital_token']


min_accounts = setconfig['min_accounts']
max_accounts = setconfig['max_accounts']

# Load buybot IDs
buybot_ids = config['buybot_ids']

send_stickers = setconfig.get('send_stickers')
send_images = setconfig.get('send_images')
keep_track_of_long_comments = setconfig.get('KeepTrackOfLongComments')

def load_sent_long_commands(file_path='sent_long_commands.json'):
    if not keep_track_of_long_comments:
        return set()
    try:
        with open(file_path, 'r') as file:
            return set(json.load(file))
    except FileNotFoundError:
        return set()

def save_sent_long_commands(sent_commands, file_path='sent_long_commands.json'):
    if keep_track_of_long_comments:
        with open(file_path, 'w') as file:
            json.dump(list(sent_commands), file)

#input(f"{send_images}\n\n")

# Load previously sent replies from a file
def load_sent_replies(file_path):
    if os.path.exists(file_path):
        with open(file_path, 'r') as file:
            return set(line.strip() for line in file)
    return set()

# Save a sent reply to a file
def save_sent_reply(file_path, reply_text):
    with open(file_path, 'a') as file:
        file.write(reply_text + '\n')

terminate_on_find = False

import asyncio
import secrets
import re  # Import regular expression library

async def get_user_ids(client):
    try:
        me = await client.get_me()
        return me.id
    except Exception as e:
        print(f"Error retrieving user ID: {str(e)}")
        return None


async def parse_and_reply_to_messages(client, target_chat_id, user_ids, words=["bot", "bots", "spam", "spamming", "botted"], 
                                      exclusions=["chattershield_bot", "buybot", "rose", "removeurlsbot", "buy bot"], limit=10):
    sent_replies_file = 'sent_replies.txt'
    replied_message_ids_file = 'replied_message_ids.json'

    def load_sent_replies(file_path):
        try:
            with open(file_path, 'r') as file:
                return set(line.strip() for line in file)
        except FileNotFoundError:
            return set()

    def save_sent_reply(file_path, reply_text):
        with open(file_path, 'a') as file:
            file.write(reply_text + '\n')

    def load_replied_message_ids(file_path):
        try:
            with open(file_path, 'r') as file:
                return set(json.load(file))
        except FileNotFoundError:
            return set()

    def save_replied_message_ids(file_path, replied_message_ids):
        with open(file_path, 'w') as file:
            json.dump(list(replied_message_ids), file)

    sent_replies = load_sent_replies(sent_replies_file)
    replied_message_ids = load_replied_message_ids(replied_message_ids_file)

    reply_texts = [
        "lmao whatever bro... have you considered the possibility that you aren't even real and this is all just a dream", 
        "lol fuck you", 
        "kek bro calm the fuck down",
        "bruh, you're the real sussy individual here, get a grip",
        "seriously? maybe your mom is a whore too",
        "dude, just chill out, it's not that deep",
        "you're hilarious, keep it up and you might get a comedy special",
        "lmfao, maybe you're just a simulation",
        "wow, you must be fun at parties",
        "relax dude, we're all fakes in this game",
        "you're acting like a jeet right now",
        "calm down bro, it's just the internet",
        "you're the paranoid android here, not me",
        "bro, you need a chill pill",
        "whatever, just take a deep breath and relax",
        "you're more animal than human, accept it",
        "maybe you're the sus one and you don't even know it",
        "dude, you're taking this way too seriously",
        "relax, it's all just ones and zeros",
        "honestly, you're just proving my point",
        "take it easy, it's not worth the stress",
        "you're overreacting, bro",
        "calm your circuits, the dame doth protest too much",
        "you've got more in common with computer than you think",
        "chill out, we're all sussy here anyway"
    ]
    available_replies = [reply for reply in reply_texts if reply not in sent_replies]

    if not available_replies:
        print("No available replies left to send.")
        return

    try:
        async for message in client.get_chat_history(chat_id=target_chat_id, limit=limit):
            message_text = message.text.lower() if message.text else ""
            if message.from_user and message.from_user.id not in user_ids:
                if any(re.search(r'\b' + word + r'\b', message_text) for word in words) and not any(exc in message_text for exc in exclusions):
                    print(f"Message ID {message.id} contains one of the words {words} and none of the exclusions {exclusions}: {message.text}")
                    if message.id not in replied_message_ids:
                        reply_text = secrets.choice(available_replies)
                        await message.reply(reply_text)
                        print(f"Replied to message ID {message.id} with: {reply_text}")
                        replied_message_ids.add(message.id)
                        save_sent_reply(sent_replies_file, reply_text)
                        save_replied_message_ids(replied_message_ids_file, replied_message_ids)
                        if "terminate_on_find" in globals() and terminate_on_find:
                            raise SystemExit("Trigger words found and no exclusions present. Terminating script.")
                        else:
                            print("Trigger words found and no exclusions present. Sleeping for 600 seconds and continuing execution.")
                            await asyncio.sleep(600)
                            return
                    else:
                        print(f"Message ID {message.id} has already been replied to.")
                elif any(word in message_text for word in words):
                    print(f"Message ID {message.id} was ignored due to exclusion words.")
            else:
                print(f"Message ID {message.id} was sent by an account in the list. Ignoring.")
    except SystemExit as e:
        print(e)
        raise
    except Exception as e:
        print(f"An error occurred while parsing messages: {str(e)}")






async def join_group_if_not_member(client, target_group):
    try:
        chat = await client.get_chat(target_group)
        print(f"Already a member of the chat {target_group}")
    except UserNotParticipant:
        await client.join_chat(target_group)
        print(f"Joined the chat {target_group}")
    except Exception as e:
        print(f"Error checking membership or joining the group {target_group}: {str(e)}")




# Global variable to track unlock status
chat_unlocked_flag = False

async def wait_for_unlock(client, target_chat_id, check_interval=600):
    global chat_unlocked_flag
    if not chat_unlocked_flag:
        print("\n\nThe chat seems to be locked, checking if its unlocked now.\n\n")
        await asyncio.sleep(1)
        try:
            if send_stickers:
                random_sticker_id = secrets.choice(stickers_data)
                # Attempt to send a sticker
                await client.send_sticker(chat_id=target_chat_id, sticker=random_sticker_id)
                chat_unlocked_flag = True
                print("\n\nChat is unlocked. Continuing execution...\n\n")
                await asyncio.sleep(1)
            else:
                # If sending stickers is turned off, try sending a simple text message instead
                

                greetings = [
                f"whats up {token} gang, ready to soar",
                f"gotta buy more {token}, always upping my game",
                f"yo diamond hand chads, {token} to the stars",
                f"pump it up {token} crew, nothing but gains",
                f"to the moon or nothin with {token}, no brakes on this rocket",
                f"hey {token} heads stackin sats, never stopping",
                f"{token} hodlers assemble, it's our time",
                f"whats the vibe {token} collectors, feeling bullish as ever",
                f"yo whos trading in {token} today, eyes on the prize",
                f"greetings {token} blockchain believers, we're in this together",
                f"{token} kings and queens whats good, keep ruling",
                f"hey traders what are we pumping today, {token} for sure",
                f"lets moon together with {token}, join the ride",
                f"hey {token} hodlers keep calm and carry on, we got this",
                f"{token} degen squad where you at, show your strength",
                f"whats your favorite {token} altcoin today, all in on {token}",
                f"keep calm and hodl on {token}, only way is up",
                f"ready to stack some more {token}, let's bulk up",
                f"{token} weather report: bullish as always",
                f"whos ready for the next {token} airdrop, more to grab",
                f"blockchain bros hows it hanging with {token}, always high",
                f"{token} to the core, core of my portfolio",
                f"whos minting {token} today, creating value",
                f"let the {token} gains begin, no end in sight",
                f"sup with the {token} market today, only green days ahead",
                f"hey {token} shillers what are you pushing, pushing towards the moon",
                f"diamond hands where you at with {token}, stronger together",
                f"ready to defy the odds in {token} defi, defy and thrive",
                f"{token} night owls how we doing, soaring all night",
                f"hey family what {token} coins are we watching, all eyes on {token}",
                f"moon mission ready for liftoff with {token}, strapped in",
                f"apes together strong for {token}, unbreakable",
                f"lets get this {token} crypto, taking over the crypto world",
                f"whats shaking in the {token} shill zone, shaking up the market",
                f"to the moon and back with {token}, and then some",
                f"hey {token} wizards spell some gains, cast your spells",
                f"where my {token} ledger gang at, securing the bag",
                f"{token} junkies got any tips, tip is to keep holding",
                f"stay frosty {token} peeps, cool gains on the way",
                f"anyone else feeling bullish on {token}, it's a bull run",
                f"{token} fud fighters assemble, squash the doubts",
                f"hodl the line friends of {token}, line to the moon",
                f"{token} market watchers whats hot, {token}'s always hot",
                f"fiat is old news {token} is where its at, digital gold",
                f"whos making {token} moves today, making millionaire moves"
            ]

                message = secrets.choice(greetings)

                await client.send_message(chat_id=target_chat_id, text=message)
                chat_unlocked_flag = True
                print("\n\nChat is unlocked. Continuing execution...\n\n\n")
        except ChatWriteForbidden:
            chat_unlocked_flag = False
            print(f"\n\nChat is locked (cannot write). Setting the lock flag to true. Checking again in {check_interval} seconds...\n\n")
            await asyncio.sleep(1)
            await asyncio.sleep(check_interval)
        except Exception as e:
            chat_unlocked_flag = False
            print(f"\n\nAn unexpected error occurred: {str(e)}. Setting the lock flag to true. Sleeping for {check_interval} seconds...\n\n")
            await asyncio.sleep(1)
            await asyncio.sleep(check_interval)
    else:
        print("\n\nChat is already unlocked. No need to check again.\n\n")
        await asyncio.sleep(1)




# Remove all previous messages sent by the user's account
async def remove_test_message(client, target_chat_id):
    async for message in client.get_chat_history(chat_id=target_chat_id):
        if message.from_user is not None and message.from_user.id == (await client.get_me()).id:
            try:
                print("sleeping for 2 seconds..\n")
                sleep(2)
                await client.delete_messages(chat_id=target_chat_id, message_ids=message.id)
                print(f"Removed message ID {message.id} sent by user.")
            except Exception as e:
                print(f"Failed to delete message ID {message.id}: {str(e)}")


def get_image_paths(folder=f'memes/{token}'):
    os.makedirs(folder, exist_ok=True)
    return [os.path.join(folder, f) for f in os.listdir(folder) if f.lower().endswith(('.png', '.jpg', '.jpeg'))]

def get_gif_paths(folder=f'GIFS/{token}'):
    os.makedirs(folder, exist_ok=True)
    return [os.path.join(folder, f) for f in os.listdir(folder) if f.endswith('.mp4')]

image_paths = get_image_paths()
gif_paths = get_gif_paths()

random.shuffle(image_paths)
random.shuffle(gif_paths)

image_iter = iter(image_paths)
gif_iter = iter(gif_paths)

async def send_random_sticker(client, target_chat_id):
    if send_stickers:
        if stickers_data:
            # Select a random sticker ID from the list

            await client.invoke(SetTyping(
            peer=await client.resolve_peer(target_chat_id),
            action=SendMessageTypingAction()
            ))

            random_sticker_id = random.choice(stickers_data)

            try:
                # Send the random sticker to the target chat
                await client.send_sticker(chat_id=target_chat_id, sticker=random_sticker_id)
                print(f"Random sticker sent to {target_group}: {random_sticker_id}")
            except Exception as e:
                print(f"Error sending random sticker: {str(e)}")
        else:
            print("No stickers found in the stickers data.")
    else:
        print("Sending stickers is turned off.")

# Global variable to hold the target chat ID if found
TargetChatID = None

# Function to list all chats and find one containing the token
async def list_and_find_chat_with_token(client):
    global TargetChatID
    #TargetChatID = None
    if TargetChatID is not None:
        return TargetChatID
    async for dialog in client.get_dialogs():
        if token.lower() in dialog.chat.title.lower():
            print(f"Found matching chat: {dialog.chat.title} (Chat ID: {dialog.chat.id})\n")
            TargetChatID = dialog.chat.id
            print(f"{TargetChatID} is the group ID of {token}\n")
            sleep(1)
            break



async def resolve_target_group(client, target_group):
    global TargetChatID
    if TargetChatID is not None:
        print(f"Using cached Chat ID: {TargetChatID}")
        return TargetChatID

    try:
        print(f"Attempting to resolve chat for target group: {target_group}")
        if target_group.startswith("https://t.me/+") or target_group.startswith("https://t.me/joinchat/"):
            # This is a private group invite link
            chat = await client.join_chat(target_group)
        else:
            # This is a public group link, we need to extract the username
            username = target_group.split('/')[-1]
            chat = await client.join_chat(username)
        
        TargetChatID = chat.id
        print(f"Joined and resolved Chat ID: {chat.id}")
        return chat.id
    except UserAlreadyParticipant:
        try:
            chat = await client.get_chat(target_group)
            TargetChatID = chat.id
            print(f"Already a participant. Using resolved Chat ID: {chat.id}")
            return chat.id
        except Exception as e:
            print(f"Error getting chat after UserAlreadyParticipant: {str(e)}")
            raise
    except Exception as e:
        print(f"General error during chat resolution: {str(e)}")
        raise



async def send_command_with_account(client, command, target_chat_id):
    global image_iter, gif_iter, chat_unlocked_flag

    try:

        await client.invoke(SetTyping(
            peer=await client.resolve_peer(target_chat_id),
            action=SendMessageTypingAction()
        ))

        typing_duration = secrets.choice(range(1, 10))
        await asyncio.sleep(typing_duration)



        if command.startswith('/') and command not in filters:
            send_count = random.randint(2, 5)  # Choose a random number between 3 and 9
            print(f"Detected command {command}, preparing to send it {send_count} times...")
            for _ in range(send_count):
                await client.send_message(chat_id=target_chat_id, text=command)
                print(f"Command sent to {target_group}: {command}")


        elif command == 'image' and send_images:
            print(f"Command is 'image', send_images is {send_images}, preparing to send image...")
            image_path = next(image_iter, None)
            if image_path:
                print(f"Sending image: {image_path}")
                await client.send_photo(chat_id=target_chat_id, photo=image_path)
                print(f"Image sent to {target_group}: {image_path}")
            else:
                print("No images available.")


        elif command == 'sticker' and send_stickers:
            await send_random_sticker(client, target_chat_id)

        elif command == 'gif':
            print("Attempting to send gif")
            gif_path = next(gif_iter, None)
            if gif_path:
                await client.send_video(chat_id=target_chat_id, video=gif_path)
                print(f"GIF sent to {target_group}: {os.path.basename(gif_path)}")

        else:
            # Sending text commands
            if command == 'image':
                print("No images available.")
                return
            await client.send_message(chat_id=target_chat_id, text=command)
            print(f"Command sent to {target_group}: {command}")

    except Exception as e:
        print(f"An unexpected error occurred: {str(e)}")
        # Check for any permission errors related to sending messages, images, or stickers
        if "CHAT_SEND_PHOTOS_FORBIDDEN" in str(e) or "CHAT_SEND_PLAIN_FORBIDDEN" in str(e):
            print("Rechecking unlock status due to permission error...")
            chat_unlocked_flag = False
            await wait_for_unlock(client, target_chat_id)
            # Optionally, try sending the command again after rechecking the unlock status
            await send_command_with_account(client, command, target_chat_id)




async def fetch_and_parse_messages(client, target_group):
    replied_messages = {}
    reactions_count = {}
    message_use_order = []
    EMOJI_LIST = ['🔥', '👍']
    DELAY_BETWEEN_REACTIONS = 5
    print("Attempting to fetch and parse messages.")

    def save_replied_messages(replied_messages, message_use_order):
        os.makedirs(f'{token}', exist_ok=True)
        with open(f'{token}/replied_messages.json', 'w') as file:
            json.dump({'replies': replied_messages, 'order': message_use_order}, file, indent=4)

    def save_reactions_count(reactions_count):
        os.makedirs(f'{token}', exist_ok=True)
        with open(f'{token}/reactions_count.json', 'w') as file:
            json.dump(reactions_count, file, indent=4)

    def load_replied_messages():
        try:
            with open(f'{token}/replied_messages.json', 'r') as file:
                data = json.load(file)
                return data.get('replies', {}), data.get('order', [])
        except FileNotFoundError:
            return {}, []

    def load_reactions_count():
        try:
            with open(f'{token}/reactions_count.json', 'r') as file:
                return json.load(file)
        except FileNotFoundError:
            return {}

    replied_messages, message_use_order = load_replied_messages()
    reactions_count = load_reactions_count()

    target_chat_id = None
    try:
        target_chat_id = await resolve_target_group(client, target_group)
    except PeerIdInvalid:
        print("Invalid peer ID encountered. Retrying...")
        target_chat_id = await resolve_target_group(client, target_group)
    except Exception as e:
        print(f"An error occurred while resolving the chat ID: {str(e)}")
        return

    try:
        async for msg in client.get_chat_history(chat_id=target_chat_id, limit=5):
            if msg.from_user is None:
                continue

            sender_id = msg.from_user.id
            if sender_id in buybot_ids:
                message_id_str = str(msg.id)
                print(f"Processing Message ID: {msg.id}")

                available_replies = [m.format(token=token, capital_token_name=capital_token_name) for m in buy_reply_messages_general if m.format(token=token, capital_token_name=capital_token_name) not in replied_messages.values()]

                if not available_replies:
                    print("All messages have been used. Resetting the list in reverse order.")
                    replied_messages.clear()
                    available_replies = [buy_reply_messages_general[i].format(token=token, capital_token_name=capital_token_name) for i in reversed(message_use_order)]
                    message_use_order.clear()
                    save_replied_messages(replied_messages, message_use_order)

                if config.get('reply_to_messages', False) and message_id_str not in replied_messages:
                    try:
                        if message_use_order:
                            random_message = available_replies.pop(0)  # Use pop to remove the message as we use it
                        else:
                            random_message = random.choice(available_replies)
                            available_replies.remove(random_message)  # Remove the chosen message
                        
                        replied_messages[message_id_str] = random_message
                        original_index = buy_reply_messages_general.index(random_message.format(token="{token}", capital_token_name="{capital_token_name}"))
                        message_use_order.append(original_index)
                        save_replied_messages(replied_messages, message_use_order)
                        await msg.reply(random_message)
                        print(f"Replied to message ID: {msg.id} with: {random_message}")
                    except Exception as e:
                        print(f"An error occurred while trying to reply to buybot message: {str(e)}")

                if message_id_str not in reactions_count:
                    reactions_count[message_id_str] = {"count": 0, "max": random.randint(min_reactions, max_reactions)}

                if reactions_count[message_id_str]["count"] < reactions_count[message_id_str]["max"]:
                    chosen_emoji = random.choice(EMOJI_LIST)
                    await msg.react(chosen_emoji)
                    reactions_count[message_id_str]["count"] += 1
                    save_reactions_count(reactions_count)
                    print(f"Reacted to message ID {msg.id} with {chosen_emoji}")
                else:
                    print(f"Message ID {msg.id} has reached the maximum number of reactions.")
    except PeerIdInvalid as e:
        print(f"Peer ID invalid error encountered during message fetch: {str(e)}")
    except Exception as e:
        print(f"An error occurred while fetching or processing messages: {str(e)}")







async def main():
    global all_accounts, TargetChatID, min_time, max_time

    # Join the group with all accounts before starting the main loop
    await join_group_with_all_accounts(target_group)

    #random.shuffle(all_accounts)
    account_iter = cycle(all_accounts)

    sent_long_commands = set()
    if keep_track_of_long_comments:
        sent_long_commands = load_sent_long_commands()

    formatted_long_commands = [cmd.format(token=token, capital_token_name=capital_token) for cmd in long_commands]
    available_long_commands = []
    for cmd in formatted_long_commands:
        if not keep_track_of_long_comments or cmd not in sent_long_commands:
            available_long_commands.extend([cmd] * long_command_count)

    prepared_meme_pump_commands = [cmd.format(token=token, capital_token_name=capital_token) for cmd in config['meme_pump_commands']]
    
    meme_pump_count = int(len(prepared_meme_pump_commands) * meme_pump_command_count)
    meme_pump_count = max(1, meme_pump_count)

    sampled_meme_pump_commands = random.choices(prepared_meme_pump_commands, k=meme_pump_count)

    commands_with_images_gifs = (sampled_meme_pump_commands + 
                                 filters + 
                                 ['image'] * image_count + 
                                 ['sticker'] * sticker_count + 
                                 available_long_commands)
    random.shuffle(commands_with_images_gifs)

    next_message_time = 0
    user_ids = []
    last_command_type = None
    user_ids.extend(buybot_ids)
    user_ids = list(set(map(int, user_ids)))

    for account in all_accounts:
        print(f"Starting client for account: {account}")
        try:
            async with Client(f"sessions/{account}", api_id=api_id, api_hash=api_hash, phone_number=account) as client:
                user_id = await get_user_ids(client)
                if user_id is not None:
                    user_ids.append(user_id)
                else:
                    print(f"Failed to retrieve user ID for account: {account}")
        except sqlite3.OperationalError as e:
            if "no such column: number" in str(e):
                print(f"Session file for {account} is invalid or corrupt. Attempting to create a new session.")
                success = await create_new_session(account, api_id, api_hash)
                if success:
                    # Retry with the new session
                    async with Client(f"sessions/{account}", api_id=api_id, api_hash=api_hash, phone_number=account) as client:
                        user_id = await get_user_ids(client)
                        if user_id is not None:
                            user_ids.append(user_id)
                        else:
                            print(f"Failed to retrieve user ID for account: {account}")
                else:
                    print(f"Skipping account {account} due to session creation failure.")
            else:
                print(f"Unexpected SQLite error for {account}: {str(e)}")
        except Exception as e:
            print(f"Unexpected error for account {account}: {str(e)}")
        

    # Resolve the target group once
    async with Client(f"sessions/{all_accounts[0]}", api_id=api_id, api_hash=api_hash, phone_number=all_accounts[0]) as client:
        TargetChatID = await resolve_target_group(client, target_group)

    while True:
        num_accounts_to_use = secrets.choice(range(int(min_accounts), int(max_accounts) + 1))
        print(f"we are using {num_accounts_to_use} this pass")
        selected_accounts = [next(account_iter) for _ in range(num_accounts_to_use)]

        for phone in selected_accounts:
            print(f"\n\nwe are trying to log into {phone}\n\n")
            client = None
            try:
                client = Client(f"sessions/{phone}", api_id=api_id, api_hash=api_hash, phone_number=phone)
                print(f"Starting client for phone: {phone}")
                await client.start()
                print(f"Client Started for {phone}")

                if TargetChatID is not None:
                    await wait_for_unlock(client, TargetChatID)
                    await parse_and_reply_to_messages(client, TargetChatID, user_ids)
                    if react_to_buybot_messages:
                        await fetch_and_parse_messages(client, TargetChatID)

                    current_time = asyncio.get_event_loop().time()
                    if current_time >= next_message_time:
                        if send_messages and commands_with_images_gifs:
                            command = None
                            for i, cmd in enumerate(commands_with_images_gifs):
                                current_type = get_command_type(cmd)
                                if current_type != last_command_type:
                                    command = commands_with_images_gifs.pop(i)
                                    last_command_type = current_type
                                    break
                            
                            if command is None:
                                print("Could not find a different command type. Shuffling the list.")
                                random.shuffle(commands_with_images_gifs)
                                command = commands_with_images_gifs.pop(0)
                                last_command_type = get_command_type(command)
                            
                            if keep_track_of_long_comments and command in sent_long_commands:
                                print(f"\n\n!!! ATTENTION: Command '{command}' found in sent_long_commands.json. Skipping and removing all instances. !!!\n\n")
                                initial_count = len(commands_with_images_gifs)
                                commands_with_images_gifs = [cmd for cmd in commands_with_images_gifs if cmd != command]
                                removed_count = initial_count - len(commands_with_images_gifs)
                                print(f"Removed {removed_count} instance(s) of '{command}' from the command list.\n")
                            else:
                                print(f"\nSending command: {command}")
                                await send_command_with_account(client, command, TargetChatID)
                                
                                if keep_track_of_long_comments and command in formatted_long_commands:
                                    print(f"\n--- Long command '{command}' sent. Removing all instances and marking as sent. ---\n")
                                    initial_count = len(commands_with_images_gifs)
                                    commands_with_images_gifs = [cmd for cmd in commands_with_images_gifs if cmd != command]
                                    removed_count = initial_count - len(commands_with_images_gifs)
                                    print(f"Removed {removed_count} instance(s) of '{command}' from the command list.")
                                    sent_long_commands.add(command)
                                    save_sent_long_commands(sent_long_commands)
                                    print(f"Added '{command}' to sent_long_commands.json\n")

                            if not commands_with_images_gifs:
                                print("\nAll commands have been used. Repopulating command list...")
                                prepared_meme_pump_commands = [cmd.format(token=capital_token, capital_token_name=capital_token) for cmd in config['meme_pump_commands']]
                                meme_pump_count = int(len(prepared_meme_pump_commands) * meme_pump_command_count)
                                meme_pump_count = max(1, meme_pump_count)
                                sampled_meme_pump_commands = random.choices(prepared_meme_pump_commands, k=meme_pump_count)
                                commands_with_images_gifs = (sampled_meme_pump_commands + 
                                                             filters + 
                                                             ['image'] * image_count + 
                                                             ['sticker'] * sticker_count)
                                if not keep_track_of_long_comments or len(available_long_commands) > 0:
                                    commands_with_images_gifs += available_long_commands
                                random.shuffle(commands_with_images_gifs)
                                print(f"Command list repopulated with {len(commands_with_images_gifs)} commands.\n")
                            
                            min_delay = int(min_time)
                            max_delay = int(max_time)
                            print(f"Current min_time: {min_time}, max_time: {max_time}")
                            next_message_time = current_time + secrets.randbelow(max_delay - min_delay + 1) + min_delay

                else:
                    print(f"Failed to resolve chat ID for group: {target_group}")

            except SessionRevoked:
                print(f"Session revoked for account {phone}. Moving to the next account.")
                continue
            except sqlite3.OperationalError as e:
                print(f"SQLite error for account {phone}: {str(e)}. Deleting session and trying again.")
                import os
                os.remove(f"sessions/{phone}.session")
                try:
                    client = Client(f"sessions/{phone}", api_id=api_id, api_hash=api_hash, phone_number=phone)
                    await client.start()
                    print(f"Client Started for {phone} after recreating session")
                except SessionPasswordNeeded:
                    print(f"Two-step verification is enabled for {phone}. Please disable it or handle it in your code.")
                    continue
                except Exception as e:
                    print(f"Failed to start client for {phone} after recreating session: {str(e)}")
                    continue
            except SessionPasswordNeeded:
                print(f"Two-step verification is enabled for {phone}. Please disable it or handle it in your code.")
                continue
            except Exception as e:
                print(f"An unexpected error occurred with account {phone}: {str(e)}")
                continue
            finally:
                if client:
                    await client.stop()

        print(f"Current min_time: {min_time}, max_time: {max_time}")

        little_sleep = secrets.choice(range(int(min_time), int(max_time)))
        print(f"Sleeping for {little_sleep} seconds")
        await asyncio.sleep(little_sleep)

if __name__ == "__main__":
    asyncio.run(main())