PHP code example of silon / silon-sdk

1. Go to this page and download the library: Download silon/silon-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/ */

    

silon / silon-sdk example snippets




use Silon\Client;

$client = new Client([
    'apiKey' => 'sk_live_...',   // Settings → API keys; or set SILON_API_KEY
    'workspace' => 'acme',       // => https://acme.silon.tech; or SILON_WORKSPACE / SILON_BASE_URL
]);

$sent = $client->messages->send([
    'channel' => 'whatsapp',
    'to' => ['client_id' => 'cust_001'],
    'content' => ['body' => 'Your order has shipped 📦'],
]);

echo $sent->id, ' ', $sent->status;   // e.g. "9f3e..." "queued"

// Approved WhatsApp template to a raw number
$client->messages->send([
    'channel' => 'whatsapp',
    'to' => ['phone_number' => '+12025550123'],
    'whatsapp_template' => [
        'name' => 'order_confirmed',
        'language' => 'en',
        'variables' => ['body_1' => 'Sara', 'body_2' => 'ORD-42'],
    ],
    'provider' => 'meta_cloud',
]);

// Personalised batch — every row is its own message (same shape as a send()
// body minus `audience`); the top-level channel is the default, a row's own
// channel wins. Max 500 rows, all-or-nothing: any invalid row 422s the whole
// batch (`messages[3].to.phone_number`) and nothing is queued.
$batch = $client->messages->sendBatch([
    'channel' => 'sms',
    'messages' => [
        ['to' => ['phone_number' => '+96550001234'], 'content' => ['body' => 'Sara, table for 2 at 7pm.']],
        ['to' => ['phone_number' => '+96550001235'], 'content' => ['body' => 'Omar, table for 4 at 9pm.']],
        [
            'channel' => 'email',
            'to' => ['email' => '[email protected]'],
            'content' => ['subject' => 'Booking confirmed', 'body' => 'Lulu, table for 6 at 8pm.'],
        ],
    ],
]);
// Per-row envelopes come back in request order; poll each id individually.
// Inline batches have no GET endpoint — the per-row ids are the tracking key.
foreach ($batch->messages ?? [] as $row) {
    $status = $client->messages->retrieve($row->id);
    echo $row->id, ' ', $status->status, PHP_EOL;
}

// Batch from an uploaded CSV — request-level fields are row defaults, CSV
// columns override per row ({{name}} renders from the row). The rows expand
// asynchronously: the 202 is an aggregate (no per-row `messages`) and the
// returned id IS the bulk batch id.
$uploaded = $client->bulk->files->upload("phone_number,name\n+96550001234,Sara\n");
$fileBatch = $client->messages->sendBatch([
    'file' => $uploaded->name,
    'channel' => 'sms',
    'content' => ['body' => 'Hello {{name}}'],
]);
echo $fileBatch->status, ' ', $fileBatch->row_count; // "queued" 1
$detail = $client->bulk->retrieve((int) $fileBatch->id); // per-row status

// Email broadcast to a client group
$result = $client->broadcasts->create([
    'channel' => 'email',
    'audience' => ['type' => 'client_group', 'slug' => 'vip'],
    'content' => ['subject' => 'We saved you a seat', 'body' => '<h1>Hello</h1>'],
]);
echo $result->target_count, ' ', $result->skipped_count;
// Why rows were skipped, itemised (skipped_count stays the sum):
echo $result->skipped?->suppressed;  // e.g. 2

// Track it
$broadcast = $client->broadcasts->retrieve($result->id);
foreach ($client->broadcasts->deliveries($result->id, ['limit' => 100])->autoPaging() as $delivery) {
    echo $delivery->client_id, ' ', $delivery->status, PHP_EOL;
}

$scheduled = $client->messages->send([
    'channel' => 'sms',
    'to' => ['phone_number' => '+96550001234'],
    'content' => ['body' => 'Doors open in an hour'],
    'send_at' => new DateTimeImmutable('+1 hour'),
]);
echo $scheduled->status;                       // "scheduled"

