定制 botbye/botbye-php-sdk 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

botbye/botbye-php-sdk

最新稳定版本:v2.0.1

Composer 安装命令:

composer require botbye/botbye-php-sdk

包简介

Botbye PHP SDK for bot detection and account takeover protection

README 文档

README

PHP SDK for the BotBye Unified Protection Platform — unifying fraud prevention and real-time event monitoring in one platform.

BotBye goes beyond fixed bot/ATO checks. Risk dimensions and metrics are fully dynamic — you define what to measure and what rules to apply per project. This means the same platform covers bot detection, account takeover, multi-accounting, payment fraud, promotion abuse, or any custom fraud scenario specific to your business.

Requirements

  • PHP 8.1 or higher
  • Composer
  • Any PSR-18 compatible HTTP client (Guzzle, Symfony HttpClient, Buzz, etc.)

Installation

composer require botbye/botbye-php-sdk

You also need a PSR-18 HTTP client and PSR-17 factories. Install one of the ready-made implementations:

Guzzle (most common):

composer require guzzlehttp/guzzle

Symfony HttpClient:

composer require symfony/http-client nyholm/psr7

Buzz:

composer require kriswallsmith/buzz nyholm/psr7

Or write a custom adapter for your HTTP transport (e.g. WordPress wp_remote_request) — in that case you only need a PSR-17 factory:

composer require nyholm/psr7

Overview

The SDK provides three request types for different integration levels:

Request Type Use Case Where It Runs
BotbyeValidationEvent Level 1 — Bot filtering Proxy or middleware, before user identity is known
BotbyeRiskScoringEvent Level 2 — Risk scoring & event logging Application layer, when user identity is known
BotbyeFullEvent Level 1+2 combined Application layer when no separate proxy exists

All requests go to a single endpoint (POST /api/v1/protect/evaluate) and return a unified response with a decision (ALLOW, CHALLENGE, BLOCK), risk scores per dimension, and triggered signals. Dimensions are dynamic — the platform ships with built-in ones (bot, ato, abuse) but you can define custom dimensions (e.g., payment_fraud, promotion_abuse) per project without code changes.

Every evaluation call is also recorded as a protection event — logged to the analytics pipeline and used to compute real-time metrics that feed the rules engine. Metrics are fully configurable per project: the platform ships with built-in ones (failed logins, distinct IPs per account, device reuse, etc.) and you can define custom metrics for your specific use case (e.g., "failed transactions over $1000 per account in 1 hour"). This means BotbyeRiskScoringEvent serves a dual purpose: it both evaluates risk and logs the event for future analysis and metric aggregation.

Quick Start

1. Initialize the Client

The SDK uses PSR-18 / PSR-17 interfaces — bring your own HTTP client and message factories.

With Guzzle:

use Botbye\Client\BotbyeClient;
use Botbye\Client\BotbyeConfig;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;

$config = new BotbyeConfig(
    serverKey: 'your-server-key' // from https://botbye.com/docs/dashboard/project
);

$httpClient = new Client(['timeout' => 2.0]);
$psr17Factory = new HttpFactory();

$client = new BotbyeClient(
    config: $config,
    httpClient: $httpClient,
    requestFactory: $psr17Factory,
    streamFactory: $psr17Factory,
);

With Symfony HttpClient:

use Symfony\Component\HttpClient\Psr18Client;
use Nyholm\Psr7\Factory\Psr17Factory;

$httpClient = new Psr18Client();
$psr17Factory = new Psr17Factory();

$client = new BotbyeClient(
    config: $config,
    httpClient: $httpClient,
    requestFactory: $psr17Factory,
    streamFactory: $psr17Factory,
);

Custom adapter (e.g. WordPress wp_remote_request):

use Botbye\Client\BotbyeClient;
use Botbye\Client\BotbyeConfig;
use Nyholm\Psr7\Factory\Psr17Factory;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

// Wrap any HTTP transport as a PSR-18 client
class WpHttpClient implements ClientInterface
{
    public function sendRequest(RequestInterface $request): ResponseInterface
    {
        $response = wp_remote_request((string) $request->getUri(), [
            'method'  => $request->getMethod(),
            'headers' => array_map(
                fn(array $v) => implode(', ', $v),
                $request->getHeaders(),
            ),
            'body'    => (string) $request->getBody(),
            'timeout' => 2,
        ]);

        if (is_wp_error($response)) {
            throw new \RuntimeException($response->get_error_message());
        }

        $psr17 = new Psr17Factory();
        $psrResponse = $psr17->createResponse(
            wp_remote_retrieve_response_code($response),
        );

        return $psrResponse->withBody(
            $psr17->createStream(wp_remote_retrieve_body($response)),
        );
    }
}

$psr17Factory = new Psr17Factory();

$client = new BotbyeClient(
    config: $config,
    httpClient: new WpHttpClient(),
    requestFactory: $psr17Factory,
    streamFactory: $psr17Factory,
);

