镖师 发表于 2025-9-13 22:59:30

Wordpress免费自动生成文章插件

<?php/** * Plugin Name: 讯飞星火AI文章生成器 * Description: 根据文章标签自动生成相关内容并推荐,支持分类继承与内容清理 * Version: 1.0.3 * Author: zoiezhu */// 防止直接访问if (!defined('ABSPATH')) {    exit;}// 引入必要的WebSocket库require_once plugin_dir_path(__FILE__) . 'vendor/autoload.php';use WebSocket\Client;class XunfeiAIArticleGenerator {    private $daily_limit = 100;    private $option_name = 'xunfei_ai_daily_count';      // 讯飞星火API配置    private $app_id = '';    private $api_key = '';    private $api_secret = '';    private $ws_url = 'wss://aichat.xf-yun.com/v1/chat';      // 需要过滤的无效词语    private $filter_words = array(      '揭秘', '探索', '解析', '深度', '浅谈', '浅析', '标题:', '标题:',         '标题', '【', '】', '《', '》', '小编', '笔者', '文章', '专题',      '独家', '重磅', '惊爆', '震惊', '惊呆了', '太震撼', '不看后悔',      '必看', '必备', '收藏', '转发', '分享', '点赞', '关注'    );      public function __construct() {      add_action('wp_footer', array($this, 'maybe_generate_articles'));      add_filter('the_content', array($this, 'add_recommendations'));      add_action('xunfei_daily_reset', array($this, 'reset_daily_count'));                // 注册每日重置任务      if (!wp_next_scheduled('xunfei_daily_reset')) {            wp_schedule_event(time(), 'daily', 'xunfei_daily_reset');      }                // 添加管理菜单      add_action('admin_menu', array($this, 'add_admin_menu'));                // 注册分类选择相关的钩子      add_action('admin_init', array($this, 'register_category_settings'));      add_action('add_meta_boxes', array($this, 'add_category_meta_box'));      add_action('save_post', array($this, 'save_category_meta_box'));    }      // 添加管理菜单    public function add_admin_menu() {      add_options_page(            '讯飞AI设置',            '讯飞AI设置',            'manage_options',            'xunfei-ai-settings',            array($this, 'plugin_settings_page')      );    }      // 注册分类设置    public function register_category_settings() {      register_setting('xunfei_ai_options', 'xunfei_daily_limit');      register_setting('xunfei_ai_options', 'xunfei_app_id');      register_setting('xunfei_ai_options', 'xunfei_api_key');      register_setting('xunfei_ai_options', 'xunfei_api_secret');      register_setting('xunfei_ai_options', 'xunfei_filter_words');      register_setting('xunfei_ai_options', 'xunfei_target_categories');    }      // 分类选择    public function add_category_meta_box() {      add_meta_box(            'xunfei_category_meta_box',            '讯飞AI文章生成设置',            array($this, 'render_category_meta_box'),            'post',            'side',            'default'      );    }      public function render_category_meta_box($post) {      wp_nonce_field('xunfei_category_meta_box', 'xunfei_category_nonce');                $selected_categories = get_post_meta($post->ID, '_xunfei_target_categories', true);      if (empty($selected_categories)) {            $selected_categories = array();      }                $all_categories = get_categories(array('hide_empty' => false));                echo '<p>选择AI生成文章的目标分类(不选则使用默认设置):</p>';                foreach ($all_categories as $category) {            $checked = in_array($category->term_id, $selected_categories) ? 'checked' : '';            echo '<label style="display: block; margin-bottom: 5px;">';            echo '<input type="checkbox" name="xunfei_target_categories[]" value="' . $category->term_id . '" ' . $checked . '> ';            echo $category->name;            echo '</label>';      }                echo '<p class="description">如果设置了目标分类,AI生成的文章将只放入这些分类中</p>';    }      public function save_category_meta_box($post_id) {      if (!isset($_POST['xunfei_category_nonce']) ||             !wp_verify_nonce($_POST['xunfei_category_nonce'], 'xunfei_category_meta_box')) {            return;      }                if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {            return;      }                if (!current_user_can('edit_post', $post_id)) {            return;      }                if (isset($_POST['xunfei_target_categories'])) {            $categories = array_map('intval', $_POST['xunfei_target_categories']);            update_post_meta($post_id, '_xunfei_target_categories', $categories);      } else {            delete_post_meta($post_id, '_xunfei_target_categories');      }    }      // 插件设置    public function plugin_settings_page() {      $all_categories = get_categories(array('hide_empty' => false));      $selected_categories = get_option('xunfei_target_categories', array());      ?>      <div class="wrap">            <h1>讯飞星火AI文章生成器设置</h1>            <form method="post" action="options.php">                <?php                settings_fields('xunfei_ai_options');                do_settings_sections('xunfei_ai_options');                ?>                <table class="form-table">                  <tr valign="top">                        <th scope="row">每日生成限制</th>                        <td>                            <input type="number" name="xunfei_daily_limit" value="<?php echo esc_attr(get_option('xunfei_daily_limit', 100)); ?>" />                            <p class="description">每天最多生成的文章数量</p>                        </td>                  </tr>                  <tr valign="top">                        <th scope="row">APP ID</th>                        <td>                            <input type="text" name="xunfei_app_id" value="<?php echo esc_attr(get_option('xunfei_app_id', 'ceda898c')); ?>" class="regular-text" />                        </td>                  </tr>                  <tr valign="top">                        <th scope="row">API Key</th>                        <td>                            <input type="text" name="xunfei_api_key" value="<?php echo esc_attr(get_option('xunfei_api_key', '97aac13819dfe17d17af646a7780ac56')); ?>" class="regular-text" />                        </td>                  </tr>                  <tr valign="top">                        <th scope="row">API Secret</th>                        <td>                            <input type="text" name="xunfei_api_secret" value="<?php echo esc_attr(get_option('xunfei_api_secret', 'YWU0NjI5MDIzNmQzNGNlNzQ2OTA0YWY2')); ?>" class="regular-text" />                        </td>                  </tr>                  <tr valign="top">                        <th scope="row">过滤词语</th>                        <td>                            <textarea name="xunfei_filter_words" rows="5" cols="50" class="large-text"><?php echo esc_textarea(get_option('xunfei_filter_words', implode(', ', $this->filter_words))); ?></textarea>                            <p class="description">需要从标题中过滤的无效词语,用逗号分隔</p>                        </td>                  </tr>                  <tr valign="top">                        <th scope="row">默认目标分类</th>                        <td>                            <?php foreach ($all_categories as $category): ?>                              <label style="display: block; margin-bottom: 5px;">                                    <input type="checkbox" name="xunfei_target_categories[]" value="<?php echo $category->term_id; ?>"                                       <?php checked(in_array($category->term_id, $selected_categories)); ?>>                                    <?php echo $category->name; ?>                              </label>                            <?php endforeach; ?>                            <p class="description">设置默认的目标分类,AI生成的文章将放入这些分类中(可在文章编辑页面单独设置)</p>                        </td>                  </tr>                </table>                <?php submit_button(); ?>            </form>                        <h2>生成统计</h2>            <p>今日已生成文章: <?php echo $this->get_daily_count(); ?> / <?php echo get_option('xunfei_daily_limit', 100); ?></p>            <p>最后重置时间: <?php echo get_option('xunfei_last_reset', '从未'); ?></p>      </div>      <?php    }      // 获取当日已生成文章数量    private function get_daily_count() {      $data = get_option($this->option_name, array('date' => '', 'count' => 0));                // 如果是新的一天,重置计数      if ($data['date'] !== date('Y-m-d')) {            $this->reset_daily_count();            return 0;      }                return $data['count'];    }      // 更新当日计数    private function update_daily_count() {      $data = array(            'date' => date('Y-m-d'),            'count' => $this->get_daily_count() + 1      );                update_option($this->option_name, $data);    }      // 重置每日计数    public function reset_daily_count() {      update_option($this->option_name, array('date' => date('Y-m-d'), 'count' => 0));      update_option('xunfei_last_reset', date('Y-m-d H:i:s'));    }      // 检查是否需要生成文章    public function maybe_generate_articles() {      if (!is_single()) {            return;      }                // 检查是否达到每日限制      if ($this->get_daily_count() >= get_option('xunfei_daily_limit', 100)) {            return;      }                // 获取当前文章ID      $post_id = get_the_ID();                // 检查是否已经处理过这篇文章      $processed = get_post_meta($post_id, '_xunfei_processed', true);      if ($processed) {            return;      }                // 标记为已处理      update_post_meta($post_id, '_xunfei_processed', true);                // 获取当前文章标签      $tags = get_the_tags();      if (empty($tags)) {            return;      }                // 获取当前文章分类      $categories = wp_get_post_categories($post_id, array('fields' => 'ids'));                // 获取目标分类设置(优先使用文章级别的设置,其次使用全局设置)      $target_categories = get_post_meta($post_id, '_xunfei_target_categories', true);      if (empty($target_categories)) {            $target_categories = get_option('xunfei_target_categories', array());      }                // 如果有设置目标分类,则使用目标分类,否则使用源文章分类      $final_categories = !empty($target_categories) ? $target_categories : $categories;                $tag_names = array();      foreach ($tags as $tag) {            $tag_names[] = $tag->name;      }                // 异步生成相关文章(传递最终确定的分类)      wp_schedule_single_event(time() + 5, 'xunfei_generate_articles', array($tag_names, $post_id, $final_categories));    }      /**   * 生成相关文章   */    public function generate_related_articles($tags, $source_post_id, $categories = array()) {      // 检查是否达到每日限制      if ($this->get_daily_count() >= get_option('xunfei_daily_limit', 100)) {            return;      }                // 生成提示词      $tag_list = implode(', ', $tags);      $prompt = "请基于以下关键词: {$tag_list},生成5个相关且吸引人的文章标题。要求:         1) 与这些关键词高度相关         2) 不使用无效修饰词或者语气词(如揭秘、探索、解析等)      3) 不使用营销词汇(如必看、收藏、分享等)      4) 标题字数20-30汉字      请直接返回标题,每个标题占一行,不要编号或额外说明。";                // 调用讯飞星火API获取标题      $response = $this->call_xunfei_api($prompt);      $titles = explode("\n", trim($response));                if (!empty($titles)) {            foreach ($titles as $title) {                // 标题清理:移除序号、编号、双引号、句号等                $clean_title = $this->remove_title_noise($title);                if (empty($clean_title)) continue;                              // 检查是否已存在相同标题的文章(使用清理后的标题)                if ($this->post_exists($clean_title)) {                  continue;                }                              // 为每个标题生成文章内容                $content_prompt = "请根据标题'{$clean_title}'撰写一篇800-1200字的优质文章。要求:               1) 文章内容必须围绕标题来写,不要脱离主题               2) 内容详实,信息准确,避开泛化主题                3) 语言流畅自然,避免AI高频表述(如'总之''结语''总的来说'等)                4) 不使用营销性语言(如'小编''笔者''必看'等)                5) 提供有价值的信息和见解";                $content = $this->call_xunfei_api($content_prompt);                              if (!empty($content)) {                  // 文章内容清理:过滤Markdown符号和无用词语                  $clean_content = $this->filter_markdown_symbols($content);                  $clean_content = $this->filter_content_noise($clean_content);                                        // 创建WordPress文章(使用清理后的标题和内容)                  $post_id = wp_insert_post(array(                        'post_title' => $clean_title,                        'post_content' => $clean_content,                        'post_status' => 'publish',                        'post_type' => 'post',                        'post_author' => 1 // 设置为管理员ID                  ));                                        if (!is_wp_error($post_id)) {                        // 添加标签关联                        wp_set_post_tags($post_id, $tags, true);                                                // 设置分类(使用传入的分类参数)                        if (!empty($categories)) {                            wp_set_post_categories($post_id, $categories, false);                        }                                                // 记录来源文章                        update_post_meta($post_id, '_xunfei_source_post', $source_post_id);                                                // 更新计数                        $this->update_daily_count();                  }                }                              // 检查是否达到每日限制                if ($this->get_daily_count() >= get_option('xunfei_daily_limit', 100)) {                  break;                }                              // 添加延迟,避免API限制                sleep(2);            }      }    }      /**   * 标题清理工具:移除序号、编号、特殊符号和无效词语   */    private function remove_title_noise($title) {      // 移除首尾空格      $clean = trim($title);                // 移除常见序号格式(正则匹配)      $clean = preg_replace('/^[\d]{1,3}\.\s+/', '', $clean);         $clean = preg_replace('/^\([\d]{1,3}\)\s+/', '', $clean);         $clean = preg_replace('/^①-⑳\s+/', '', $clean);         $clean = preg_replace('/^[一二三四五六七八九十百千万]+[\.、\s]+/', '', $clean);               // 移除首尾双引号/单引号      $clean = trim($clean, '"');      $clean = trim($clean, "'");      $clean = trim($clean, "【】");      $clean = trim($clean, "《》");                // 移除标题末尾的句号/问号      $clean = rtrim($clean, '。.?');                // 过滤无效词语      $filter_words = $this->get_filter_words();      foreach ($filter_words as $word) {            $clean = str_replace($word, '', $clean);      }                // 移除多余空格(多个空格合并为一个)      $clean = preg_replace('/\s+/', ' ', $clean);      $clean = trim($clean);                return $clean;    }      /**   * 文章内容清理工具:过滤Markdown符号   */    private function filter_markdown_symbols($content) {      $content = preg_replace('/^#{1,6}\s+/m', '', $content);      $content = preg_replace('/\*{1,3}(.*?)\*{1,3}/', '$1', $content);      $content = preg_replace('/^[\-*+]\s+/m', '', $content);      $content = preg_replace('/^[\d]{1,3}\.\s+/m', '', $content);      $content = preg_replace('/^>\s+/m', '', $content);      $content = preg_replace('/\n{3,}/', "\n\n", $content);                return $content;    }      /**   * 内容噪音过滤   */    private function filter_content_noise($content) {      $filter_words = $this->get_filter_words();                // 移除常见AI痕迹和营销用语      $ai_patterns = array(            '/作为(一个)?AI/',            '/标题:/',            '/标题:/',            '/总之,/',            '/综上所述,/',            '/总结,/',            '/总的来说,/',            '/根据我的(知识|理解)/',            '/请注意[,,::].*?(重要|关键)/',            '/建议.*?(收藏|分享|点赞|关注)/',            '/欢迎.*?(评论|留言)/'      );                foreach ($ai_patterns as $pattern) {            $content = preg_replace($pattern, '', $content);      }                // 移除过滤词列表中的词语      foreach ($filter_words as $word) {            $content = str_replace($word, '', $content);      }                return $content;    }      /**   * 获取过滤词列表   */    private function get_filter_words() {      $custom_words = get_option('xunfei_filter_words', '');      if (!empty($custom_words)) {            $words = array_map('trim', explode(',', $custom_words));            return array_unique(array_merge($this->filter_words, $words));      }                return $this->filter_words;    }      // 检查文章是否已存在(使用清理后的标题)    private function post_exists($title) {      global $wpdb;                $post = $wpdb->get_var($wpdb->prepare(            "SELECT ID FROM $wpdb->posts WHERE post_title = %s AND post_type = 'post' AND post_status = 'publish'",            $title      ));                return !is_null($post);    }      // 调用讯飞星火API    private function call_xunfei_api($prompt) {      $app_id = get_option('xunfei_app_id', $this->app_id);      $api_key = get_option('xunfei_api_key', $this->api_key);      $api_secret = get_option('xunfei_api_secret', $this->api_secret);      $ws_url = $this->ws_url;                $auth_url = $this->assemble_auth_url("GET", $ws_url, $api_key, $api_secret);                $request_data = [            "header" => [                "app_id" => $app_id,                "uid" => uniqid()            ],            "parameter" => [                "chat" => [                  "domain" => "lite",                  "temperature" => 0.7,                  "max_tokens" => 4096                ]            ],            "payload" => [                "message" => [                  "text" => [                        ["role" => 'user', "content" => $prompt]                  ]                ]            ]      ];                try {            $client = new Client($auth_url, [                'timeout' => 60,                'fragment_size' => 4096            ]);                        $client->send(json_encode($request_data));            $answer = "";                        while (true) {                $response = $client->receive();                $resp = json_decode($response, true);                              if (json_last_error() !== JSON_ERROR_NONE) {                  error_log('讯飞API响应数据格式错误: ' . json_last_error_msg());                  break;                }                              $code = $resp["header"]["code"] ?? -1;                if ($code !== 0) {                  $error_msg = $resp["header"]["message"] ?? "未知服务错误";                  error_log("讯飞API请求失败:{$error_msg}(错误码:{$code})");                  break;                }                              $content = $resp['payload']['choices']['text']['content'] ?? '';                if (!empty($content)) {                  $answer .= $content;                }                              $status = $resp["header"]["status"] ?? 0;                if ($status === 2) {                  break;                }            }                        $client->close();            return $answer;                  } catch (Exception $e) {            error_log('讯飞API连接异常:' . $e->getMessage());            return '';      }    }      // 组装认证URL    private function assemble_auth_url($method, $addr, $api_key, $api_secret) {      if (empty($api_key) || empty($api_secret)) {            return $addr;      }                $url_parts = parse_url($addr);      if ($url_parts === false) {            return $addr;      }                $timestamp = gmdate("D, d M Y H:i:s \G\M\T", time());                $sign_string = implode("\n", [            "host: " . $url_parts["host"],            "date: " . $timestamp,            "{$method} " . $url_parts["path"] . " HTTP/1.1"      ]);                $hmac = hash_hmac('sha256', $sign_string, $api_secret, true);      $signature = base64_encode($hmac);                $auth_header = "api_key="{$api_key}", algorithm="hmac-sha256", headers="host date request-line", signature="{$signature}"";      $auth_header = base64_encode($auth_header);                return $addr . '?' . http_build_query([            'host' => $url_parts['host'],            'date' => $timestamp,            'authorization' => $auth_header      ]);    }      // 在文章末尾添加推荐    public function add_recommendations($content) {      if (!is_single()) {            return $content;      }                $post_id = get_the_ID();                // 查询由AI生成的相关文章      $related_posts = get_posts(array(            'meta_key' => '_xunfei_source_post',            'meta_value' => $post_id,            'post_type' => 'post',            'post_status' => 'publish',            'numberposts' => 5,            'orderby' => 'date',            'order' => 'DESC'      ));                // 如果没有AI生成的文章,则基于标签查找      if (empty($related_posts)) {            $tags = get_the_tags();            if (empty($tags)) {                return $content;            }                        $tag_ids = array();            foreach ($tags as $tag) {                $tag_ids[] = $tag->term_id;            }                        $related_posts = get_posts(array(                'tag__in' => $tag_ids,                'numberposts' => 5,                'post__not_in' => array($post_id),                'orderby' => 'rand'            ));      }                if (!empty($related_posts)) {            $content .= '<div class="xunfei-recommendations">';            $content .= '<h3>猜你想看</h3>';            $content .= '<ul>';                        foreach ($related_posts as $post) {                $content .= '<li><a href="' . get_permalink($post->ID) . '">' . $post->post_title . '</a></li>';            }                        $content .= '</ul>';            $content .= '</div>';      }                return $content;    }}// 初始化插件$xunfei_ai_generator = new XunfeiAIArticleGenerator();// 注册生成文章的钩子add_action('xunfei_generate_articles', array($xunfei_ai_generator, 'generate_related_articles'), 10, 3);// 添加样式add_action('wp_head', function() {    echo '<style>    .xunfei-recommendations {      margin-top: 40px;      padding: 20px;      background-color: #f9f9f9;      border-radius: 5px;      border-left: 4px solid #1E88E5;    }      .xunfei-recommendations h3 {      margin-top: 0;      color: #333;    }      .xunfei-recommendations ul {      list-style-type: none;      padding-left: 0;    }      .xunfei-recommendations li {      margin-bottom: 10px;      padding: 8px 0;      border-bottom: 1px solid #eee;    }      .xunfei-recommendations li:last-child {      border-bottom: none;    }      .xunfei-recommendations a {      color: #1E88E5;      text-decoration: none;    }      .xunfei-recommendations a:hover {      text-decoration: underline;    }    </style>';});1、需要在插件目录安装composer依赖,运行:composer require textalk/websocket2、该插件使用的是科大讯飞星火的spark lite模型(目前免费使用),需要获取app_id、api_key、api_secret
3、当前插件逻辑是根据文章中的标签生成5个相关标题,再根据标题生成文章,生成的文章自行选择当前文章标签的分类入库(当然也可以根据标题生成,自行修改代码)
4、经过测试还是没有python代码跑起来利索(5-8秒一篇/1000字左右),生成的质量一般,可以用
5、如若需要修改composer和php版本,修改composer.json文件,自行选择版本修改,然后运行composer update重新生成依赖
{    "require": {      "php": ">=7.4",      "textalk/websocket": "^1.6"    },    "config": {      "platform": {            "php": "7.4.33"      }    }}6、可以修改每日生成数量,到达数量后自动停止,然后第二天继续

婷姐 发表于 2025-9-13 23:00:29

第一次知道这星火,接触这么多AI,这是个另类。居然还是wss的

婷姐 发表于 2025-9-13 23:01:02

这模型做知识类的还是不错的,速度快,主要是官方宣传永久免费

TyCoding 发表于 2025-9-13 23:01:22

不错的插件
页: [1]
查看完整版本: Wordpress免费自动生成文章插件