cubesoftware/cube-connect-sdk-php

Official Laravel SDK for CubeConnect WhatsApp Business Platform

Maintainers

Package info

github.com/CubeSoftLabs/cube-connect-sdk-php

Homepage

Issues

Documentation

pkg:composer/cubesoftware/cube-connect-sdk-php

Statistics

Installs: 6

Dependents: 0

Suggesters: 0

Stars: 0

1.0.0 2026-05-18 04:15 UTC

This package is auto-updated.

Last update: 2026-05-18 04:18:30 UTC


README

Latest Version License PHP Version

Official Laravel SDK for the CubeConnect WhatsApp Business Platform.

Installation

composer require cubesoftware/cube-connect-sdk-php

The package auto-discovers its service provider and facade. No manual registration required.

Publish Configuration

php artisan vendor:publish --tag=cubeconnect-config

Environment Variables

CUBECONNECT_API_KEY=your_api_key_here
CUBECONNECT_WHATSAPP_ACCOUNT_ID=your_account_id_here
Variable Default Description
CUBECONNECT_API_KEY Your API key — Settings → API in the dashboard
CUBECONNECT_WHATSAPP_ACCOUNT_ID Your WhatsApp account ID — Dashboard → WhatsApp Numbers → API ID:
CUBECONNECT_URL https://cubeconnect.io API base URL
CUBECONNECT_TIMEOUT 30 Request timeout in seconds
CUBECONNECT_WEBHOOK_SECRET null Webhook signing secret for signature verification

Multiple WhatsApp Numbers

If your account has more than one connected number, set a default in your .env and override it per call using the $whatsappAccountId parameter:

// Send from the default number (CUBECONNECT_WHATSAPP_ACCOUNT_ID)
CubeConnect::sendTemplate('+966501234567', 'order_confirmation', 'ar', ['ORD-1234']);

// Send from a different number
CubeConnect::sendTemplate(
    '+966501234567',
    'offer_reminder',
    'ar',
    ['50%'],
    null,                  // $scheduledAt
    null,                  // $timezone
    '01JX_MARKETING',      // $whatsappAccountId — override
);

// List templates for a specific number
$templates = CubeConnect::getTemplates('APPROVED', '01JX_MARKETING');

// Create a campaign from a specific number
CubeConnect::createCampaign([
    'message_type'        => 'template',
    'template_name'       => 'offer_reminder',
    'template_language'   => 'ar',
    'recipients'          => [...],
    'whatsapp_account_id' => '01JX_MARKETING',  // override
]);

Find each number's ID in Dashboard → WhatsApp Numbers → API ID:.

Usage

sendText()

Parameter Type Required Description
$phone string Yes Recipient phone number with country code
$body string Yes Message text (max 4096 characters)
$scheduledAt string|null No ISO 8601 datetime for scheduled delivery
$timezone string|null No IANA timezone. Required when $scheduledAt is set
$whatsappAccountId string|null No Override the default WhatsApp account (useful with multiple numbers)
use CubeConnect\Facades\CubeConnect;

$response = CubeConnect::sendText('+966501234567', 'مرحباً بك في متجرنا!');

$response->status;       // "queued"
->messageLogId; // "01JXXX..."

Scheduled delivery:

$response = CubeConnect::sendText(
    '+966501234567',
    'تذكير: موعدك غداً الساعة 10 صباحاً.',
    '2026-05-01T09:00:00', // $scheduledAt (ISO 8601)
    'Asia/Riyadh',         // $timezone (IANA)
);

$response->status;      // "scheduled"
$response->scheduledAt; // "2026-05-01T06:00:00Z" (UTC)

sendTemplate()

Parameter Type Required Description
$phone string Yes Recipient phone number with country code
$name string Yes Template name (e.g., order_confirmation)
$languageCode string Yes Language code matching the approved template (e.g., ar, en_US)
$params array No Parameters mapping to {{1}}, {{2}}, etc.
$scheduledAt string|null No ISO 8601 datetime for scheduled delivery
$timezone string|null No IANA timezone. Required when $scheduledAt is set
$whatsappAccountId string|null No Override the default WhatsApp account (useful with multiple numbers)
use CubeConnect\Facades\CubeConnect;

