Хотите автоматизировать создание контента? Мы создали бота, который берет шедевры из крупнейшего музея мира (более 470,000 экспонатов!), генерирует к ним уникальные описания через GPT и автоматически публикует в Telegram и Дзен.
Главная фишка - контента хватит на 60+ лет ежедневных публикаций! Вы просто запускаете бота и получаете:
- 10 уникальных постов каждый день
- Автопубликация в заданное время
- Синхронизация с Дзеном
- Никакого копирайтинга или поиска контента
А теперь самое главное - полный код бота:
```python
import asyncio
from openai import OpenAI
from telegram import Bot
import logging
from datetime import datetime
import random
import pytz
import requests
from typing import Optional, Dict, Any
import json
# Настройка логирования
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('met_bot.log', encoding='utf-8'),
logging.StreamHandler()
]
)
logger = logging.getLogger(__name__)
# Конфигурация - замените на свои значения
TELEGRAM_TOKEN = "TELEGRAM_BOT_TOKEN"
OPENAI_API_KEY = "OPENAI_API_KEY"
CHANNEL_ID = "CHANNEL_ID"
OPENAI_MODEL = "gpt-4o-mini"
class MetMuseumBot:
def __init__(self):
logger.info("Запуск бота")
self.bot = Bot(TELEGRAM_TOKEN)
self.client = OpenAI(api_key=OPENAI_API_KEY)
self.moscow_tz = pytz.timezone('Europe/Moscow')
self.base_url = "https://collectionapi.metmuseum.org/public/collection/v1"
self.published_items = set()
logger.info("Бот инициализирован успешно")
async def get_random_exhibit(self) -> Optional[Dict[str, Any]]:
try:
response = requests.get(f"{self.base_url}/objects", timeout=10)
response.raise_for_status()
data = response.json()
object_id = random.choice(data['objectIDs'])
object_response = requests.get(f"{self.base_url}/objects/{object_id}", timeout=10)
object_response.raise_for_status()
item = object_response.json()
if not item.get('primaryImage'):
logger.warning(f"Нет изображения для объекта {object_id}")
return None
result = {
'id': str(object_id),
'title': item.get('title', 'Без названия'),
'description': item.get('description', ''),
'image_url': item['primaryImage'],
'artist': item.get('artistDisplayName', 'Неизвестный автор'),
'date': item.get('objectDate', 'Дата неизвестна'),
'medium': item.get('medium', ''),
'department': item.get('department', ''),
'source': 'The Metropolitan Museum of Art'
}
logger.info(f"Успешно получен экспонат: {result['title']}")
return result
except Exception as e:
logger.error(f"Ошибка при получении экспоната: {str(e)}")
return None
def translate_and_format(self, exhibit: Dict[str, Any]) -> Optional[str]:
try:
prompt = f"""Создай краткое и ёмкое описание произведения искусства на русском языке. Общая длина ответа должна быть не более 800 символов.
Название: {exhibit['title']}
Художник: {exhibit['artist']}
Дата: {exhibit['date']}
Техника: {exhibit['medium']}
Отдел: {exhibit['department']}
Описание: {exhibit['description']}
Формат ответа (строго до 800 символов):
🎨 [Краткое название на русском]
[Лаконичное описание произведения и художника, 2-3 предложения]
📌 [Один короткий интересный факт]
🏛 {exhibit['source']}
#теги: [3-4 тега, основанных на: период/эпоха, стиль, техника]"""
response = self.client.chat.completions.create(
model=OPENAI_MODEL,
messages=[
{"role": "system", "content": "Ты - увлеченный искусствовед с глубокими знаниями истории искусств."},
{"role": "user", "content": prompt}
],
temperature=0.7,
max_tokens=500
)
text = response.choices[0].message.content
logger.info(f"Получен перевод длиной {len(text)} символов")
return text
except Exception as e:
logger.error(f"Ошибка при переводе: {str(e)}")
return None
async def send_exhibit(self, text: str, image_url: str) -> bool:
try:
if len(text) > 1000:
logger.warning(f"Текст слишком длинный ({len(text)} символов)")
return False
response = requests.get(image_url, timeout=10)
if response.status_code == 200:
await self.bot.send_photo(
chat_id=CHANNEL_ID,
photo=response.content,
caption=text,
parse_mode="Markdown"
)
logger.info("Сообщение отправлено успешно")
return True
except Exception as e:
logger.error(f"Ошибка при отправке: {str(e)}")
return False
async def run(self):
try:
while True:
try:
await self.wait_until_next_run()
logger.info("Начало нового цикла публикации")
published_count = 0
while published_count < 10:
try:
exhibit = await self.get_random_exhibit()
if not exhibit:
await asyncio.sleep(5)
continue
if exhibit['id'] in self.published_items:
continue
text = self.translate_and_format(exhibit)
if not text:
continue
if await self.send_exhibit(text, exhibit['image_url']):
self.published_items.add(exhibit['id'])
published_count += 1
logger.info(f"Опубликовано {published_count}/10")
await asyncio.sleep(random.randint(60, 120))
except Exception as e:
logger.error(f"Ошибка при публикации: {str(e)}")
await asyncio.sleep(5)
except Exception as e:
logger.error(f"Ошибка в цикле: {str(e)}")
await asyncio.sleep(60)
except Exception as e:
logger.critical(f"Критическая ошибка: {str(e)}")
if __name__ == "__main__":
try:
bot = MetMuseumBot()
asyncio.run(bot.run())
except KeyboardInterrupt:
logger.info("Бот остановлен пользователем")
except Exception as e:
logger.critical(f"Неожиданная ошибка: {str(e)}")
```
Как запустить:
1. Создайте бота через @BotFather в Telegram
2. Получите API ключ OpenAI
3. Вставьте токены в код выше
4. Установите необходимые библиотеки:
```bash
pip3 install python-telegram-bot openai requests pytz
```
5. Запустите скрипт:
```bash
python bot.py
```
Для синхронизации с Дзеном:
1. Зайдите в настройки канала
2. Найдите раздел "Кросспостинг"
3. Получите код и отправьте его боту @zen_sync_bot в Telegram
Бот начнет публиковать 10 уникальных постов каждый день в 12:00 по МСК. Контента из Met Museum хватит на десятилетия вперед - в базе более 470,000 экспонатов!
Посмотреть как это работает можно здесь:
https://dzen.ru/museumart
#автоматизация #python #telegram #дзен #боты