WordPress + Firecrawl

Автоматическое наполнение WordPress сайтов актуальным контентом.

Возможности интеграции

Content Automation

  • Автопостинг - Публикация статей из парсинга
  • Конкурентный анализ - Мониторинг сайтов конкурентов
  • Новостные дайджесты - Агрегация новостей по теме
  • SEO контент - Генерация статей с AI анализом

WooCommerce Integration

  • Парсинг товаров - Импорт каталогов конкурентов
  • Мониторинг цен - Отслеживание изменений цен
  • Описания товаров - AI генерация описаний
  • Отзывы клиентов - Сбор отзывов с других сайтов

WordPress Plugin создание

1. Структура плагина

firecrawl-integration/
├── firecrawl-integration.php
├── includes/
   ├── class-firecrawl-api.php
   ├── class-content-importer.php
   ├── class-admin-page.php
   └── class-scheduler.php
├── admin/
   ├── css/
   ├── js/
   └── partials/
└── public/
    ├── css/
    └── js/

2. Основной файл плагина

<?php
/**
 * Plugin Name: Firecrawl Integration
 * Description: Автоматический импорт контента через Firecrawl API
 * Version: 1.0.0
 * Author: Your Name
 */

// Предотвращаем прямой доступ
if (!defined('ABSPATH')) {
    exit;
}

// Основной класс плагина
class FirecrawlIntegration {
    
    private $api_key;
    private $api_url = 'https://api.firecrawl.ru/v1';
    
    public function __construct() {
        add_action('init', array($this, 'init'));
        add_action('admin_menu', array($this, 'add_admin_menu'));
        add_action('wp_ajax_firecrawl_import', array($this, 'ajax_import_content'));
        
        // Планировщик задач
        add_action('firecrawl_scheduled_import', array($this, 'scheduled_import'));
        
        if (!wp_next_scheduled('firecrawl_scheduled_import')) {
            wp_schedule_event(time(), 'hourly', 'firecrawl_scheduled_import');
        }
    }
    
    public function init() {
        $this->api_key = get_option('firecrawl_api_key');
    }
    
    // Добавляем страницу в админку
    public function add_admin_menu() {
        add_management_page(
            'Firecrawl Integration',
            'Firecrawl',
            'manage_options',
            'firecrawl-integration',
            array($this, 'admin_page')
        );
    }
    
    // Страница настроек в админке
    public function admin_page() {
        ?>
        <div class="wrap">
            <h1>Firecrawl Integration</h1>
            
            <form method="post" action="options.php">
                <?php
                settings_fields('firecrawl_settings');
                do_settings_sections('firecrawl_settings');
                ?>
                
                <table class="form-table">
                    <tr>
                        <th scope="row">API Key</th>
                        <td>
                            <input type="text" name="firecrawl_api_key" 
                                   value="<?php echo esc_attr(get_option('firecrawl_api_key')); ?>" 
                                   class="regular-text" />
                            <p class="description">Введите ваш Firecrawl API ключ</p>
                        </td>
                    </tr>
                    
                    <tr>
                        <th scope="row">Автоимпорт</th>
                        <td>
                            <label>
                                <input type="checkbox" name="firecrawl_auto_import" 
                                       value="1" <?php checked(1, get_option('firecrawl_auto_import'), true); ?> />
                                Включить автоматический импорт контента
                            </label>
                        </td>
                    </tr>
                    
                    <tr>
                        <th scope="row">Поисковые запросы</th>
                        <td>
                            <textarea name="firecrawl_search_queries" rows="5" cols="50" class="large-text"><?php 
                                echo esc_textarea(get_option('firecrawl_search_queries', 'новости технологий\nстартапы инвестиции\nИИ разработка')); 
                            ?></textarea>
                            <p class="description">Каждый запрос с новой строки</p>
                        </td>
                    </tr>
                </table>
                
                <?php submit_button(); ?>
            </form>
            
            <hr>
            
            <h2>Ручной импорт</h2>
            <div id="firecrawl-import-section">
                <input type="text" id="firecrawl-url" placeholder="URL для парсинга" class="regular-text" />
                <button id="firecrawl-import-btn" class="button button-primary">Импортировать</button>
                
                <div id="firecrawl-import-result" style="margin-top: 20px;"></div>
            </div>
            
            <script>
            jQuery(document).ready(function($) {
                $('#firecrawl-import-btn').click(function() {
                    var url = $('#firecrawl-url').val();
                    if (!url) {
                        alert('Введите URL');
                        return;
                    }
                    
                    $('#firecrawl-import-result').html('<p>Импортируем контент...</p>');
                    
                    $.ajax({
                        url: ajaxurl,
                        type: 'POST',
                        data: {
                            action: 'firecrawl_import',
                            url: url,
                            nonce: '<?php echo wp_create_nonce('firecrawl_import'); ?>'
                        },
                        success: function(response) {
                            if (response.success) {
                                $('#firecrawl-import-result').html('<p style="color: green;">Контент успешно импортирован! <a href="' + response.data.edit_link + '">Редактировать пост</a></p>');
                            } else {
                                $('#firecrawl-import-result').html('<p style="color: red;">Ошибка: ' + response.data + '</p>');
                            }
                        },
                        error: function() {
                            $('#firecrawl-import-result').html('<p style="color: red;">Произошла ошибка при импорте</p>');
                        }
                    });
                });
            });
            </script>
        </div>
        <?php
    }
    