2. Bot Validation (Level 1)

Validate device tokens where user identity is not yet available — at the proxy layer or in a middleware before authentication.

use Botbye\Model\BotbyeValidationEvent;
use Botbye\Model\Headers;

$headers = Headers::fromArray(getallheaders());

$response = $client->evaluate(new BotbyeValidationEvent(
    ip: $_SERVER['REMOTE_ADDR'],
    token: $_GET['botbye_token'] ?? '',
    headers: $headers->jsonSerialize(),
    requestMethod: $_SERVER['REQUEST_METHOD'],
    requestUri: $_SERVER['REQUEST_URI'],
));

if ($response->isBlocked()) {
    http_response_code(403);
    exit('Access denied');
}

// Propagate bot score to Level 2 via header
header(BotbyeClient::RESULT_HEADER . ': ' . $client->encodeResult($response));

3. Risk Scoring & Event Logging (Level 2)

Evaluate risk and log events when user identity is known. Each call both scores the request and feeds the real-time metrics engine, so you should call evaluate() for every significant user action — not just when you need a decision.

use Botbye\Model\BotbyeRiskScoringEvent;
use Botbye\Model\BotbyeUserInfo;
use Botbye\Model\EventStatus;
use Botbye\Model\Decision;

$response = $client->evaluate(new BotbyeRiskScoringEvent(
    ip: $_SERVER['REMOTE_ADDR'],
    headers: $headers->jsonSerialize(),
    user: new BotbyeUserInfo(
        accountId: $userId,
        email: $userEmail,       // optional
        phone: $userPhone,       // optional
    ),
    eventType: 'LOGIN',
    eventStatus: EventStatus::SUCCESSFUL,
    botbyeResult: $_SERVER['HTTP_X_BOTBYE_RESULT'] ?? null, // from Level 1
));

match ($response->decision) {
    Decision::BLOCK     => abort(403),
    Decision::CHALLENGE => showChallenge($response->challenge),
    Decision::ALLOW     => continueRequest(),
};

When botbyeResult is null (no Level 1 upstream), bot validation is automatically bypassed.

Event Types

eventType is an arbitrary string — the server accepts any value. Pass any string that matches your business domain:

'LOGIN'
'REGISTRATION'
'TRANSACTION'
'BONUS_CLAIM'
'PASSWORD_RESET'
'WITHDRAWAL'

Using Level 2 for Event Logging

Even when you don't need to act on the decision, sending events builds the metrics profile for the account. This enables rules like "more than 5 failed logins in 10 minutes" or "distinct devices per account in 1 hour":

// Log a failed login attempt — feeds metrics even if you don't act on the decision
$client->evaluate(new BotbyeRiskScoringEvent(
    ip: $_SERVER['REMOTE_ADDR'],
    headers: $headers->jsonSerialize(),
    user: new BotbyeUserInfo(accountId: $userId),
    eventType: 'LOGIN',
    eventStatus: EventStatus::FAILED,
));

// Log a custom business event
$client->evaluate(new BotbyeRiskScoringEvent(
    ip: $_SERVER['REMOTE_ADDR'],
    headers: $headers->jsonSerialize(),
    user: new BotbyeUserInfo(accountId: $userId),
    eventType: 'BONUS_CLAIM',
    eventStatus: EventStatus::SUCCESSFUL,
    customFields: ['bonus_id' => 'welcome_100'],
));

4. Full Evaluation (Level 1+2 Combined)

Use when there is no separate proxy layer — validates the device token and evaluates risk in a single call.

use Botbye\Model\BotbyeFullEvent;

$response = $client->evaluate(new BotbyeFullEvent(
    ip: $_SERVER['REMOTE_ADDR'],
    token: $_GET['botbye_token'] ?? '',
    headers: $headers->jsonSerialize(),
    user: new BotbyeUserInfo(accountId: $userId),
    eventType: 'LOGIN',
    eventStatus: EventStatus::FAILED,
));

Response

BotbyeEvaluateResponse contains:

Field Type Description
requestId ?string Request UUID
decision Decision ALLOW, CHALLENGE, or BLOCK
riskScore ?float Overall risk score (0–1)
scores ?array Per-dimension scores (bot, ato, abuse, ...)
signals ?array Triggered signal names (e.g., BruteForce, ImpossibleTravel)
challenge ?BotbyeChallenge Challenge type and token (when decision is CHALLENGE)
extraData ?BotbyeExtraData Enriched device data (IP, country, browser, device, etc.)
config BotbyeEvaluateConfig Config flags (bypassBotValidation)
error ?BotbyeError Error details (on fallback)
$response->decision;              // Decision::ALLOW
$response->isBlocked();           // false
$response->riskScore;             // 0.72
$response->scores;                // ['bot' => 0.15, 'ato' => 0.72, 'abuse' => 0.05]
$response->signals;               // ['BruteForce', 'ImpossibleTravel']
$response->challenge?->type;      // 'captcha'
$response->extraData?->country;   // 'US'

