Этот вопрос закрыт для ответов, так как повторяет вопрос Пишу юзерботов. Надо запускать несколько приложений с разными ботами, как это сделать?
@momvov1

Пишу юзерботов. Надо запускать несколько приложений с разными ботами, как это сделать?

Пишу юзерботов. Сделал успешный исходник, работает как надо. Пытаюсь запустить второе такое же приложение, с изменёнными ключами ботов. Но выдаёт ошибку sqlite3.OperationalError: database is locked. Давал возможность каждому приложению создавать отдельную базу, уже к chatgpt обращался, но всё четно. Может кто сталкивался, возможно нужно что-то конкретное в коде? Мне надо запускать по несколько приложений с разными ключами, в приложение от 10 до 20 ботов. Но работает только , если запустить 1 приложение. Помогите
import asyncio
import random
from datetime import datetime
from telethon import TelegramClient, events
from telethon.tl.functions.channels import JoinChannelRequest
from telethon.errors import SlowModeWaitError, SessionPasswordNeededError, FloodWaitError, PhoneNumberBannedError, InviteHashExpiredError

# Ваши API ID и хэши
api_ids = [
айди
]
api_hashes = [
хэши
]
phone_numbers = [
номера телефонов
]

# Уведомляющий бот
notifier_api_id =
notifier_api_hash = ''
notifier_phone_number = '+'
notification_chat_link = '' # Ссылка на чат для уведомлений

# Ссылка на целевой чат
target_chat_link = ''

# Ссылки на чаты, в которые отправляем сообщения
chat_links = [

]

# Сообщения для рассылки
messages = [
'''сообщение 1''',

'''
сообщение 2
'''
]

# Фотографии для рассылки
images = [
'E:\\bot\\1.jpg',
'E:\\bot\\2.jpg',
'E:\\bot\\3.jpg',
'E:\\bot\\4.jpg'
]

# Функция для отправки сообщения с изображением в указанные чаты
async def send_message_with_image(client, api_id, phone_number, notifier_client, message, image_path):
for chat_link in chat_links:
try:
await client(JoinChannelRequest(chat_link))
await client.send_message(chat_link, message, file=image_path)
print(f"{datetime.now()} - Сообщение с изображением отправлено в чат {chat_link} от {phone_number}")
except SlowModeWaitError as e:
print(f"Ошибка SlowModeWaitError в чате {chat_link}: {e}")
continue
except FloodWaitError as e:
print(f"Ошибка FloodWaitError в чате {chat_link}: {e}")
continue
except InviteHashExpiredError as e:
print(f"Ссылка на чат {chat_link} недействительна: {e}")
continue
except Exception as e:
print(f"Ошибка при отправке сообщения в чат {chat_link}: {e}")
continue

# Отправка уведомления после рассылки
notification_message = f"API ID: {api_id}, Phone number: {phone_number} произвёл рассылку в {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
await notifier_client.send_message(notification_chat_link, notification_message)

# Функция для обработки входящих сообщений
async def handle_new_message(event):
sender = await event.get_sender()
if sender:
sender_username = f"@{sender.username}" if sender.username else f"{sender.id}"
else:
sender_username = "Неизвестный отправитель"

message_text = f"Сообщение от пользователя {sender_username}: {event.message.message}"

if event.is_private and not event.is_reply:
await event.respond('Привет. Я бот. Вот аккаунт продавца: https://t.me/')
await event.client.send_message(target_chat_link, message_text)

# Функция для инициализации клиента и выполнения всех задач
# Функция для инициализации клиента и выполнения всех задач
async def init_client(api_id, api_hash, phone_number, notifier_client):
try:
print(f"Сейчас осуществляется вход для API ID {api_id} и номера {phone_number}")
session_file = f'db_{api_id}_{phone_number}.session' # Имя файла сессии зависит от API ID и номера телефона
client = TelegramClient(f'userbot_session_{api_id}_{phone_number}', api_id, api_hash)
await client.connect()

if not await client.is_user_authorized():
try:
await client.start(phone=phone_number)
except SessionPasswordNeededError:
print(f"Для API ID {api_id} требуется пароль двухфакторной аутентификации.")
return
except PhoneNumberBannedError:
print(f"Номер телефона {phone_number} забанен.")
await notifier_client.send_message(notification_chat_link, f"Аккаунт {api_id} {phone_number} получил спамблок")
return

print(f"Бот успешно запущен с API ID {api_id}")
client.add_event_handler(handle_new_message, events.NewMessage(incoming=True))

# Первичная рассылка
await send_message_with_image(client, api_id, phone_number, notifier_client, random.choice(messages), random.choice(images))

# Планирование отправки сообщений каждый час
async def scheduled_message():
while True:
await asyncio.sleep(3600) # 1 час
message = random.choice(messages)
selected_images = random.sample(images, 2)
for i in range(0, len(chat_links), 20):
await send_message_with_image(client, api_id, phone_number, notifier_client, message, images)
await asyncio.sleep(60) # 1 минута между группами чатов

asyncio.create_task(scheduled_message())
await client.run_until_disconnected()
except Exception as e:
print(f"Ошибка в init_client для {api_id}: {e}")

# Основная функция для инициализации всех клиентов последовательно
async def main():
while True:
delay_between_clients = random.randint(220, 225) # Задержка между запуском клиентов в секундах

# Инициализация уведомляющего бота
notifier_client = TelegramClient('notifier_session', notifier_api_id, notifier_api_hash)
await notifier_client.connect()

if not await notifier_client.is_user_authorized():
try:
await notifier_client.start(phone=notifier_phone_number)
except SessionPasswordNeededError:
print("Для уведомляющего бота требуется пароль двухфакторной аутентификации.")
return

tasks = []
for api_id, api_hash, phone_number in zip(api_ids, api_hashes, phone_numbers):
task = asyncio.create_task(init_client(api_id, api_hash, phone_number, notifier_client))
tasks.append(task)
await asyncio.sleep(delay_between_clients)

await asyncio.gather(*tasks)

if __name__ == "__main__":
asyncio.run(main())
  • Вопрос задан
  • 162 просмотра
Ответы на вопрос 2
@TheDigitalMadness
Программист
используй разные базы данных. Например, ты можешь использовать одинаковые названия баз данных, но в конце добавлять "_номер".

Либо же вариант гораздо проще и правильнее - после запроса в базу данных, закрывай коннект с ней.

Объясняю, почему необходимо так сделать: программа не может использовать базу данных, которая уже используется на данный момент другой программой. Поэтому правильно будет закрывать неиспользуемую на данный момент базу данных, а открывать непосредственно перед запросом в нее.
Ответ написан
@iWeezy
Для каждого нового бота 'notifier_session' должен быть разным, например notifier_session1 и т.д...
Это имя сессии, т.е вы пытаетесь запустить другой аккаунт с уже существующей сессией другого аккаунта.
Ответ написан
Ваш ответ на вопрос

Вопрос закрыт для ответов и комментариев

Потому что уже есть похожий вопрос.
Похожие вопросы