    // AJAX обработка импорта
    public function ajax_import_content() {
        // Проверка nonce для безопасности
        if (!wp_verify_nonce($_POST['nonce'], 'firecrawl_import')) {
            wp_die('Security check failed');
        }
        
        $url = sanitize_url($_POST['url']);
        if (!$url) {
            wp_send_json_error('Invalid URL');
            return;
        }
        
        // Парсим контент через Firecrawl
        $content_data = $this->scrape_content($url);
        
        if ($content_data && $content_data['success']) {
            // Создаем пост в WordPress
            $post_id = $this->create_post_from_content($content_data['data'], $url);
            
            if ($post_id) {
                wp_send_json_success(array(
                    'post_id' => $post_id,
                    'edit_link' => admin_url('post.php?post=' . $post_id . '&action=edit')
                ));
            } else {
                wp_send_json_error('Failed to create post');
            }
        } else {
            wp_send_json_error('Failed to scrape content');
        }
    }
    
    // Парсинг контента через Firecrawl API
    private function scrape_content($url) {
        if (!$this->api_key) {
            return false;
        }
        
        $response = wp_remote_post($this->api_url . '/scrape', array(
            'headers' => array(
                'X-API-Key' => $this->api_key,
                'Content-Type' => 'application/json'
            ),
            'body' => json_encode(array(
                'url' => $url,
                'formats' => array('markdown'),
                'onlyMainContent' => true
            )),
            'timeout' => 30
        ));
        
        if (is_wp_error($response)) {
            return false;
        }
        
        $body = wp_remote_retrieve_body($response);
        return json_decode($body, true);
    }
    
    // Создание поста из контента
    private function create_post_from_content($content_data, $source_url) {
        $markdown = $content_data['markdown'] ?? '';
        $metadata = $content_data['metadata'] ?? array();
        
        // Конвертируем Markdown в HTML
        $html_content = $this->markdown_to_html($markdown);
        
        // Определяем заголовок
        $title = $metadata['title'] ?? 'Imported Content from ' . parse_url($source_url, PHP_URL_HOST);
        
        // Данные поста
        $post_data = array(
            'post_title' => sanitize_text_field($title),
            'post_content' => wp_kses_post($html_content),
            'post_status' => 'draft', // Сохраняем как черновик для проверки
            'post_type' => 'post',
            'post_category' => array(get_option('default_category')),
            'meta_input' => array(
                'firecrawl_source_url' => $source_url,
                'firecrawl_import_date' => current_time('mysql'),
                'firecrawl_original_title' => $metadata['title'] ?? '',
                'firecrawl_description' => $metadata['description'] ?? ''
            )
        );
        
        $post_id = wp_insert_post($post_data);
        
        return $post_id;
    }
    
