Интеграция Firecrawl с Telegram ботами для автоматического мониторинга и уведомлений
pip install python-telegram-bot requests schedule
import asyncio
import requests
from telegram import Update
from telegram.ext import Application, CommandHandler, MessageHandler, filters
# Конфигурация
TELEGRAM_TOKEN = "YOUR_TELEGRAM_BOT_TOKEN"
FIRECRAWL_API_KEY = "YOUR_FIRECRAWL_API_KEY"
FIRECRAWL_BASE_URL = "https://api.firecrawl.ru/v1"
class FirecrawlBot:
def __init__(self):
self.headers = {"X-API-Key": FIRECRAWL_API_KEY}
def scrape_url(self, url: str) -> dict:
"""Парсит URL через Firecrawl API"""
response = requests.post(
f"{FIRECRAWL_BASE_URL}/scrape",
headers=self.headers,
json={
"url": url,
"formats": ["markdown"],
"onlyMainContent": True
}
)
return response.json()
def search_content(self, query: str, ai_analysis: bool = False) -> dict:
"""Поиск контента с опциональным AI анализом"""
payload = {
"query": query,
"limit": 5,
"parseResults": ai_analysis,
"aiPrompt": f"Проанализируй результаты поиска по запросу '{query}' и выдели ключевые моменты"
}
response = requests.post(
f"{FIRECRAWL_BASE_URL}/search",
headers=self.headers,
json=payload
)
return response.json()
# Инициализация бота
bot = FirecrawlBot()
async def start(update: Update, context):
"""Команда /start"""
await update.message.reply_text(
"🔥 Firecrawl бот запущен!\n\n"
"Команды:\n"
"/scrape <URL> - парсинг страницы\n"
"/search <запрос> - поиск контента\n"
"/monitor <URL> - мониторинг изменений\n"
"/ai_search <запрос> - поиск с AI анализом"
)
async def scrape_command(update: Update, context):
"""Команда /scrape URL"""
if not context.args:
await update.message.reply_text("❌ Укажите URL: /scrape https://example.com")
return
url = context.args[0]
await update.message.reply_text(f"🔄 Парсим {url}...")
try:
result = bot.scrape_url(url)
if result.get('success'):
content = result['data']['markdown'][:1000] + "..." if len(result['data']['markdown']) > 1000 else result['data']['markdown']
await update.message.reply_text(
f"✅ **Результат парсинга:**\n\n{content}",
parse_mode='Markdown'
)
else:
await update.message.reply_text(f"❌ Ошибка: {result.get('error', 'Неизвестная ошибка')}")
except Exception as e:
await update.message.reply_text(f"❌ Ошибка: {str(e)}")
async def search_command(update: Update, context):
"""Команда /search запрос"""
if not context.args:
await update.message.reply_text("❌ Укажите запрос: /search новости технологий")
return
query = " ".join(context.args)
await update.message.reply_text(f"🔍 Ищем: {query}...")
try:
result = bot.search_content(query)
if result.get('success') and result['data']['pages']:
response = f"🔍 **Результаты поиска '{query}':**\n\n"
for i, page in enumerate(result['data']['pages'][:3], 1):
response += f"{i}. **{page['title']}**\n{page['url']}\n_{page['description']}_\n\n"
await update.message.reply_text(response, parse_mode='Markdown')
else:
await update.message.reply_text("❌ Ничего не найдено")
except Exception as e:
await update.message.reply_text(f"❌ Ошибка: {str(e)}")
async def ai_search_command(update: Update, context):
"""Команда /ai_search запрос"""
if not context.args:
await update.message.reply_text("❌ Укажите запрос: /ai_search тренды ИИ 2025")
return
query = " ".join(context.args)
await update.message.reply_text(f"🤖 AI анализ: {query}...")
try:
result = bot.search_content(query, ai_analysis=True)
if result.get('success') and result['data'].get('markdown'):
analysis = result['data']['markdown']
# Разбиваем длинный текст на части
if len(analysis) > 4000:
parts = [analysis[i:i+4000] for i in range(0, len(analysis), 4000)]
for i, part in enumerate(parts, 1):
await update.message.reply_text(
f"🤖 **AI Анализ (часть {i}/{len(parts)}):**\n\n{part}",
parse_mode='Markdown'
)
else:
await update.message.reply_text(
f"🤖 **AI Анализ:**\n\n{analysis}",
parse_mode='Markdown'
)
else:
await update.message.reply_text("❌ Не удалось получить AI анализ")
except Exception as e:
await update.message.reply_text(f"❌ Ошибка: {str(e)}")
# Запуск бота
async def main():
app = Application.builder().token(TELEGRAM_TOKEN).build()
# Регистрация команд
app.add_handler(CommandHandler("start", start))
app.add_handler(CommandHandler("scrape", scrape_command))
app.add_handler(CommandHandler("search", search_command))
app.add_handler(CommandHandler("ai_search", ai_search_command))
print("🤖 Telegram бот запущен!")
await app.run_polling()
if __name__ == "__main__":
asyncio.run(main())
import schedule
import time
from datetime import datetime
class ContentMonitor:
def __init__(self, bot_instance):
self.bot = bot_instance
self.monitored_urls = {} # {chat_id: [urls]}
self.last_content = {} # {url: content_hash}
def add_monitor(self, chat_id: int, url: str):
"""Добавить URL в мониторинг"""
if chat_id not in self.monitored_urls:
self.monitored_urls[chat_id] = []
self.monitored_urls[chat_id].append(url)
# Сохраняем начальный контент
result = self.bot.scrape_url(url)
if result.get('success'):
content_hash = hash(result['data']['markdown'])
self.last_content[url] = content_hash
def check_changes(self):
"""Проверка изменений на всех отслеживаемых URL"""
for chat_id, urls in self.monitored_urls.items():
for url in urls:
try:
result = self.bot.scrape_url(url)
if result.get('success'):
current_hash = hash(result['data']['markdown'])
if url in self.last_content and self.last_content[url] != current_hash:
# Контент изменился!
self.notify_change(chat_id, url)
self.last_content[url] = current_hash
except Exception as e:
print(f"Ошибка мониторинга {url}: {e}")
async def notify_change(self, chat_id: int, url: str):
"""Уведомление об изменении"""
message = f"🔔 **Изменения на сайте!**\n\n📍 {url}\n🕐 {datetime.now().strftime('%H:%M %d.%m.%Y')}"
# Здесь нужно отправить сообщение через Telegram API
# (требует доступ к bot application instance)
# Запуск мониторинга каждые 30 минут
schedule.every(30).minutes.do(monitor.check_changes)
while True:
schedule.run_pending()
time.sleep(60)
const TelegramBot = require('node-telegram-bot-api');
const axios = require('axios');
const TELEGRAM_TOKEN = 'YOUR_TELEGRAM_BOT_TOKEN';
const FIRECRAWL_API_KEY = 'YOUR_FIRECRAWL_API_KEY';
const FIRECRAWL_BASE_URL = 'https://api.firecrawl.ru/v1';
const bot = new TelegramBot(TELEGRAM_TOKEN, {polling: true});
// Firecrawl API wrapper
const firecrawl = {
headers: {'X-API-Key': FIRECRAWL_API_KEY},
async scrape(url) {
const response = await axios.post(`${FIRECRAWL_BASE_URL}/scrape`, {
url: url,
formats: ['markdown'],
onlyMainContent: true
}, {headers: this.headers});
return response.data;
},
async search(query, aiAnalysis = false) {
const response = await axios.post(`${FIRECRAWL_BASE_URL}/search`, {
query: query,
limit: 5,
parseResults: aiAnalysis,
aiPrompt: `Проанализируй результаты поиска по запросу "${query}"`
}, {headers: this.headers});
return response.data;
}
};
// Команды бота
bot.onText(/\/start/, (msg) => {
bot.sendMessage(msg.chat.id,
'🔥 Firecrawl бот запущен!\n\n' +
'Команды:\n' +
'/scrape <URL> - парсинг страницы\n' +
'/search <запрос> - поиск контента\n' +
'/ai_search <запрос> - поиск с AI анализом'
);
});
bot.onText(/\/scrape (.+)/, async (msg, match) => {
const url = match[1];
try {
bot.sendMessage(msg.chat.id, `🔄 Парсим ${url}...`);
const result = await firecrawl.scrape(url);
if (result.success) {
const content = result.data.markdown.substring(0, 1000) +
(result.data.markdown.length > 1000 ? '...' : '');
bot.sendMessage(msg.chat.id,
`✅ **Результат парсинга:**\n\n${content}`,
{parse_mode: 'Markdown'}
);
} else {
bot.sendMessage(msg.chat.id, `❌ Ошибка: ${result.error || 'Неизвестная ошибка'}`);
}
} catch (error) {
bot.sendMessage(msg.chat.id, `❌ Ошибка: ${error.message}`);
}
});
console.log('🤖 Telegram бот запущен!');
# Создать Procfile
echo "worker: python bot.py" > Procfile
# Развернуть
git init
git add .
git commit -m "Initial commit"
heroku create your-bot-name
git push heroku master
# Установка PM2
npm install -g pm2
# Запуск бота
pm2 start bot.py --name telegram-bot
pm2 startup
pm2 save
import schedule
def daily_digest():
"""Ежедневный дайджест новостей"""
result = bot.search_content("новости технологий", ai_analysis=True)
# Отправка всем подписчикам
schedule.every().day.at("09:00").do(daily_digest)
from flask import Flask, request
app = Flask(__name__)
@app.route('/webhook', methods=['POST'])
def webhook():
data = request.json
# Обработка уведомлений от внешних систем
# Автоматический парсинг и отправка в Telegram
return 'OK'