Level 1 to Level 2 Propagation

When using both levels, propagate the Level 1 result to Level 2 via the X-Botbye-Result header. This allows the platform to link both evaluations by requestId and combine bot score from Level 1 with risk scores from Level 2 into a single unified result:

// Level 1 (proxy) — validate and forward result
$response = $client->evaluate(new BotbyeValidationEvent(...));
header(BotbyeClient::RESULT_HEADER . ': ' . $client->encodeResult($response));

// Or bypass validation entirely
header(BotbyeClient::RESULT_HEADER . ': ' . $client->bypassResult());

// Level 2 (middleware) — pass the header value as botbyeResult
$response = $client->evaluate(new BotbyeRiskScoringEvent(
    // ...
    botbyeResult: $_SERVER['HTTP_X_BOTBYE_RESULT'] ?? null,
));

Configuration

$config = new BotbyeConfig(
    serverKey: 'your-server-key', // from https://app.botbye.com
    botbyeEndpoint: 'https://verify.botbye.com', // default
);

Timeouts are configured on the HTTP client you provide:

// Guzzle
$httpClient = new \GuzzleHttp\Client(['timeout' => 2.0, 'connect_timeout' => 1.0]);

// Symfony
$httpClient = new Psr18Client(HttpClient::create(['timeout' => 2.0, 'max_duration' => 3.0]));

PSR-3 Logger

use Monolog\Logger;
use Monolog\Handler\StreamHandler;

$logger = new Logger('botbye');
$logger->pushHandler(new StreamHandler('/var/log/botbye.log', Logger::WARNING));

$client = new BotbyeClient(
    config: $config,
    httpClient: $httpClient,
    requestFactory: $psr17Factory,
    streamFactory: $psr17Factory,
    logger: $logger,
);

Error Handling

The SDK follows a fail-open strategy. On network or server errors, evaluate() returns a bypass response (Decision::ALLOW with bypassBotValidation: true) instead of throwing:

$response = $client->evaluate($event);

if ($response->error !== null) {
    // Evaluation failed, request was allowed by default
    log($response->error->message);
}

BotbyeException is only thrown for unrecoverable errors during sendPayload() — the client catches these internally and returns the bypass response.

Framework Integration

Laravel Middleware

namespace App\Http\Middleware;

use Botbye\Client\BotbyeClient;
use Botbye\Model\BotbyeValidationEvent;
use Botbye\Model\Headers;
use Closure;
use Illuminate\Http\Request;

class BotbyeMiddleware
{
    public function __construct(private BotbyeClient $botbye) {}

    public function handle(Request $request, Closure $next)
    {
        $headers = Headers::fromArray($request->headers->all());

        $response = $this->botbye->evaluate(new BotbyeValidationEvent(
            ip: $request->ip(),
            token: $request->query('botbye_token', ''),
            headers: $headers->jsonSerialize(),
            requestMethod: $request->method(),
            requestUri: $request->getRequestUri(),
        ));

        if ($response->isBlocked()) {
            abort(403, 'Access denied');
        }

        return $next($request);
    }
}

Register the BotbyeClient in a service provider:

// AppServiceProvider.php
$this->app->singleton(BotbyeClient::class, function ($app) {
    $httpClient = new \GuzzleHttp\Client(['timeout' => 2.0]);
    $factory = new \GuzzleHttp\Psr7\HttpFactory();

    return new BotbyeClient(
        config: new BotbyeConfig(serverKey: config('services.botbye.key')),
        httpClient: $httpClient,
        requestFactory: $factory,
        streamFactory: $factory,
    );
});

Symfony Event Subscriber

namespace App\EventSubscriber;

use Botbye\Client\BotbyeClient;
use Botbye\Model\BotbyeValidationEvent;
use Botbye\Model\Headers;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;

class BotbyeSubscriber implements EventSubscriberInterface
{
    public function __construct(private BotbyeClient $botbye) {}

    public static function getSubscribedEvents(): array
    {
        return [KernelEvents::REQUEST => 'onKernelRequest'];
    }

    public function onKernelRequest(RequestEvent $event): void
    {
        $request = $event->getRequest();
        $headers = Headers::fromArray($request->headers->all());

        $response = $this->botbye->evaluate(new BotbyeValidationEvent(
            ip: $request->getClientIp(),
            token: $request->query->get('botbye_token', ''),
            headers: $headers->jsonSerialize(),
            requestMethod: $request->getMethod(),
            requestUri: $request->getRequestUri(),
        ));

        if ($response->isBlocked()) {
            throw new AccessDeniedHttpException('Access denied');
        }
    }
}

Testing

composer install
vendor/bin/phpunit

License

MIT

Support

For support, visit botbye.com or contact accounts@botbye.com.

统计信息

  • 总下载量: 29
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 0
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-11-19

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固