Spaces:
No application file
No application file
File size: 8,488 Bytes
038c7d7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
import asyncio
import logging
import os
from datetime import datetime
from aiogram import Bot, Dispatcher, types
from aiogram.contrib.fsm_storage.memory import MemoryStorage
from aiogram.dispatcher import FSMContext
from aiogram.dispatcher.filters.state import State, StatesGroup
from aiogram.utils import executor
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
# Настройки
BOT_TOKEN = "7903604359:AAFRZc1r8zqIQiX1N-VJJadRfmDf5ljf1Jg" # Замените на токен вашего бота
INSTAGRAM_APP_ID = "YOUR_INSTAGRAM_APP_ID" # Замените на ID вашего приложения Instagram
INSTAGRAM_APP_SECRET = "YOUR_INSTAGRAM_APP_SECRET" # Замените на секрет вашего приложения Instagram
INSTAGRAM_REDIRECT_URI = "YOUR_INSTAGRAM_REDIRECT_URI" # Замените на URI перенаправления
# Временное хранилище (для простоты)
user_data = {}
scheduled_posts = {}
# Временное хранилище для видео и описаний
video_data = {}
# Состояния для FSM
class ConnectAccount(StatesGroup):
platform = State()
class UploadVideo(StatesGroup):
video = State()
description = State()
publish_time = State()
logging.basicConfig(level=logging.INFO)
bot = Bot(token=BOT_TOKEN)
storage = MemoryStorage()
dp = Dispatcher(bot, storage=storage)
scheduler = AsyncIOScheduler()
# --- Хэндлеры ---
@dp.message_handler(commands=['start'])
async def send_welcome(message: types.Message):
await message.reply("Привет! Этот бот поможет тебе планировать публикации в TikTok, Instagram и YouTube.")
@dp.message_handler(commands=['connect'])
async def connect_command(message: types.Message):
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True, selective=True)
keyboard.add("Instagram (тест)") # Пока добавим только Instagram для упрощения
# keyboard.add("TikTok (скоро)")
# keyboard.add("YouTube (скоро)")
await message.reply("Выберите платформу для подключения:", reply_markup=keyboard)
await ConnectAccount.platform.set()
@dp.message_handler(state=ConnectAccount.platform, text="Instagram (тест)")
async def process_connect_instagram(message: types.Message, state: FSMContext):
# TODO: Реализовать OAuth 2.0 flow для Instagram
auth_url = f"https://api.instagram.com/oauth/authorize?client_id={INSTAGRAM_APP_ID}&redirect_uri={INSTAGRAM_REDIRECT_URI}&scope=user_profile,user_media&response_type=code"
await message.reply(f"Для подключения Instagram перейдите по ссылке:\n{auth_url}\n\nПосле авторизации вы будете перенаправлены на страницу с кодом. Скопируйте этот код и отправьте его мне.")
await state.finish() # Временный финиш, обработка кода будет в отдельном хэндлере
@dp.message_handler(commands=['upload'])
async def upload_command(message: types.Message):
await message.reply("Пожалуйста, отправьте видео для публикации.")
await UploadVideo.video.set()
@dp.message_handler(state=UploadVideo.video, content_types=types.ContentType.VIDEO)
async def process_video(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['video'] = message.video.file_id
await message.reply("Отлично! Теперь, пожалуйста, напишите описание к видео (или отправьте '-' если описания нет).")
await UploadVideo.description.set()
@dp.message_handler(state=UploadVideo.description)
async def process_description(message: types.Message, state: FSMContext):
async with state.proxy() as data:
data['description'] = message.text if message.text != '-' else ""
keyboard = types.ReplyKeyboardMarkup(resize_keyboard=True, selective=True)
keyboard.add("Сейчас")
keyboard.add("Указать время")
await message.reply("Когда вы хотите опубликовать видео?", reply_markup=keyboard)
await UploadVideo.publish_time.set()
@dp.message_handler(state=UploadVideo.publish_time, text="Сейчас")
async def process_publish_now(message: types.Message, state: FSMContext):
async with state.proxy() as data:
video_file = await bot.get_file(data['video'])
video_path = video_file.file_path
description = data['description']
# TODO: Реализовать немедленную публикацию в выбранные соцсети
await message.reply(f"Видео будет опубликовано прямо сейчас с описанием: {description}")
# Временная имитация публикации
await asyncio.sleep(2)
await message.reply("Видео успешно опубликовано (имитация).")
await state.finish()
@dp.message_handler(state=UploadVideo.publish_time, text="Указать время")
async def process_set_publish_time(message: types.Message):
await message.reply("Пожалуйста, укажите желаемое время публикации в формате ГГГГ-ММ-ДД ЧЧ:ММ (например, 2025-03-22 15:00).")
await dp.current_state().set_state(UploadVideo.publish_time) # Остаемся в этом состоянии для обработки времени
@dp.message_handler(state=UploadVideo.publish_time)
async def process_publish_time_input(message: types.Message, state: FSMContext):
try:
publish_at = datetime.strptime(message.text, '%Y-%m-%d %H:%M')
if publish_at <= datetime.now():
await message.reply("Указанное время уже прошло. Пожалуйста, выберите будущее время.")
return
async with state.proxy() as data:
video_file = await bot.get_file(data['video'])
video_path = video_file.file_path
description = data['description']
user_id = message.from_user.id
post_id = f"{user_id}_{datetime.now().timestamp()}"
scheduled_posts[post_id] = {
'user_id': user_id,
'video_path': video_path,
'description': description,
'publish_at': publish_at,
'platforms': ['instagram'] # Пока только одна платформа
}
scheduler.add_job(publish_scheduled_post, 'date', run_date=publish_at, args=[bot, post_id, scheduled_posts])
await message.reply(f"Видео запланировано к публикации на {publish_at.strftime('%Y-%m-%d %H:%M')} с описанием: {description}")
except ValueError:
await message.reply("Неверный формат времени. Пожалуйста, используйте формат ГГГГ-ММ-ДД ЧЧ:ММ.")
return
await state.finish()
async def publish_scheduled_post(bot: Bot, post_id: str, scheduled_posts: dict):
post_data = scheduled_posts.get(post_id)
if post_data:
user_id = post_data['user_id']
video_path = post_data['video_path']
description = post_data['description']
platforms = post_data['platforms']
# TODO: Реализовать фактическую публикацию в Instagram API
# Вам потребуется получить токен доступа пользователя
await bot.send_message(user_id, f"Начинаю публикацию запланированного видео с описанием: {description} в {platforms}")
# Временная имитация публикации
await asyncio.sleep(5)
await bot.send_message(user_id, f"Видео успешно опубликовано (имитация) в {platforms}.")
del scheduled_posts[post_id]
else:
logging.warning(f"Запланированный пост с ID {post_id} не найден.")
async def main():
scheduler.start()
await dp.start_polling()
if __name__ == '__main__':
asyncio.run(main())
|