    // Простая конвертация Markdown в HTML
    private function markdown_to_html($markdown) {
        // Заголовки
        $html = preg_replace('/^### (.*$)/m', '<h3>$1</h3>', $markdown);
        $html = preg_replace('/^## (.*$)/m', '<h2>$1</h2>', $html);
        $html = preg_replace('/^# (.*$)/m', '<h1>$1</h1>', $html);
        
        // Ссылки
        $html = preg_replace('/\[([^\]]+)\]\(([^)]+)\)/', '<a href="$2">$1</a>', $html);
        
        // Жирный текст
        $html = preg_replace('/\*\*(.*?)\*\*/', '<strong>$1</strong>', $html);
        
        // Курсив
        $html = preg_replace('/\*(.*?)\*/', '<em>$1</em>', $html);
        
        // Параграфы
        $html = '<p>' . str_replace(array("\r\n", "\n", "\r"), '</p><p>', $html) . '</p>';
        $html = str_replace('<p></p>', '', $html);
        
        return $html;
    }
    
    // Автоматический импорт по расписанию
    public function scheduled_import() {
        if (!get_option('firecrawl_auto_import')) {
            return;
        }
        
        $queries = get_option('firecrawl_search_queries', '');
        if (empty($queries)) {
            return;
        }
        
        $queries_array = explode("\n", $queries);
        
        foreach ($queries_array as $query) {
            $query = trim($query);
            if (empty($query)) continue;
            
            // Поиск контента через Firecrawl
            $search_results = $this->search_content($query);
            
            if ($search_results && $search_results['success']) {
                $pages = $search_results['data']['pages'] ?? array();
                
                // Импортируем первые 2 результата
                foreach (array_slice($pages, 0, 2) as $page) {
                    // Проверяем, не импортировали ли мы уже этот URL
                    $existing = get_posts(array(
                        'meta_key' => 'firecrawl_source_url',
                        'meta_value' => $page['url'],
                        'post_type' => 'post',
                        'numberposts' => 1
                    ));
                    
                    if (empty($existing)) {
                        $content_data = $this->scrape_content($page['url']);
                        if ($content_data && $content_data['success']) {
                            $this->create_post_from_content($content_data['data'], $page['url']);
                        }
                    }
                }
            }
        }
    }
    
    // Поиск контента через Firecrawl API
    private function search_content($query) {
        if (!$this->api_key) {
            return false;
        }
        
        $response = wp_remote_post($this->api_url . '/search', array(
            'headers' => array(
                'X-API-Key' => $this->api_key,
                'Content-Type' => 'application/json'
            ),
            'body' => json_encode(array(
                'query' => $query,
                'limit' => 5,
                'parseResults' => false
            )),
            'timeout' => 30
        ));
        
        if (is_wp_error($response)) {
            return false;
        }
        
        $body = wp_remote_retrieve_body($response);
        return json_decode($body, true);
    }
}

// Инициализируем плагин
new FirecrawlIntegration();

// Регистрируем настройки
add_action('admin_init', 'firecrawl_admin_init');

function firecrawl_admin_init() {
    register_setting('firecrawl_settings', 'firecrawl_api_key');
    register_setting('firecrawl_settings', 'firecrawl_auto_import');
    register_setting('firecrawl_settings', 'firecrawl_search_queries');
}

// Очистка задач при деактивации
register_deactivation_hook(__FILE__, 'firecrawl_deactivation');

function firecrawl_deactivation() {
    wp_clear_scheduled_hook('firecrawl_scheduled_import');
}
?>

WooCommerce интеграция

Парсинг товаров

