spamtroll/php-sdk

PHP SDK for the Spamtroll spam detection API.

Maintainers

Package info

github.com/spamtroll/spamtroll-php-sdk

Homepage

Issues

pkg:composer/spamtroll/php-sdk

Statistics

Installs: 57

Dependents: 0

Suggesters: 0

Stars: 0

v0.9.3 2026-04-26 17:39 UTC

This package is auto-updated.

Last update: 2026-04-26 17:41:39 UTC


README

Latest Version PHP Version CI License

Zero-dependency PHP client for the Spamtroll spam detection API.

Drop it into a WordPress plugin, an IPS Community Suite application, a framework app, or a plain PHP script — the core SDK has no runtime dependencies beyond ext-curl and ext-json. Host platforms can swap in their own HTTP transport (so WP calls go through wp_remote_* and respect admin filters, IPS calls go through \IPS\Http\Url) by implementing one interface.

Requirements

  • PHP 8.0 or newer
  • ext-curl, ext-json

Installation

composer require spamtroll/php-sdk

Without Composer (e.g. a bundled plugin), drop src/ somewhere in your project and include the fallback autoloader:

require_once __DIR__ . '/path/to/spamtroll-php-sdk/autoload.php';

Quick start

use Spamtroll\Sdk\Client;
use Spamtroll\Sdk\Request\CheckSpamRequest;

$client = new Client('your-api-key');

$response = $client->checkSpam(
    new CheckSpamRequest(
        content: $comment,
        source: CheckSpamRequest::SOURCE_COMMENT,
        ipAddress: $_SERVER['REMOTE_ADDR'] ?? null,
        username: $author,
        email: $authorEmail,
    )
);

if ($response->isSpam()) {
    // block
} elseif ($response->getSpamScore() >= 0.4) {
    // moderate
}

Configuration

use Spamtroll\Sdk\Client;
use Spamtroll\Sdk\ClientConfig;

$config = new ClientConfig(
    baseUrl: 'https://api.spamtroll.io/api/v1',
    timeout: 5,
    maxRetries: 3,
    retryBaseDelayMs: 500,
    userAgent: 'my-plugin/1.0 spamtroll-php-sdk/' . \Spamtroll\Sdk\Version::VERSION,
    scoreDenominator: 30.0,
);

$client = new Client('your-api-key', $config);

What the fields mean

Field Default Notes
baseUrl https://api.spamtroll.io/api/v1 Trailing slash stripped.
timeout 5 Per-request seconds (connect + read).
maxRetries 3 Total attempts, not retries. First attempt counts.
retryBaseDelayMs 500 Backoff: attempt * base ms before attempt 2+. Set 0 to disable (tests).
userAgent spamtroll-php-sdk/{version} Host integrations should prepend their own identifier.
scoreDenominator 30.0 Maps raw API score (0…∞) to normalized 0.0–1.0 via min(1, raw / denominator).

Score normalization

The backend scores on an open-ended additive scale. A raw score of 15 is "definitely spam", 30 is "twice the spam threshold". The SDK normalizes via min(1.0, raw / scoreDenominator):

Raw Normalized (denominator 30)
0 0.00
7.5 0.25
15 0.50
22.5 0.75
30+ 1.00

Use getSpamScore() for the 0–1 value and getRawSpamScore() for the raw number if you need to display the native scale.

Custom HTTP adapter

use Spamtroll\Sdk\Client;
use Spamtroll\Sdk\Http\HttpClientInterface;
use Spamtroll\Sdk\Http\HttpResponse;
use Spamtroll\Sdk\Exception\ConnectionException;
use Spamtroll\Sdk\Exception\TimeoutException;

final class MyHttpClient implements HttpClientInterface
{
    public function send(string $method, string $url, array $headers, ?string $body, int $timeout): HttpResponse
    {
        // Translate connection/timeout failures into
        // ConnectionException / TimeoutException.
        // 4xx/5xx are NOT errors here — return them via HttpResponse.
    }
}

$client = new Client('your-api-key', null, new MyHttpClient());

WordPress and IPS integrations ship adapters that delegate to wp_remote_* and \IPS\Http\Url respectively, so platform-level filters (proxy, SSL overrides, request inspection) still apply.

Error handling

The SDK throws when something prevents a meaningful response:

Exception When
NotConfiguredException Empty API key.
AuthenticationException HTTP 401 — invalid API key.
ConnectionException Connection failure after all retries.
TimeoutException Timeout after all retries (extends ConnectionException).
ServerException HTTP 5xx after all retries.
SpamtrollException Base for all SDK exceptions. Catch this if you want a single fail-open path.

Non-fatal error responses — HTTP 429, other 4xx — are returned as a Response with success === false and an error message, so the caller can decide whether to back off or log.

Documentation

  • Installation — requirements, Composer + manual install.
  • Usage — every Client method, request fields, examples.
  • ConfigurationClientConfig field-by-field, environment-specific recommendations.
  • HTTP adapters — interface contract, reference adapters for WordPress / IPS / Guzzle.
  • Error handling — exception hierarchy, fail-open patterns.
  • Response schemaCheckSpamResponse getters, score normalisation, envelope handling.
  • Contributing — local setup, quality gate, release checklist.

Development

composer install
composer qa            # cs-fixer + phpstan + peck + pest
composer test          # tests only
composer test:coverage # tests with coverage
composer lint:fix      # auto-format

See docs/CONTRIBUTING.md for the full quality gate, including the aspell dependency required by composer peck.

License

MIT — see LICENSE.