$response = CubeConnect::sendTemplate(
    '+966501234567',          // $phone
    'order_confirmation',     // $name
    'ar',                     // $languageCode
    ['ORD-1234', '500 SAR'],  // $params → {{1}}, {{2}}
);

$response->status;               // "queued"
$response->messageLogId;         // 4521
$response->conversationCategory; // "UTILITY"
$response->queued();             // true

Without parameters:

$response = CubeConnect::sendTemplate('+966501234567', 'welcome_message', 'ar');

Scheduled delivery:

$response = CubeConnect::sendTemplate(
    '+966501234567',
    'appointment_reminder',
    'ar',                      // $languageCode
    ['Dr. Ahmed', '10:00 AM'], // $params
    '2026-05-01T09:00:00',     // $scheduledAt (ISO 8601)
    'Asia/Riyadh',             // $timezone (IANA)
);

$response->status;      // "scheduled"
$response->scheduledAt; // "2026-05-01T06:00:00Z" (UTC)

createCampaign()

Send a pre-approved template to a large list in a single API call.

Parameter Type Required Description
message_type string Yes Must be template
template_name string Yes Template name (same as $name in sendTemplate())
template_language string Yes Language code (same as $languageCode in sendTemplate())
recipients array Yes List of recipients. Max 50,000
recipients[].phone string Yes Recipient phone number
recipients[].name string No Recipient display name
recipients[].variables array No Per-recipient variables (e.g., ['1' => 'Ahmed', '2' => 'ORD-1234'])
campaign_name string No Human-readable campaign name
scheduled_at string No ISO 8601 datetime for scheduled delivery
timezone string No IANA timezone. Required when scheduled_at is set
whatsapp_account_id string No Override the default WhatsApp account
$campaign = CubeConnect::createCampaign([
    'message_type'      => 'template',
    'template_name'     => 'order_confirmation',
    'template_language' => 'ar',
    'recipients'        => [
        ['phone' => '+966501234567', 'name' => 'Ahmed', 'variables' => ['1' => 'Ahmed', '2' => 'ORD-1234']],
        ['phone' => '+966509876543', 'name' => 'Sara',  'variables' => ['1' => 'Sara',  '2' => 'ORD-5678']],
    ],
    'campaign_name' => 'Order Notifications',
]);

$campaign->campaignId; // "01JX..."
$campaign->status;     // "pending"
$campaign->totalCount; // 2

Scheduled delivery:

$campaign = CubeConnect::createCampaign([
    'message_type'      => 'template',
    'template_name'     => 'offer_reminder',
    'template_language' => 'ar',
    'recipients'        => [...],
    'campaign_name'     => 'Flash Sale',
    'scheduled_at'      => '2026-05-01T09:00:00', // ISO 8601
    'timezone'          => 'Asia/Riyadh',            // IANA timezone
]);

$campaign->status;        // "pending"
$campaign->isScheduled(); // true

Get Campaign Status

$campaign = CubeConnect::getCampaign($campaignId);

$campaign->status;        // "processing", "completed", "cancelled", "failed"
$campaign->totalCount;    // 500
$campaign->sentCount;     // 320
$campaign->failedCount;   // 12
$campaign->isCompleted(); // true

Cancel a Scheduled Campaign

$ok = CubeConnect::cancelCampaign($campaignId); // true on success

List Templates

$templates = CubeConnect::getTemplates('APPROVED');

foreach ($templates as $t) {
    $t->name;         // "order_confirmation"
    $t->paramsCount;  // 3
    $t->body;         // "Hello {{1}}, your order {{2}} has been shipped."
    $t->header;       // null
    $t->isApproved(); // true
}

Get Message Status

Retrieve the current delivery status of a previously sent message using the messageLogId returned by sendTemplate().

$msg = CubeConnect::getMessageStatus(4521);