<?php
// Дополнительный класс для WooCommerce
class FirecrawlWooCommerce {
    
    public function __construct() {
        add_action('admin_menu', array($this, 'add_woo_menu'));
        add_action('wp_ajax_firecrawl_import_products', array($this, 'import_products'));
    }
    
    public function add_woo_menu() {
        add_submenu_page(
            'woocommerce',
            'Firecrawl Products',
            'Import Products',
            'manage_woocommerce',
            'firecrawl-products',
            array($this, 'products_page')
        );
    }
    
    public function import_products() {
        $competitor_url = sanitize_url($_POST['competitor_url']);
        
        // Парсим страницу каталога
        $content = $this->scrape_catalog($competitor_url);
        
        if ($content && $content['success']) {
            $products = $this->extract_products($content['data']['markdown']);
            
            foreach ($products as $product_data) {
                $this->create_woo_product($product_data);
            }
            
            wp_send_json_success(array('imported' => count($products)));
        } else {
            wp_send_json_error('Failed to scrape catalog');
        }
    }
    
    private function extract_products($markdown) {
        // Простая логика извлечения товаров из markdown
        $products = array();
        
        // Ищем структуры типа:
        // ## Название товара
        // Цена: 1990 руб
        // Описание...
        
        $pattern = '/##\s*([^\n]+)\n.*?(?:цена|price):\s*([0-9,.\s]+).*?\n(.*?)(?=##|$)/is';
        preg_match_all($pattern, $markdown, $matches, PREG_SET_ORDER);
        
        foreach ($matches as $match) {
            $products[] = array(
                'name' => trim($match[1]),
                'price' => $this->extract_price($match[2]),
                'description' => trim($match[3])
            );
        }
        
        return $products;
    }
    
    private function extract_price($price_text) {
        preg_match('/([0-9,.\s]+)/', $price_text, $matches);
        return isset($matches[1]) ? floatval(str_replace(array(',', ' '), '', $matches[1])) : 0;
    }
    
    private function create_woo_product($product_data) {
        $post_data = array(
            'post_title' => $product_data['name'],
            'post_content' => $product_data['description'],
            'post_status' => 'draft',
            'post_type' => 'product',
        );
        
        $product_id = wp_insert_post($post_data);
        
        if ($product_id) {
            // Устанавливаем цену
            update_post_meta($product_id, '_regular_price', $product_data['price']);
            update_post_meta($product_id, '_price', $product_data['price']);
            
            // Устанавливаем тип товара
            wp_set_object_terms($product_id, 'simple', 'product_type');
            
            // Помечаем как импортированный
            update_post_meta($product_id, '_firecrawl_imported', 'yes');
        }
        
        return $product_id;
    }
}

// Инициализируем, если WooCommerce активен
if (class_exists('WooCommerce')) {
    new FirecrawlWooCommerce();
}
?>

Shortcodes для контента

<?php
// Шорткоды для вставки динамического контента
add_shortcode('firecrawl_content', 'firecrawl_content_shortcode');

function firecrawl_content_shortcode($atts) {
    $atts = shortcode_atts(array(
        'url' => '',
        'query' => '',
        'limit' => 3,
        'format' => 'list' // list, grid, simple
    ), $atts);
    
    if (empty($atts['url']) && empty($atts['query'])) {
        return '<p>Укажите URL или поисковый запрос</p>';
    }
    
    $firecrawl = new FirecrawlIntegration();
    
    if (!empty($atts['url'])) {
        // Парсим конкретный URL
        $result = $firecrawl->scrape_content($atts['url']);
        if ($result && $result['success']) {
            return '<div class="firecrawl-content">' . 
                   wp_kses_post($firecrawl->markdown_to_html($result['data']['markdown'])) . 
                   '</div>';
        }
    } elseif (!empty($atts['query'])) {
        // Поиск и отображение результатов
        $results = $firecrawl->search_content($atts['query']);
        if ($results && $results['success']) {
            $output = '<div class="firecrawl-search-results">';
            
            foreach (array_slice($results['data']['pages'], 0, $atts['limit']) as $page) {
                if ($atts['format'] == 'grid') {
                    $output .= '<div class="firecrawl-item-grid">';
                } else {
                    $output .= '<div class="firecrawl-item-list">';
                }
                
                $output .= '<h3><a href="' . esc_url($page['url']) . '" target="_blank">' . 
                          esc_html($page['title']) . '</a></h3>';
                $output .= '<p>' . esc_html($page['description']) . '</p>';
                $output .= '</div>';
            }
            
            $output .= '</div>';
            return $output;
        }
    }
    
    return '<p>Контент не найден</p>';
}

