feat: 实现用户名-评论联合检测机制

- 修改 AI 检测提示词,同时判断用户名和评论内容合规性
- 评论合规但用户名不合规时,自动生成唯一随机用户名(用户-XXXXXXXX)
- 基于用户名、IP、UA 生成8位唯一标识码
- 发送邮件通知用户名变更,包含原因和新用户名
- 创建用户名变更通知邮件模板
- 保存原始用户名到评论元数据
- 兼容旧格式 API 响应
- 增加 max_tokens 到 150 以支持更详细的响应
This commit is contained in:
2026-01-22 18:17:39 +08:00
parent 0e9ef6f2b2
commit aeebf39a59
3 changed files with 964 additions and 18 deletions

View File

@@ -284,6 +284,7 @@ require_once(get_template_directory() . '/email-templates/comment-notify.php');
require_once(get_template_directory() . '/email-templates/reply-notify.php');
require_once(get_template_directory() . '/email-templates/feedback-notify.php');
require_once(get_template_directory() . '/email-templates/spam-notify.php');
require_once(get_template_directory() . '/email-templates/username-change-notify.php');
//检测更新
require_once(get_template_directory() . '/theme-update-checker/plugin-update-checker.php');
@@ -7313,9 +7314,9 @@ function argon_get_siliconflow_models($api_key, $custom_endpoint = '') {
// ==========================================================================
/**
* 检测评论是否为垃圾评论
* 检测评论是否为垃圾评论(用户名-评论联合检测)
* @param int $comment_id 评论 ID
* @return array|false ['is_spam' => bool, 'reason' => string] 或 false
* @return array|false ['is_spam' => bool, 'reason' => string, 'username_invalid' => bool, 'username_reason' => string] 或 false
*/
function argon_detect_spam_comment($comment_id) {
$comment = get_comment($comment_id);
@@ -7334,16 +7335,25 @@ function argon_detect_spam_comment($comment_id) {
}
if (empty($prompt)) {
$prompt = '你是一个专业的内容审核助手。请判断以下评论是否为垃圾评论。垃圾评论包括但不限于:广告推广、反动言论、错误政治观点、时政敏感内容、违法信息、色情暴力、恶意攻击等
$prompt = '你是一个专业的内容审核助手。请分别判断以下评论的用户名和内容是否合规
请仅返回 JSON 格式:{"is_spam": true/false, "reason": "理由(25字以内)"}
不合规内容包括但不限于:广告推广、反动言论、错误政治观点、时政敏感内容、违法信息、色情暴力、恶意攻击等。
不合规用户名包括但不限于:广告推广、色情暴力、政治敏感、恶意攻击、侮辱性词汇等。
如果是正常评论reason 填写 "正常"。如果是垃圾评论,简要说明原因。';
请仅返回 JSON 格式:
{
"content_spam": true/false,
"content_reason": "内容判断理由(25字以内)",
"username_invalid": true/false,
"username_reason": "用户名判断理由(25字以内)"
}
如果内容正常content_reason 填写 "正常"。如果用户名正常username_reason 填写 "正常"。';
}
// 构建评论内容
$comment_text = sprintf(
"作者%s\n邮箱%s\n网站%s\n内容%s",
"用户名%s\n邮箱%s\n网站%s\n评论内容:%s",
$comment->comment_author,
$comment->comment_author_email,
$comment->comment_author_url,
@@ -7353,12 +7363,20 @@ function argon_detect_spam_comment($comment_id) {
// 调用 AI API
$result = argon_call_ai_api_for_spam_detection($provider, $api_key, $model, $prompt, $comment_text);
if ($result && isset($result['is_spam'])) {
if ($result && isset($result['content_spam'])) {
// 转换为统一格式
$unified_result = [
'is_spam' => $result['content_spam'],
'reason' => isset($result['content_reason']) ? $result['content_reason'] : '未知',
'username_invalid' => isset($result['username_invalid']) ? $result['username_invalid'] : false,
'username_reason' => isset($result['username_reason']) ? $result['username_reason'] : '正常'
];
// 保存检测结果
update_comment_meta($comment_id, '_argon_spam_detection_result', $result);
update_comment_meta($comment_id, '_argon_spam_detection_result', $unified_result);
update_comment_meta($comment_id, '_argon_spam_detection_time', time());
return $result;
return $unified_result;
}
return false;
@@ -7397,7 +7415,7 @@ function argon_call_ai_api_for_spam_detection($provider, $api_key, $model, $prom
'model' => $model,
'messages' => $messages,
'temperature' => 0.3,
'max_tokens' => 100
'max_tokens' => 150
];
// 根据服务商设置端点
@@ -7421,7 +7439,7 @@ function argon_call_ai_api_for_spam_detection($provider, $api_key, $model, $prom
$body = [
'model' => $model,
'messages' => [['role' => 'user', 'content' => $prompt . "\n\n" . $content]],
'max_tokens' => 100
'max_tokens' => 150
];
$headers = [
'x-api-key' => $api_key,
@@ -7448,6 +7466,49 @@ function argon_call_ai_api_for_spam_detection($provider, $api_key, $model, $prom
$response_body = json_decode(wp_remote_retrieve_body($response), true);
// 解析响应
$ai_content = '';
if ($provider === 'anthropic') {
if (isset($response_body['content'][0]['text'])) {
$ai_content = $response_body['content'][0]['text'];
}
} else {
if (isset($response_body['choices'][0]['message']['content'])) {
$ai_content = $response_body['choices'][0]['message']['content'];
}
}
if (empty($ai_content)) {
return false;
}
// 提取 JSON支持 Markdown 代码块包裹)
$ai_content = trim($ai_content);
if (preg_match('/```(?:json)?\s*(\{.*?\})\s*```/s', $ai_content, $matches)) {
$json_str = $matches[1];
} elseif (preg_match('/(\{.*?\})/s', $ai_content, $matches)) {
$json_str = $matches[1];
} else {
return false;
}
$result = json_decode($json_str, true);
if (!is_array($result)) {
return false;
}
// 兼容旧格式和新格式
if (isset($result['is_spam'])) {
// 旧格式,转换为新格式
return [
'content_spam' => $result['is_spam'],
'content_reason' => isset($result['reason']) ? $result['reason'] : '未知',
'username_invalid' => false,
'username_reason' => '正常'
];
}
return $result;
}
$ai_response = '';
if ($provider === 'anthropic') {
if (isset($response_body['content'][0]['text'])) {
@@ -7662,7 +7723,46 @@ function argon_update_user_spam_stats($comment, $is_spam) {
}
/**
* 异步执行垃圾评论检测
* 生成唯一的随机用户名
* @param string $original_username 原始用户名
* @param string $email 邮箱
* @param string $ip IP地址
* @param string $user_agent User Agent
* @return string 格式为 "用户-XXXXXXXX" 的用户名
*/
function argon_generate_unique_username($original_username, $email, $ip, $user_agent) {
// 生成基于用户信息的唯一标识
$seed = $original_username . $email . $ip . $user_agent . time();
$hash = md5($seed);
// 取前8位转为大写字母和数字排除易混淆的字符
$chars = '0123456789ABCDEFGHJKLMNPQRSTUVWXYZ';
$unique_code = '';
for ($i = 0; $i < 8; $i++) {
$index = hexdec(substr($hash, $i * 2, 2)) % strlen($chars);
$unique_code .= $chars[$index];
}
$new_username = '用户-' . $unique_code;
// 检查是否已存在(理论上不会重复,但保险起见)
global $wpdb;
$exists = $wpdb->get_var($wpdb->prepare(
"SELECT comment_ID FROM {$wpdb->comments} WHERE comment_author = %s LIMIT 1",
$new_username
));
if ($exists) {
// 如果重复,添加时间戳后缀
$new_username .= substr(time(), -4);
}
return $new_username;
}
/**
* 异步执行垃圾评论检测(用户名-评论联合检测)
*/
function argon_async_spam_detection_handler($comment_id) {
// 检查是否已经检测过
@@ -7686,10 +7786,14 @@ function argon_async_spam_detection_handler($comment_id) {
update_comment_meta($comment_id, '_argon_spam_detection_code', $detection_code);
if ($result && isset($result['is_spam'])) {
// 更新用户统计
argon_update_user_spam_stats($comment, $result['is_spam']);
$content_spam = $result['is_spam'];
$username_invalid = isset($result['username_invalid']) ? $result['username_invalid'] : false;
if ($result['is_spam']) {
// 更新用户统计
argon_update_user_spam_stats($comment, $content_spam);
// 情况1评论内容是垃圾评论
if ($content_spam) {
// 获取自动处理方式
$auto_action = get_option('argon_comment_spam_detection_auto_action', 'trash');
@@ -7710,18 +7814,69 @@ function argon_async_spam_detection_handler($comment_id) {
update_comment_meta($comment_id, '_argon_spam_detection_result', [
'is_spam' => true,
'reason' => $result['reason'],
'action' => $auto_action
'action' => $auto_action,
'username_invalid' => $username_invalid,
'username_reason' => isset($result['username_reason']) ? $result['username_reason'] : ''
]);
// 发送垃圾评论通知邮件给评论者
if (!empty($comment->comment_author_email)) {
argon_send_spam_notify_email($comment, $result, $detection_code);
}
} else {
}
// 情况2评论内容正常但用户名不合规
elseif ($username_invalid) {
$original_username = $comment->comment_author;
// 生成新用户名
$new_username = argon_generate_unique_username(
$original_username,
$comment->comment_author_email,
$comment->comment_author_IP,
isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''
);
// 更新评论的用户名
global $wpdb;
$wpdb->update(
$wpdb->comments,
['comment_author' => $new_username],
['comment_ID' => $comment_id],
['%s'],
['%d']
);
// 记录原始用户名和检测信息
update_comment_meta($comment_id, '_argon_original_username', $original_username);
update_comment_meta($comment_id, '_argon_username_changed', true);
update_comment_meta($comment_id, '_argon_spam_detection_result', [
'is_spam' => false,
'reason' => $result['reason'],
'username_invalid' => true,
'username_reason' => $result['username_reason'],
'original_username' => $original_username,
'new_username' => $new_username
]);
// 如果留了邮箱,发送用户名变更通知
if (!empty($comment->comment_author_email)) {
argon_send_username_change_notify_email(
$comment,
$original_username,
$new_username,
$result['username_reason'],
$detection_code
);
}
}
// 情况3评论和用户名都正常
else {
// 记录正常评论的检测结果
update_comment_meta($comment_id, '_argon_spam_detection_result', [
'is_spam' => false,
'reason' => $result['reason']
'reason' => $result['reason'],
'username_invalid' => false,
'username_reason' => isset($result['username_reason']) ? $result['username_reason'] : '正常'
]);
}
}