$msg->messageLogId;  // 4521
$msg->status;        // "delivered"
$msg->toPhone;       // "966501234567"
$msg->messageType;   // "template"
$msg->metaMessageId; // "wamid.HBgN..."
$msg->sentAt;        // "2026-05-01T07:05:00Z"
$msg->scheduledAt;   // null
$msg->costAmount;    // 0.05
$msg->costCurrency;  // "SAR"
$msg->errorMessage;  // null (set if status is "failed")

$msg->isSent();      // true if status is "sent"
$msg->isDelivered(); // true if status is "delivered"
$msg->isRead();      // true if status is "read"
$msg->isFailed();    // true if status is "failed"
$msg->isScheduled(); // true if status is "scheduled"

Health Check

$health = CubeConnect::health();
// ['status' => 'healthy', 'checks' => [...], 'timestamp' => '...']

Webhooks

Receive real-time notifications from CubeConnect for messages, campaigns, templates, chatbot flows, and quality events.

Setup

CUBECONNECT_WEBHOOK_SECRET=your_webhook_secret_here

Signature Verification Middleware

// routes/api.php
use CubeConnect\Webhooks\WebhookHandler;

Route::post('/cubeconnect/webhook', [WebhookController::class, 'handle'])
    ->middleware(WebhookHandler::class);

Handling Webhook Events

use CubeConnect\DTOs\WebhookEvent;

class WebhookController extends Controller
{
    public function handle(Request $request)
    {
        $event = WebhookEvent::fromRequest($request);

        match (true) {
            $event->isMessageReceived()       => $this->handleMessage($event),
            $event->isMessageStatusUpdated()  => $this->handleStatus($event),
            $event->isCampaignCompleted()     => $this->handleCampaign($event),
            $event->isTemplateStatusChanged() => $this->handleTemplate($event),
            $event->isFlowSessionCompleted()  => $this->handleFlow($event),
            $event->isQualityEvent()          => $this->handleQuality($event),
            default => null,
        };

        return response('OK', 200);
    }
}

Supported Events

Event Method Description
message.status_updated isMessageStatusUpdated() Message status change (sent, delivered, read, failed)
message.received isMessageReceived() Incoming message from a customer
campaign.created isCampaignCreated() New campaign created
campaign.started isCampaignStarted() Campaign execution started
campaign.completed isCampaignCompleted() Campaign finished
template.submitted isTemplateSubmitted() Template submitted to Meta
template.status_changed isTemplateStatusChanged() Template approved, rejected, or paused
flow.session_started isFlowSessionStarted() Chatbot flow session started
flow.session_completed isFlowSessionCompleted() Chatbot flow session completed
flow.session_cancelled isFlowSessionCancelled() Session cancelled by customer
account.quality_event isQualityEvent() Quality event (block or report)
webhook.test isTest() Connection test ping

Dependency Injection

use CubeConnect\Contracts\Messaging;

class OrderController extends Controller
{
    public function shipped(Order $order, Messaging $messaging)
    {
        $messaging->sendTemplate(
            $order->customer_phone,
            'order_shipped',
            'ar',
            [$order->id, $order->tracking_number],
        );
    }
}

Response Objects

MessageResponse

Returned by sendText() and sendTemplate():

Property Type Description
status string queued for immediate delivery, scheduled for future delivery
messageLogId string Unique tracking ID
conversationCategory string MARKETING, UTILITY, or AUTHENTICATION
cost float Message cost
scheduledAt string|null UTC datetime if scheduled, otherwise null
$response->queued();    // true if status is "queued"
$response->scheduled(); // true if status is "scheduled"
$response->toArray();   // Array representation

CampaignResponse

Returned by createCampaign() and getCampaign():

Property Type Description
campaignId string Unique campaign ULID
name string|null Campaign name
status string pending, processing, completed, cancelled, failed
totalCount int Total recipients
sentCount int Successfully sent
failedCount int Failed deliveries
scheduledAt string|null Scheduled UTC datetime
createdAt string Creation timestamp
$campaign->isScheduled(); // true if pending with a scheduledAt
$campaign->isCompleted(); // true if status is "completed"
$campaign->isCancelled(); // true if status is "cancelled"
$campaign->toArray();     // Array representation