// Changed your mind? Allowed while still "scheduled":
$canceled = $client->messages->cancel($scheduled->id);
echo $canceled->status;                        // "canceled" — never dispatches

$row = $client->suppressions->create([
    'address' => '+96550001234',
    'reason' => 'stop',   // "manual" (default) | "unsubscribe" | "hard_bounce" | "stop"
]);                       // omit `channel` => suppressed everywhere

foreach ($client->suppressions->list(['channel' => 'sms'])->autoPaging() as $s) {
    echo $s->address, ' ', $s->reason, PHP_EOL;
}
$client->suppressions->delete($row->id);

$client->clients->create([
    'client_id' => 'cust_001',
    'first_name' => 'Sara',
    'phone_number' => '+96512345678',
    'default_channel' => 'whatsapp',
]);

// Lists are cursor-paginated (newest first); iterate one page or drain all:
foreach ($client->clients->list(['limit' => 100])->autoPaging() as $contact) {
    echo $contact->client_id, PHP_EOL;
}

$client->clients->update('cust_001', ['notes' => 'VIP']);   // PATCH (partial)
$client->clients->delete('cust_001');

$group = $client->clientGroups->create([
    'name' => 'VIP',
    'slug' => 'vip',
    'client_ids' => ['cust_001', 'cust_002'],   // membership (write-only)
]);

$tmpl = $client->templates->create([
    'slug' => 'order-shipped',
    'subject' => 'Your order is on its way',
    'body_md' => 'Hi {{ client_name }}, order **{{ order_id }}** has shipped.',
]);                                                    // version 1

$client->templates->update('order-shipped', ['body_md' => '...new copy...']);   // mints v2

// Pin a revision on a send (omit `version` for the latest):
$client->messages->send([
    'channel' => 'email',
    'to' => ['email' => '[email protected]'],
    'template' => ['slug' => 'order-shipped', 'version' => 1, 'variables' => ['client_name' => 'Sara']],
]);

use Silon\Webhooks;
use Silon\Exception\WebhookSignatureVerificationException;

$payload = file_get_contents('php://input');
$signature = $_SERVER['HTTP_SILON_SIGNATURE'] ?? '';

try {
    $event = Webhooks::constructEvent($payload, $signature, $_ENV['SILON_WEBHOOK_SECRET']);
} catch (WebhookSignatureVerificationException $e) {
    http_response_code(400);
    exit;
}

if ($event->type === 'message.failed') {
    error_log($event->data->recipient . ' failed: ' . $event->data->error);
}

$page = $client->events->list(['type' => 'message.delivered', 'limit' => 50]);
foreach ($page as $event) { /* this page only */ }
foreach ($page->autoPaging() as $event) { /* every page, fetched lazily */ }

use Silon\Exception\UnprocessableEntityException;
use Silon\Exception\RateLimitException;
use Silon\Exception\ApiStatusException;

try {
    $client->messages->send([...]);
} catch (UnprocessableEntityException $e) {
    echo $e->errors[0]->attr, ': ', $e->errors[0]->detail;
} catch (RateLimitException $e) {
    sleep((int) ceil($e->retryAfter ?? 1));
} catch (ApiStatusException $e) {
    error_log("HTTP {$e->statusCode} ({$e->requestId}): {$e->getMessage()}");
}

use Silon\Client;
use Silon\Http\HttpClientInterface;
use Silon\Http\Request;
use Silon\Http\Response;

$client = new Client([
    'apiKey' => 'sk_live_...',
    'workspace' => 'acme',
    'httpClient' => new class implements HttpClientInterface {
        public function send(Request $request, float $timeout): Response
        {
            // ... adapt to Guzzle, a PSR-18 client, an on-prem CA, etc.
            // Return a Response for any HTTP status; throw a
            // Silon\Http\TransportException only when no response is produced.
        }
    },
]);