PHP code example of botbye / botbye-php-sdk

1. Go to this page and download the library: Download botbye/botbye-php-sdk library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

botbye / botbye-php-sdk example snippets


use Botbye\Protection\BotbyeClient;
use Botbye\Protection\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,
);

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,
);

use Botbye\Protection\BotbyeClient;
use Botbye\Protection\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,
);

use Botbye\Protection\Model\BotbyeValidationEvent;
use Botbye\Common\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');
}

use Botbye\Protection\Model\BotbyeRiskScoringEvent;
use Botbye\Protection\Model\BotbyeUserInfo;
use Botbye\Protection\Model\EventStatus;
use Botbye\Protection\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(),
};

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

// 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'],
));

use Botbye\Protection\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,
));

use Botbye\Phishing\BotbyePhishingClient;
use Botbye\Phishing\BotbyePhishingConfig;

$phishing = new BotbyePhishingClient(
    new BotbyePhishingConfig(
        endpoint: 'https://verify.botbye.com', // default
        clientKey: '<public-client-key>',
    ),
    $httpClient,     // PSR-18 ClientInterface
    $requestFactory, // PSR-17 RequestFactoryInterface
);

// Proxy the browser's pixel request: forward its original query verbatim (it carries
// format / image_id and the JS tag's module_name / module_version).
$res = $phishing->fetchImage($_SERVER['HTTP_ORIGIN'] ?? null, $_GET);

$res->status;   // 200
$res->headers;  // ['Content-Type' => 'image/png', ...]
$res->body;     // string — raw image bytes to relay back to the browser
$res->error;    // ?BotbyeError — non-null on transport failure

$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 (proxy) — validate and get result
$l1Response = $client->evaluate(new BotbyeValidationEvent(...));

// Pass botbyeResult to Level 2 (e.g. via header or directly)
$l2Response = $client->evaluate(new BotbyeRiskScoringEvent(
    // ...
    botbyeResult: $l1Response->botbyeResult,
));

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

// 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]));

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,
);

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

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

use Botbye\Protection\BotbyeClient;
use Botbye\Protection\Model\BotbyeRequestInfo;
use Botbye\Common\Headers;
use Illuminate\Http\Request;

$client = BotbyeClient::withExtractor(
    config: $config,
    httpClient: $httpClient,
    requestFactory: $psr17Factory,
    streamFactory: $psr17Factory,
    requestInfoExtractor: fn (Request $request) => new BotbyeRequestInfo(
        ip: $request->ip(),
        headers: Headers::fromArray($request->headers->all())->jsonSerialize(),
        token: $request->query('botbye_token'),
        requestMethod: $request->method(),
        requestUri: $request->getRequestUri(),
    ),
);

use Botbye\Protection\Model\BotbyeUserInfo;
use Botbye\Protection\Model\EventStatus;

// Level 1 — bot validation
$l1 = $client->evaluateValidation($request);

// Level 2 — risk scoring & event logging
$l2 = $client->evaluateRiskScoring(
    request: $request,
    user: new BotbyeUserInfo(accountId: $userId),
    eventType: 'LOGIN',
    eventStatus: EventStatus::SUCCESSFUL,
    botbyeResult: $l1->botbyeResult,
);

// Level 1+2 combined (no separate proxy)
$full = $client->evaluateFull($request, new BotbyeUserInfo(accountId: $userId), 'LOGIN', EventStatus::FAILED);

namespace App\Http\Middleware;

use Botbye\Protection\BotbyeClient;
use Closure;
use Illuminate\Http\Request;

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

    public function handle(Request $request, Closure $next)
    {
        if ($this->botbye->evaluateValidation($request)->isBlocked()) {
            abort(403, 'Access denied');
        }

        return $next($request);
    }
}

// AppServiceProvider.php
use Botbye\Protection\Model\BotbyeRequestInfo;
use Botbye\Common\Headers;
use Illuminate\Http\Request;

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

    return BotbyeClient::withExtractor(
        config: new BotbyeConfig(serverKey: config('services.botbye.key')),
        httpClient: $httpClient,
        requestFactory: $factory,
        streamFactory: $factory,
        requestInfoExtractor: fn (Request $request) => new BotbyeRequestInfo(
            ip: $request->ip(),
            headers: Headers::fromArray($request->headers->all())->jsonSerialize(),
            token: $request->query('botbye_token'),
            requestMethod: $request->method(),
            requestUri: $request->getRequestUri(),
        ),
    );
});

namespace App\EventSubscriber;

use Botbye\Protection\BotbyeClient;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\KernelEvents;

// Build $botbye via BotbyeClient::withExtractor(..., requestInfoExtractor: fn (Request $r) => new BotbyeRequestInfo(...))
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
    {
        if ($this->botbye->evaluateValidation($event->getRequest())->isBlocked()) {
            throw new AccessDeniedHttpException('Access denied');
        }
    }
}

use Botbye\Phishing\BotbyePhishingClient;
use Botbye\Phishing\BotbyePhishingConfig;

$phishing = BotbyePhishingClient::withExtractor(
    config: new BotbyePhishingConfig(clientKey: '<public-client-key>'),
    httpClient: $httpClient,
    requestFactory: $requestFactory,
    originExtractor: fn ($request) => $request->headers->get('Origin'),
);

// Origin via the extractor; forward the browser's pixel query for attribution
$res = $phishing->fetchImageFromRequest($request, $request->getQueryParams());
bash
composer