TG бот (предложка). Как решить проблему выкладки постов

Когда планируешь два поста, то он выставляет самый последний по времени самого первого поста. Как исправить?

Говорят, что проблема в переменной user_data, оно перезаписывается при каждом новом добавлении поста. Когда админ добавляет новый пост, то старый стирается. Но как это исправить я без понятия.

from telebot import TeleBot, types
from datetime import datetime
import threading
import time

bot = TeleBot("BOT_TOKEN")

# Временное хранилище данных для каждого пользователя
user_data = {}

# Каналы для публикации (используем ID канала)
CHANNELS = {
    "long_term": id_channel,  # 1 группа
    "medium_term": id_channel,  # 2 группа
    "news": id_channel  # 3 группа
}

# Команда /start для начала создания поста
@bot.message_handler(commands=['start'])
def start_post(message):
    user_id = message.from_user.id
    user_data[user_id] = {"content": [], "posting_in_progress": True}
    request_skip_or_photo(user_id)


# Функция для отображения кнопок пропуска или отправки фото
def request_skip_or_photo(user_id):
    markup = types.InlineKeyboardMarkup(row_width=1)
    markup.add(
        types.InlineKeyboardButton("Пропустить", callback_data="skip_photo")
    )
    bot.send_message(user_id, "Отправьте картинку или пропустите:", reply_markup=markup)


# Обработчик для пропуска фото
@bot.callback_query_handler(func=lambda call: call.data == "skip_photo")
def skip_photo(call):
    user_id = call.from_user.id
    user_data[user_id]["content"].append({"type": "photo", "file_id": None})
    request_skip_or_text(user_id)


# Функция для отображения кнопок пропуска или отправки текста
def request_skip_or_text(user_id):
    markup = types.InlineKeyboardMarkup(row_width=1)
    markup.add(
        types.InlineKeyboardButton("Пропустить", callback_data="skip_text")
    )
    bot.send_message(user_id, "Отправьте текст или пропустите:", reply_markup=markup)


# Обработчик для пропуска текста
@bot.callback_query_handler(func=lambda call: call.data == "skip_text")
def skip_text(call):
    user_id = call.from_user.id
    user_data[user_id]["content"].append({"type": "text", "text": None})
    bot.send_message(user_id, "Выберите канал для публикации.")
    request_channel(user_id)


# Обработчик для картинок (если пользователь отправляет фото вместо пропуска)
@bot.message_handler(content_types=['photo'])
def save_photo_content(message):
    user_id = message.from_user.id
    if user_id not in user_data or not user_data[user_id].get("posting_in_progress"):
        bot.send_message(user_id, "Сначала отправьте команду /start.")
        return

    # Сохраняем фото
    user_data[user_id]["content"].append({"type": "photo", "file_id": message.photo[-1].file_id})
    request_skip_or_text(user_id)


# Обработчик для текстового контента
@bot.message_handler(func=lambda message: message.from_user.id in user_data and user_data[message.from_user.id].get(
    "posting_in_progress"))
def save_text_content(message):
    user_id = message.from_user.id
    user_data[user_id]["content"].append({"type": "text", "text": message.text})
    request_channel(user_id)


# Функция для отображения кнопок выбора канала
def request_channel(user_id):
    markup = types.InlineKeyboardMarkup(row_width=1)
    markup.add(
        types.InlineKeyboardButton("Долгосрочные инвестиции | Phipness Core", callback_data="long_term"),
        types.InlineKeyboardButton("Среднесрочные инвестиции | Phipness Core", callback_data="medium_term"),
        types.InlineKeyboardButton("Новости Инвестиции | Phipness Core", callback_data="news")
    )
    bot.send_message(user_id, "Выберите канал для публикации:", reply_markup=markup)


# Обработчик для выбора канала
@bot.callback_query_handler(func=lambda call: call.data in CHANNELS)
def channel_selection(call):
    user_id = call.from_user.id
    user_data[user_id]["channel"] = CHANNELS[call.data]

    # Получаем текущую дату и время
    current_time = datetime.now().strftime("%d.%m.%Y %H:%M")

    # Формируем сообщение с примером времени
    markup = types.InlineKeyboardMarkup(row_width=1)
    markup.add(
        types.InlineKeyboardButton("Выставить пост сразу", callback_data="post_now")
    )

    bot.send_message(
        user_id,
        f"Когда мне выставить пост?\nПример: {current_time}",
        reply_markup=markup
    )

    # Убираем флаг ожидания канала
    user_data[user_id]["posting_in_progress"] = False


# Обработчик для немедленной отправки поста
@bot.callback_query_handler(func=lambda call: call.data == "post_now")
def post_now(call):
    user_id = call.from_user.id
    if user_id in user_data:
        channel_id = user_data[user_id]["channel"]
        content = user_data[user_id]["content"]

        # Отправка содержимого (картинка + текст)
        photo_sent = False
        for item in content:
            if item["type"] == "photo" and item["file_id"]:
                caption = next((i["text"] for i in content if i["type"] == "text" and i["text"]), "")
                bot.send_photo(channel_id, item["file_id"], caption=caption)
                photo_sent = True

        if not photo_sent:
            text_content = next((i["text"] for i in content if i["type"] == "text" and i["text"]), None)
            if text_content:
                bot.send_message(channel_id, text_content)

        # Подтверждение отправки поста
        bot.send_message(user_id, "Ваш пост был успешно опубликован!")

        # Удаление данных после отправки
        del user_data[user_id]


# Обработчик для установки времени публикации
@bot.message_handler(
    func=lambda message: message.from_user.id in user_data and "post_time" not in user_data[message.from_user.id])
def set_time(message):
    user_id = message.from_user.id
    try:
        post_time = datetime.strptime(message.text, "%d.%m.%Y %H:%M")
        user_data[user_id]["post_time"] = post_time
        bot.send_message(message.chat.id,
                         f"Ваш пост запланирован на {post_time.strftime('%d.%m.%Y %H:%M')}. Он будет опубликован.")

        # Запуск задачи для отложенной публикации
        threading.Thread(target=schedule_post, args=(user_id, post_time)).start()

    except ValueError:
        bot.send_message(message.chat.id, "Неверный формат времени. Попробуйте ещё раз.")


# Функция для отложенной отправки поста
def schedule_post(user_id, post_time):
    # Ожидание до времени публикации
    while datetime.now() < post_time:
        time.sleep(5)

    # Проверка, что данные пользователя не были удалены
    if user_id in user_data:
        channel_id = user_data[user_id]["channel"]
        content = user_data[user_id]["content"]

        # Отправка содержимого (картинка + текст)
        photo_sent = False
        for item in content:
            if item["type"] == "photo" and item["file_id"]:
                caption = next((i["text"] for i in content if i["type"] == "text" and i["text"]), "")
                bot.send_photo(channel_id, item["file_id"], caption=caption)
                photo_sent = True

        if not photo_sent:
            text_content = next((i["text"] for i in content if i["type"] == "text" and i["text"]), None)
            if text_content:
                bot.send_message(channel_id, text_content)

        # Подтверждение отправки поста
        bot.send_message(user_id, "Ваш пост был успешно опубликован!")

        # Удаление данных после отправки
        del user_data[user_id]


# Запуск бота
bot.polling(none_stop=True)

Ответы (0 шт):