feedple / feedple-sdk
Official PHP SDK for the Feedple AI platform
Requires
- php: >=8.0
- monolog/monolog: ^1.25 || ^2.0 || ^3.0
- psr/log: ^1.0 || ^2.0 || ^3.0
- ratchet/pawl: ^0.4
- react/event-loop: ^1.0
Requires (Dev)
- phpunit/phpunit: ^6.5 || ^7.5 || ^8.5 || ^9.5 || ^10.5 || ^11.0
Suggests
- illuminate/support: Required to use the Laravel Service Provider (^9.0 || ^10.0 || ^11.0 || ^12.0).
Provides
None
Conflicts
None
Replaces
None
README
The official PHP SDK for the Feedple AI platform. Connect your database to Feedple AI with minimal setup.
Installation
composer require feedple/feedple-sdk
Requirements: PHP >= 8.0 and the pdo extension for your database (pdo_mysql, pdo_pgsql, or pdo_sqlite).
Core Setup in 3 Steps
require __DIR__ . '/vendor/autoload.php'; use Feedple\Sdk\FeedpleSDK; use Feedple\Sdk\DbConfig; use Feedple\Sdk\Core\Identity; // 1. Configure database connection $dbConfig = DbConfig::mysql( host: '127.0.0.1', database: 'myapp', username: 'root', password: 'secret_password', ); // 2. Define table access permissions (RBAC) $identity = new Identity( name: 'main-app', allTables: true, // or: allowedTables: ['users', 'orders'] ); // 3. Initialize Feedple SDK $sdk = new FeedpleSDK( apiKey: getenv('FEEDPLE_API_KEY'), dbConfig: $dbConfig, identity: $identity, );
Transport Modes
Feedple supports two execution transports:
1. Webhook Mode (Recommended for Web & APIs)
Stateless and fast (~15–30ms). Requires zero background daemons or event loops. Incoming queries from Feedple Cloud are handled directly via WebhookBridge:
use Feedple\Sdk\Core\WebhookBridge; $bridge = new WebhookBridge( sdk: $sdk, webhookSecret: getenv('FEEDPLE_WEBHOOK_SECRET'), ); $rawBody = file_get_contents('php://input') ?: ''; $headers = getallheaders() ?: []; $result = $bridge->handle($rawBody, $headers); http_response_code($result['status_code']); header('Content-Type: application/json'); echo json_encode($result['body']);
2. WebSocket Mode (CLI Daemon / Local Dev)
Persistent outbound socket connection. Ideal for CLI workers or local environments behind NAT/firewalls:
$sdk = new FeedpleSDK( apiKey: getenv('FEEDPLE_API_KEY'), dbConfig: $dbConfig, identity: $identity, transport: 'websocket', ); // Start worker (blocks until stopped) $sdk->run(); // Or stop cleanly from another process/signal: $sdk->stop();
Auto Transport Selection: When
transportis omitted, the SDK defaults to'websocket'in local development (APP_ENV=local) and'webhook'in production. If your app is onlocalhostbut targeting Feedple Cloud,'websocket'is automatically forced so the cloud can reach your database.
Local Development & Testing Guide
1. For Application Developers (Testing Locally)
- Zero Configuration: The SDK automatically detects local development when
APP_ENV=localor whenAPP_URLpoints tolocalhost/127.0.0.1. - Automatic WebSocket Selection: Because Feedple Cloud (on the internet) cannot send inbound HTTP webhooks into a private laptop without public tunneling, the SDK's reachability guard automatically routes traffic over WebSocket mode.
- Running Locally:
- Zero extra commands: When you run
php artisan serve, the SDK automatically hooks in and boots the background WebSocket worker! - Or via CLI daemon: Run
php artisan feedple:start.
- Zero extra commands: When you run
2. For Feedple Platform Developers (Local Backend + Local App)
When testing against a local Feedple AI backend running on http://localhost:8000:
-
Add to
.env:FEEDPLE_DEV_ENV=true
This immediately redirects the SDK to
http://localhost:8000/api/v1(REST) andws://localhost:8000/api/v1/tenants/ws(WebSocket) without touching SDK source code. -
To Test Webhook Transport Locally:
FEEDPLE_DEV_ENV=true FEEDPLE_TRANSPORT=webhook APP_URL=http://127.0.0.1:8001
- Start
feedple-aion port 8000:uvicorn app.main:app --port 8000 --reload - Start Laravel on port 8001:
php artisan serve --port=8001 - Run sync:
php artisan feedple:syncFeedple AI on port 8000 will call your webhook bridge directly on port 8001.
- Start
-
To Test WebSocket Transport Locally:
FEEDPLE_DEV_ENV=true FEEDPLE_TRANSPORT=websocket
Start the daemon with
php artisan feedple:startto connect tows://localhost:8000.
| Environment | Client App Location | Feedple Server | Default Transport | Required Settings |
|---|---|---|---|---|
| Client Local Dev | localhost:8000 |
Cloud Run | WebSocket | None (Auto-detected) |
| Client Production | yourdomain.com |
Cloud Run | Webhook | None (Auto-detected) |
| Core Dev (Webhook) | 127.0.0.1:8001 |
localhost:8000 |
Webhook | FEEDPLE_DEV_ENV=trueFEEDPLE_TRANSPORT=webhook |
| Core Dev (WebSocket) | 127.0.0.1:8001 |
localhost:8000 |
WebSocket | FEEDPLE_DEV_ENV=trueFEEDPLE_TRANSPORT=websocket |
Database Configuration (DbConfig)
use Feedple\Sdk\DbConfig; // PostgreSQL $db = DbConfig::pgsql(host: '127.0.0.1', database: 'myapp', username: 'postgres', password: 'secret', port: 5432); // MySQL / MariaDB $db = DbConfig::mysql(host: '127.0.0.1', database: 'myapp', username: 'root', password: 'secret', port: 3306); // SQLite $db = DbConfig::sqlite('/path/to/database.sqlite'); // Custom DSN $db = DbConfig::raw('sqlsrv:Server=localhost;Database=myapp', username: 'sa', password: 'secret');
Table Access Control (Identity)
Control which database tables Feedple AI is permitted to query:
use Feedple\Sdk\Core\Identity; // Expose specific tables only (Recommended) $identity = new Identity( name: 'restricted-access', allowedTables: ['users', 'orders', 'products'], ); // Expose all tables $identity = new Identity( name: 'full-access', allTables: true, );
Note: Sensitive columns (password, token, secret, hash, salt, ssn, credit_card) are always excluded automatically.
Schema Synchronization
Upload your database structure (tables, columns, primary & foreign keys) to Feedple:
// HTTP one-shot sync (recommended for deploy scripts / CI) $result = $sdk->syncSchemaHttp( webhookUrl: 'https://myapp.com/api/feedple/bridge', force: false, ); // Sync schema & notify WebSocket if active $sdk->syncSchema();
Laravel Integration (Zero-Config Auto-Discovery)
The SDK automatically registers the service provider via Laravel Package Discovery. No manual registration in bootstrap/app.php or config/app.php is needed!
- Install the SDK:
composer require feedple/feedple-sdk
- Add your Feedple API Key to
.env:
FEEDPLE_API_KEY=fdpl_live_your_actual_api_key
When you start your development server (php artisan serve), the Feedple background worker daemon starts automatically in < 5ms without blocking.
(Optional) Publish the configuration file if you wish to customize options:
php artisan vendor:publish --tag=feedple-config
Artisan Commands
# Push schema and register webhook bridge php artisan feedple:sync # Check worker status php artisan feedple:status # Start background worker daemon (WebSocket mode) php artisan feedple:start php artisan feedple:start --tail # Force start daemon even if transport is configured for webhook mode php artisan feedple:start --force # Stop background worker daemon php artisan feedple:stop
Note on Webhook Mode: If your application is configured for Webhook mode (
FEEDPLE_TRANSPORT=webhook), runningphp artisan feedple:startinforms you that webhook mode is stateless and does not require a background daemon, directing you tophp artisan feedple:sync. Pass--forceif you wish to run a WebSocket worker daemon anyway.
Standalone CLI Binary (./vendor/bin/feedple)
For non-Laravel frameworks (Symfony, WordPress, CodeIgniter, Yii) or vanilla PHP projects, the SDK includes a unified CLI binary installed to ./vendor/bin/feedple.
The CLI automatically detects your project's .env file and connects using standard DB_* and FEEDPLE_* environment variables:
# Check status and database connection ./vendor/bin/feedple status ./vendor/bin/feedple status --lines=25 # Synchronize schema and register webhook bridge ./vendor/bin/feedple sync ./vendor/bin/feedple sync --force --bridge-url=https://myapp.com/feedple-bridge.php # Start persistent WebSocket daemon (with optional live log tailing) ./vendor/bin/feedple start ./vendor/bin/feedple start --tail # Stop background WebSocket daemon ./vendor/bin/feedple stop
Environment Configuration
By default, the SDK connects to Feedple Cloud:
- API Base URL:
https://feedple-ai-614817435356.us-central1.run.app/api/v1 - WebSocket URL:
wss://feedple-ai-614817435356.us-central1.run.app/api/v1/tenants/ws
To connect to a local Feedple server during development, set in .env:
FEEDPLE_DEV_ENV=true
(Sets API to http://localhost:8000/api/v1 and WebSocket to ws://localhost:8000/api/v1/tenants/ws)
SSL Verification & CA Certificate Bundles
The SDK automatically resolves a bundled Mozilla CA root certificate bundle (resources/cacert.pem), eliminating cURL error 60: SSL certificate problem: unable to get local issuer certificate on Windows (XAMPP/WAMP) and shared hosting.
You can customize SSL behavior in .env:
# Disable SSL certificate verification (e.g. for self-signed certificates or local dev) FEEDPLE_VERIFY_SSL=false # Or specify a custom CA bundle path FEEDPLE_CA_BUNDLE="C:\Server\ssl\cacert.pem"
Core API Reference
FeedpleSDK
namespace Feedple\Sdk; class FeedpleSDK { public function __construct( string $apiKey, DbConfig $dbConfig, Identity $identity, ?string $autoloadPath = null, bool $autoSync = true, int $syncInterval = 60, bool $reconnectEnabled = true, ?int $maxRetries = null, bool $probeBeforeConnect = false, ?LoggerInterface $logger = null, ?string $runtimeDir = null, bool $isWorkerProcess = false, ?string $transport = null, // 'webhook' | 'websocket' ?string $webhookSecret = null, bool|string|null $verifySsl = null, // bool or FEEDPLE_VERIFY_SSL ?string $caBundlePath = null // path or FEEDPLE_CA_BUNDLE ); public function run(): void; public function stop(): void; public function syncSchema(?string $webhookUrl = null): void; public function syncSchemaHttp(?string $apiBaseUrl = null, bool $force = false, ?string $webhookUrl = null): array; public function executeIr(array $ir): array; public function getTransport(): string; public function setTransport(string $transport): void; public function isSslVerified(): bool; public function getCaBundlePath(): ?string; // Helpers public static function isCliDevServer(): bool; public static function isLocalDevTool(): bool; public static function isServerEnvironment(): bool; public static function isTesting(): bool; public static function isDevelopment(): bool; public static function isProduction(): bool; public static function getDefaultTransport(): string; public static function isWebhookReachable(): bool; public static function isLocalApp(): bool; public static function isLocalUrl(string $url): bool; public static function detectAppUrl(?string $explicitUrl = null): ?string; public static function detectWebhookUrl(?string $bridgePath = null, ?string $appUrl = null): ?string; public static function isValidCaFile(?string $path): bool; public static function resolveCaBundle(?string $customPath = null): ?string; public static function isSslVerificationEnabled(): bool; public static function isDevEnv(): bool; }
WebhookBridge
namespace Feedple\Sdk\Core; class WebhookBridge { public function __construct(FeedpleSDK $sdk, ?string $webhookSecret = null, int $tolerance = 300); public function handle(string $rawBody, array $headers): array; // ['status_code' => int, 'body' => array] public static function verifySignature(string $rawBody, ?string $signatureHeader, string|array|null $secret = null, int $tolerance = 300): array; }
DbConfig
namespace Feedple\Sdk; final class DbConfig { public static function mysql(string $host, string $database, ?string $username = null, ?string $password = null, int $port = 3306, string $charset = 'utf8mb4'): self; public static function pgsql(string $host, string $database, ?string $username = null, ?string $password = null, int $port = 5432): self; public static function sqlite(string $path): self; public static function raw(string $dsn, ?string $username = null, ?string $password = null, array $options = []): self; public function toPdo(): \PDO; }
Identity
namespace Feedple\Sdk\Core; class Identity { public function __construct(?string $name = null, array $allowedTables = [], bool $allTables = false); }
License
MIT License.