Guides/ PHP and WordPress
Guides

PHP and WordPress

A plain PHP handler, and WordPress filters for Contact Form 7 and WPForms.

Plain PHP

<?php
function spamex_classify(array $f): ?array {
    $body = json_encode([
        'name'         => $f['name'] ?? '',
        'email'        => $f['email'] ?? '',
        'subject'      => $f['subject'] ?? '',
        'message'      => $f['message'] ?? '',
        'honeypot'     => $f['website'] ?? '',                 // your hidden trap field
        'form_load_ts' => isset($f['form_load_ts']) ? (float) $f['form_load_ts'] : null,
        'submit_ts'    => time(),
        'ip'           => $_SERVER['REMOTE_ADDR'] ?? null,
        'user_agent'   => $_SERVER['HTTP_USER_AGENT'] ?? null,
    ]);
    $ch = curl_init('https://api.spamex.dev/v1/classify');
    curl_setopt_array($ch, [
        CURLOPT_POST           => true,
        CURLOPT_POSTFIELDS     => $body,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 5,
        CURLOPT_HTTPHEADER     => ['Authorization: Bearer ' . getenv('SPAMEX_KEY'), 'Content-Type: application/json'],
    ]);
    $res  = curl_exec($ch);
    $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);
    return ($code === 200 && $res) ? json_decode($res, true) : null; // null = fail open
}

$verdict = spamex_classify($_POST);
if ($verdict && $verdict['label'] === 'spam') {
    // quarantine; keep $verdict['id'] for feedback
} else {
    // deliver
}

WordPress: Contact Form 7

Add to a small plugin or your theme’s functions.php, together with the spamex_classify function above. Define SPAMEX_KEY in wp-config.php and read it with getenv or constant.

add_filter('wpcf7_spam', function ($spam, $submission) {
    if ($spam) {
        return $spam;
    }
    $d = $submission->get_posted_data();
    $v = spamex_classify([
        'name'    => $d['your-name'] ?? '',
        'email'   => $d['your-email'] ?? '',
        'subject' => $d['your-subject'] ?? '',
        'message' => $d['your-message'] ?? '',
        'website' => $d['website'] ?? '',
    ]);
    return $v && $v['label'] === 'spam';
}, 10, 2);

Contact Form 7 keeps spam submissions out of the mail and, with Flamingo installed, in a reviewable list where you can act on the reasons.

WordPress: WPForms

add_filter('wpforms_process_honeypot', '__return_false'); // let spamex judge instead
add_action('wpforms_process', function ($fields, $entry, $form_data) {
    $text = implode("\n", array_map(
        fn($f) => is_array($f['value'] ?? null) ? '' : (string) ($f['value'] ?? ''),
        $fields
    ));
    $v = spamex_classify(['message' => $text, 'email' => $entry['fields'][1] ?? '']);
    if ($v && $v['label'] === 'spam') {
        wpforms()->process->errors[$form_data['id']]['header'] = 'Your message could not be sent. Please email us instead.';
    }
}, 10, 3);

Adjust the field ids to your form. A hidden trap field and load/submit timestamps in the form add two free signals; the quickstart shows how.

Feedback

$ch = curl_init('https://api.spamex.dev/v1/feedback');
curl_setopt_array($ch, [
    CURLOPT_POST       => true,
    CURLOPT_POSTFIELDS => json_encode(['id' => $storedVerdictId, 'label' => 'ham']),
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('SPAMEX_KEY'), 'Content-Type: application/json'],
    CURLOPT_RETURNTRANSFER => true,
]);
curl_exec($ch);
↑↓ navigate↵ openDocs and blog