You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

订单触发后定时发送自定义邮件插件无法正常发送问题排查

问题描述

我正在开发一款WordPress插件,功能是在用户订单状态触发指定条件后,延迟设定时长给客户发送自定义评价请求邮件。目前遇到的问题是邮件既没发送也没被接收——已经确认插件配置项全部正确,且WooCommerce自带的订单确认邮件能正常送达客户。相关代码如下:

public function schedule_review_email($order_id, $old_status, $new_status) {
    $settings = get_option('fast_reviews_settings');

    if (!$settings || empty($settings['trigger_status']) || empty($settings['send_after_value']) || empty($settings['send_after_unit'])) {
        error_log("Fast Reviews settings are not properly configured.");
        return;
    }

    error_log("schedule_review_email triggered for Order ID: $order_id, Old Status: $old_status, New Status: $new_status");

    if ($new_status === $settings['trigger_status']) {
        $delay = intval($settings['send_after_value']);
        $unit = sanitize_text_field($settings['send_after_unit']);

        $valid_units = ['seconds', 'minutes', 'hours', 'days'];
        if (!in_array($unit, $valid_units)) {
            error_log("Invalid time unit provided: $unit");
            return;
        }

        $unit_multiplier = $unit === 'seconds' ? 1 : ($unit === 'minutes' ? 60 : ($unit === 'hours' ? 3600 : 86400));
        $schedule_timestamp = time() + $delay * $unit_multiplier;

        error_log("Scheduling email for Order ID: $order_id to be sent after $delay $unit at timestamp: $schedule_timestamp");

        wp_clear_scheduled_hook('fast_reviews_send_email', [$order_id]);

        wp_schedule_single_event($schedule_timestamp, 'fast_reviews_send_email', [$order_id]);
    } else {
        error_log("No action taken for Order ID: $order_id. New status does not match trigger status.");
    }
}

public function send_review_email($order_id) {
    $order = wc_get_order($order_id);
    if (!$order) {
        error_log("Order not found for Order ID: $order_id");
        return;
    }

    $customer_name = $order->get_billing_first_name();
    $order_number = $order->get_order_number();
    $customer_email = $order->get_billing_email();

    if (empty($customer_email)) {
        error_log("No billing email found for Order ID: $order_id");
        return;
    }

    error_log("Preparing to send review email for Order ID: $order_id, Customer Name: $customer_name, Order Number: $order_number");

    // Retrieve email settings
    $settings = get_option('fast_reviews_settings');
    if (!$settings) {
        error_log("Fast Reviews settings not found.");
        return;
    }

    $review_url = isset($settings['review_url']) ? esc_url($settings['review_url']) : '';
    $trustpilot_url = isset($settings['trustpilot_url']) ? esc_url($settings['trustpilot_url']) : '';
    $subject = isset($settings['email_subject']) ? sanitize_text_field($settings['email_subject']) : 'Review Request';
    $content = isset($settings['email_content']) ? str_replace(
        ['{customer_name}', '{order_number}', '{review_url}', '{trustpilot_url}'],
        [$customer_name, $order_number, $review_url, $trustpilot_url],
        wpautop($settings['email_content']) // Convert line breaks to HTML <p> tags
    ) : '';

    $headers = [
        'Content-Type: text/html; charset=UTF-8',
        'From: Your Company Name <noreply@yourdomain.com>', // Customize From address
        'Reply-To: support@yourdomain.com' // Customize Reply-To address
    ];

    $max_attempts = 3;
    $sent = false;

    for ($attempts = 1; $attempts <= $max_attempts; $attempts++) {
        error_log("Attempt $attempts: Sending email to: $customer_email, Subject: $subject");

        $sent = wp_mail($customer_email, $subject, $content, $headers);

        if ($sent) {
            error_log("Email sent successfully to: $customer_email");
            break; 
        } else {
            error_log("Attempt $attempts: Failed to send email to: $customer_email");
            if ($attempts < $max_attempts) {
                sleep(5); 
            }
        }
    }
}
排查建议
  • 确认定时任务是否执行:WordPress的wp_schedule_single_event依赖WP-Cron,而WP-Cron是靠网站请求触发的,低访问量网站可能导致任务延迟/不执行。可以用WP Crontrol插件查看fast_reviews_send_email钩子是否被正确调度,或者手动访问wp-cron.php触发任务测试。
  • 检查钩子绑定是否遗漏:确保插件初始化时已经把send_review_email函数和fast_reviews_send_email钩子绑定,比如添加:add_action('fast_reviews_send_email', [$this, 'send_review_email']);,这是最容易遗漏的环节。
  • 验证邮件头与内容:
    • 发件人地址noreply@yourdomain.com必须是域名下的有效邮箱,避免被反垃圾系统拦截;
    • 测试时可以暂时去掉wpautop,用纯文本内容发送,排除HTML格式导致的问题;
    • 确保配置的review_url等变量不为空,避免替换后内容出现异常。
  • 查看服务器日志:检查PHP错误日志和服务器邮件服务日志(如Postfix/Exim日志),确认wp_mail是否被正常调用,有没有被服务器防火墙或邮件服务拒绝。
  • 替换邮件发送方式:既然系统自带邮件能正常发送,可以临时改用WooCommerce的邮件类发送测试,比如:
    $mailer = WC()->mailer();
    $mailer->send( $customer_email, $subject, $content, $headers );
    

内容的提问来源于stack exchange,提问作者Ghassen Larnaout

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 16:05:12