MessageStatusResponse

Returned by getMessageStatus():

Property Type Description
messageLogId string Unique message log ID
status string queued, scheduled, sent, delivered, read, or failed
toPhone string Recipient phone number
messageType string template or text
metaMessageId string|null WhatsApp message ID (set after delivery)
sentAt string|null UTC datetime when sent to WhatsApp
scheduledAt string|null UTC datetime of scheduled delivery
costAmount float Message cost
costCurrency string Currency code (e.g., SAR)
errorMessage string|null Error details if status is failed
createdAt string UTC creation datetime
$msg->isSent();      // true if status is "sent"
$msg->isDelivered(); // true if status is "delivered"
$msg->isRead();      // true if status is "read"
$msg->isFailed();    // true if status is "failed"
$msg->isScheduled(); // true if status is "scheduled"
$msg->toArray();     // Array representation

Error Reference

HTTP Error Code Cause
401 AUTHENTICATION_REQUIRED No API key provided in the request
401 INVALID_API_KEY API key is invalid or has been revoked
403 FORBIDDEN API key does not have permission for this action
403 API_KEY_NO_TENANT API key is not linked to any account
404 NOT_FOUND The requested resource does not exist
404 TEMPLATE_NOT_FOUND Template name not found in your account
422 VALIDATION_ERROR Request failed input validation — check error.details for field-level errors
422 INVALID_PHONE_NUMBER Phone number is not in a valid international format
422 NO_ACTIVE_ACCOUNT No connected WhatsApp number found for the given whatsapp_account_id
422 MISSING_ACCESS_TOKEN The selected WhatsApp number has no Meta access token configured
422 TEMPLATE_LANGUAGE_MISMATCH Language code does not match any approved version of this template
422 TEMPLATE_PARAMS_MISMATCH Fewer parameters provided than the template requires
429 RATE_LIMIT_EXCEEDED Too many API requests — apply exponential backoff and retry
429 PLAN_LIMIT_REACHED Monthly message quota reached — upgrade your plan
429 SUBSCRIPTION_EXPIRED Subscription has expired
500 MESSAGE_SEND_FAILED WhatsApp API rejected or failed to deliver the message
500 INTERNAL_ERROR Unexpected server error — contact support if this persists
503 SERVICE_DEGRADED One or more platform services are temporarily unavailable

Error Handling

use CubeConnect\Facades\CubeConnect;
use CubeConnect\Exceptions\AuthenticationException;
use CubeConnect\Exceptions\ValidationException;
use CubeConnect\Exceptions\RateLimitException;
use CubeConnect\Exceptions\NotFoundException;
use CubeConnect\Exceptions\CubeConnectException;

try {
    CubeConnect::sendTemplate('+966501234567', 'order_confirmation', 'ar', ['ORD-1234']);
} catch (AuthenticationException $e) {
    // 401/403 — Invalid API key or permissions
    $e->errorCode;  // "INVALID_API_KEY", "FORBIDDEN", ...
    $e->statusCode; // 401 or 403
} catch (ValidationException $e) {
    // 422 — Invalid request data
    $e->errorCode; // "VALIDATION_ERROR", "INVALID_PHONE_NUMBER", ...
    $e->errors;    // ['phone' => ['The phone field is required.']]
} catch (NotFoundException $e) {
    // 404 — Resource not found
    $e->errorCode; // "NOT_FOUND", "TEMPLATE_NOT_FOUND"
} catch (RateLimitException $e) {
    // 429 — Rate or plan limit exceeded
    $e->errorCode; // "RATE_LIMIT_EXCEEDED", "PLAN_LIMIT_REACHED", ...
} catch (CubeConnectException $e) {
    // 5xx or network errors
    $e->errorCode;  // "INTERNAL_ERROR", "MESSAGE_SEND_FAILED", ...
    $e->statusCode;
}

Documentation

Full API documentation is available at docs.cubeconnect.io.

License

CubeConnect for Laravel is open-sourced software licensed under the MIT license.

Copyright © 2026 Cube Software (CubeSoftLabs). All rights reserved.