// CSS стили для шорткодов
add_action('wp_head', 'firecrawl_shortcode_styles');

function firecrawl_shortcode_styles() {
    echo '<style>
        .firecrawl-content {
            border: 1px solid #ddd;
            padding: 20px;
            margin: 20px 0;
            background: #f9f9f9;
        }
        
        .firecrawl-search-results {
            display: flex;
            flex-wrap: wrap;
            gap: 20px;
        }
        
        .firecrawl-item-grid {
            flex: 1 1 calc(33% - 20px);
            border: 1px solid #eee;
            padding: 15px;
            background: white;
        }
        
        .firecrawl-item-list {
            width: 100%;
            border-bottom: 1px solid #eee;
            padding: 15px 0;
        }
        
        .firecrawl-item-grid h3,
        .firecrawl-item-list h3 {
            margin-top: 0;
            margin-bottom: 10px;
        }
        
        .firecrawl-item-grid a,
        .firecrawl-item-list a {
            text-decoration: none;
            color: #0073aa;
        }
    </style>';
}
?>

Использование в WordPress

1. В админке

  • Перейдите в Инструменты → Firecrawl
  • Введите API ключ
  • Настройте поисковые запросы
  • Включите автоимпорт

2. Шорткоды в постах

[firecrawl_content url="https://example.com/article"]

[firecrawl_content query="новости ИИ" limit="5" format="grid"]

[firecrawl_content query="стартапы инвестиции" format="list"]

3. В шаблонах тем

<?php
// В файлах темы
if (function_exists('firecrawl_content_shortcode')) {
    echo do_shortcode('[firecrawl_content query="' . get_the_category()[0]->name . '" limit="3"]');
}
?>

Автоматизация контента

Cron задачи

  • Ежечасно - Импорт новых статей
  • Ежедневно - Обновление существующих
  • Еженедельно - Очистка старого контента

Фильтрация контента

// Хук для фильтрации импортируемого контента
add_filter('firecrawl_before_import', 'custom_content_filter', 10, 2);

function custom_content_filter($content, $source_url) {
    // Исключаем контент с определенных доменов
    $blocked_domains = array('spam-site.com', 'low-quality.org');
    
    foreach ($blocked_domains as $domain) {
        if (strpos($source_url, $domain) !== false) {
            return false; // Не импортировать
        }
    }
    
    // Проверяем минимальную длину
    if (strlen($content['markdown']) < 500) {
        return false;
    }
    
    return $content;
}

SEO оптимизация

Мета-данные из парсинга

// Автоматическое заполнение SEO полей
add_action('save_post', 'firecrawl_seo_meta', 10, 2);

function firecrawl_seo_meta($post_id, $post) {
    $source_url = get_post_meta($post_id, 'firecrawl_source_url', true);
    
    if ($source_url) {
        // Yoast SEO integration
        if (function_exists('YoastSEO')) {
            $description = get_post_meta($post_id, 'firecrawl_description', true);
            if ($description) {
                update_post_meta($post_id, '_yoast_wpseo_metadesc', $description);
            }
        }
        
        // Canonical URL
        update_post_meta($post_id, '_yoast_wpseo_canonical', $source_url);
    }
}
WordPress интеграция открывает огромные возможности для автоматизации контента и монетизации!