Интеграция с Telegram ботами

Создайте мощных Telegram ботов с веб-скрейпингом и AI анализом.

Популярные кейсы

  • Мониторинг цен конкурентов с уведомлениями
  • Новостные дайджесты с AI анализом
  • Отслеживание вакансий и автоматические заявки
  • SEO мониторинг изменений на сайтах
  • Парсинг объявлений недвижимости/авто

Что понадобится

  1. Telegram Bot Token - получить у @BotFather
  2. Firecrawl API Key - из личного кабинета
  3. Python 3.8+ или Node.js
  4. 5 минут времени ⏱️

Python реализация

1. Установка зависимостей

pip install python-telegram-bot requests schedule

2. Базовый бот с парсингом

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)

JavaScript/Node.js версия

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 бот запущен!');

Деплой бота

Heroku (бесплатно)

# Создать 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

VPS сервер

# Установка 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)

Webhook для уведомлений

from flask import Flask, request

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    data = request.json
    # Обработка уведомлений от внешних систем
    # Автоматический парсинг и отправка в Telegram
    return 'OK'

Преимущества Telegram ботов

  • 95% доставляемость сообщений
  • Мгновенные уведомления в реальном времени
  • Кроссплатформенность (iOS, Android, Web, Desktop)
  • Простая интеграция с API

Готовые шаблоны

Telegram боты - это самый быстрый способ донести parsed данные до пользователей в России! 🚀