Search by

md-anisujjaman-bd / awajdigital-laravel

md-anisujjaman-bd

Unofficial Laravel client for the AwajDigital Voice Broadcasting API. Not affiliated with or endorsed by AwajDigital.

Package info

github.com/md-anisujjaman-bd/awajdigital-laravel

pkg:composer/md-anisujjaman-bd/awajdigital-laravel

Fund package maintenance!

md-anisujjaman-bd

Statistics

Installs: 3

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v0.1.1 2026-09-30 04:27 UTC

This package is auto-updated.

Last update: 2026-09-30 04:27:14 UTC


README

Notice: This is an unofficial package, not affiliated with or endorsed by AwajDigital.

Latest Version on Packagist Tests License PHP Version

An idiomatic, strongly-typed Laravel client for the AwajDigital Voice Broadcasting, IVR Surveys, Audio Management, and Call Center SDK APIs.

Requirements

  • PHP ^8.3
  • Laravel ^12.0 or ^13.0

Installation

Install the package via Composer:

composer require md-anisujjaman-bd/awajdigital-laravel

Publish the configuration file:

php artisan vendor:publish --tag="awajdigital-config"

Configuration

Add your AwajDigital credentials to your .env file:

AWAJDIGITAL_BASE_URL=https://api.awajdigital.com/api
AWAJDIGITAL_TOKEN=your_api_bearer_token_here
AWAJDIGITAL_SENDER=8809612000000
AWAJDIGITAL_TIMEOUT=30

Tip

You can generate and manage your API Bearer token in the AwajDigital Dashboard → API Tokens.

Environment Variable Default Description
AWAJDIGITAL_BASE_URL https://api.awajdigital.com/api API Base URL
AWAJDIGITAL_TOKEN null AwajDigital API Bearer Token
AWAJDIGITAL_SENDER null Default approved sender number (e.g. 8809612000000)
AWAJDIGITAL_TIMEOUT 30 HTTP request timeout in seconds

Quick Start

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Broadcasts\DataTransferObjects\SendBulkBroadcastData;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Broadcasts\DataTransferObjects\SendOtpData;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Surveys\DataTransferObjects\CreateSurveyData;

// 1. Check account balance
$balance = AwajDigital::checkBalance();
echo "Current balance: {$balance->amount} {$balance->currency}";

// 2. Send Voice OTP
$otpBroadcast = AwajDigital::sendOtp(new SendOtpData(
    voice: 'otp_voice_part',
    phoneNumber: '01712345678',
    otpCode: '5842',
));

// 3. Send Bulk Audio Broadcast (up to 999 numbers)
$bulkBroadcast = AwajDigital::sendBulkBroadcast(new SendBulkBroadcastData(
    voice: 'promotional_campaign_v1',
    phoneNumbers: ['01711111111', '01822222222'],
));

// 4. Create Template-based IVR Survey
$survey = AwajDigital::createSurvey(new CreateSurveyData(
    templateName: 'nps_feedback_survey',
    phoneNumbers: ['01711111111'],
));

Usage by Area

1. Broadcasts

Voice OTP (POST /broadcasts/otp)

Voice OTP dispatches an audio prompt containing a dynamic digit-mode part.

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Broadcasts\DataTransferObjects\SendOtpData;

$broadcast = AwajDigital::sendOtp(new SendOtpData(
    voice: 'otp_voice',
    phoneNumber: '01712345678',
    otpCode: '8491',
));

Bulk Broadcast (POST /broadcasts)

Broadcast an approved library voice to up to 999 unique recipients.

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Broadcasts\DataTransferObjects\SendBulkBroadcastData;

$broadcast = AwajDigital::sendBulkBroadcast(new SendBulkBroadcastData(
    voice: 'announcement_voice',
    phoneNumbers: ['01711111111', '01822222222'],
));

Dynamic Broadcast (POST /broadcasts/dynamic)

Asynchronous broadcast (returns HTTP 202) personalizing approved voices with dynamic keys (tts, number, digit, character, audio_url) for 1–10 recipients.

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Broadcasts\DataTransferObjects\DynamicRecipientData;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Broadcasts\DataTransferObjects\SendDynamicBroadcastData;

$response = AwajDigital::sendDynamicBroadcast(new SendDynamicBroadcastData(
    voice: 'due_payment_reminder',
    recipients: [
        new DynamicRecipientData('01711111111', ['customer_name' => 'Rahim', 'amount' => '1500']),
        new DynamicRecipientData('01822222222', ['customer_name' => 'Karim', 'amount' => '2200']),
    ],
));

// Returns array{request_id: string, message: string}
$requestId = $response['request_id'];

Direct Broadcast (POST /broadcasts/direct)

Broadcast 1–10 direct CDN audio URLs (WAV/8000Hz/mono/pcm_s16le) to up to 999 recipients.

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Broadcasts\DataTransferObjects\SendDirectBroadcastData;

$broadcast = AwajDigital::sendDirectBroadcast(new SendDirectBroadcastData(
    phoneNumbers: ['01711111111'],
    voices: ['https://cdn.example.com/audio/message.wav'],
));

Direct TTS Broadcast (POST /broadcasts/direct-tts)

Dispatches raw text converted on the fly via AwajDigital's AI TTS engine (rate limited to 1 req/sec). Returns HTTP 202.

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Broadcasts\DataTransferObjects\SendDirectTtsBroadcastData;

$response = AwajDigital::sendDirectTtsBroadcast(new SendDirectTtsBroadcastData(
    phoneNumbers: ['01711111111'],
    texts: ['আপনার অ্যাকাউন্ট নবায়ন সফল হয়েছে।'],
    voice: 'female',
    languageCode: 'bn-BD',
));

// Check status by request ID
$status = AwajDigital::getDirectTtsStatus($response['request_id']);
if ($status->status === 'completed') {
    $broadcastId = $status->broadcastId;
}

// Or automatically poll until completion (maxAttempts: 10, intervalSeconds: 2)
$status = AwajDigital::pollDirectTtsStatus($response['request_id']);

List Broadcasts & Results

// List broadcasts from the last 30 days (date range maximum: 90 days)
$history = AwajDigital::listBroadcasts(
    startDate: '2026-09-01T00:00:00Z',
    endDate: '2026-09-29T00:00:00Z',
);

// Get detailed call results and status distribution
$result = AwajDigital::getBroadcastResult($broadcastId);
$answered = $result->statusDistribution['answered'] ?? 0;
echo "Completed: {$result->completeCount}, Answered: {$answered}";

2. Surveys (IVR)

Template Survey (POST /surveys)

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Surveys\DataTransferObjects\CreateSurveyData;

$survey = AwajDigital::createSurvey(new CreateSurveyData(
    templateName: 'published_template_slug',
    phoneNumbers: ['01711111111'],
    webhookUrl: 'https://example.com/api/webhooks/survey-completed',
));

Direct Survey (POST /v1/surveys/direct-order)

Define a full dynamic IVR tree without a pre-published template, combining library voices or CDN URLs with DTMF branch options.

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Surveys\DataTransferObjects\CreateDirectSurveyData;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Surveys\DataTransferObjects\DtmfOptionData;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Surveys\DataTransferObjects\VoiceEntry;

$survey = AwajDigital::createDirectSurvey(new CreateDirectSurveyData(
    phoneNumbers: ['01711111111'],
    questionVoices: [
        VoiceEntry::library('intro_question_voice'),
    ],
    dtmfOptions: [
        new DtmfOptionData(key: '1', voices: [VoiceEntry::library('ack_yes_voice')]),
        new DtmfOptionData(key: '2', voices: [VoiceEntry::library('ack_no_voice')]),
    ],
    retryCount: 1,
    webhookUrl: 'https://example.com/api/webhooks/survey-completed',
));

// Query survey results and call progress by survey ID
$result = AwajDigital::getSurveyResult($survey->id);
echo "Total calls: {$result->totalCount}, Completed: {$result->completeCount}";

Handling Survey Completion Webhook

Use SurveyWebhookPayloadData in your webhook controller to parse the incoming JSON payload:

use Illuminate\Http\Request;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Surveys\DataTransferObjects\SurveyWebhookPayloadData;

Route::post('/api/webhooks/survey-completed', function (Request $request) {
    $payload = SurveyWebhookPayloadData::fromArray($request->all());

    foreach ($payload->results as $result) {
        // $result['phone_number'], $result['status'], $result['response']
    }

    return response()->json(['status' => 'acknowledged']);
});

3. Voices & Senders

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Voices\DataTransferObjects\UploadVoiceData;

// List approved and pending account voices
$voices = AwajDigital::listVoices();

// Upload a new audio file (MP3, WAV, OGG, M4A, AAC, WEBM, FLAC; max 10MB)
// Option A: From local path
$upload = AwajDigital::uploadVoice(UploadVoiceData::fromPath(
    filePath: storage_path('app/audio/prompt.wav'),
    name: 'Customer Support Welcome',
));

// Option B: From controller UploadedFile
// $upload = AwajDigital::uploadVoice(UploadVoiceData::fromUploadedFile($request->file('audio')));

// List approved caller IDs / senders
$senders = AwajDigital::listSenders();

4. Payments

AwajDigital provides a hosted checkout portal for refilling account balances.

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Payments\DataTransferObjects\CreatePaymentData;

// Initiate payment (minimum 20 BDT; URLs must use HTTPS)
$payment = AwajDigital::createPayment(new CreatePaymentData(
    amount: 500.0,
    successUrl: 'https://example.com/billing/payment-success',
    cancelUrl: 'https://example.com/billing/payment-cancelled',
));

// Redirect user to payment URL
return redirect($payment->paymentUrl);

// Verify status and trigger balance fulfillment
$status = AwajDigital::getPaymentStatus($payment->invoiceId);
if ($status->status === 'completed') {
    // Payment verified and account credited
}

5. Call Center (Agents & SDK)

Manage call center agents and issue temporary session tokens for browser widgets.

use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;

// List agents
$agents = AwajDigital::listAgents();

// Query agent call logs for a specific date (YYYY-MM-DD)
$callLogs = AwajDigital::listAgentCalls(
    agentId: 10,
    date: '2026-09-29',
    page: 1,
);

// Mint a temporary SDK token for the browser widget
$tokenData = AwajDigital::mintSdkToken(agentId: 10);
// Returns: tokenData->token, tokenData->expiresIn, tokenData->sessionUrl

// Revoke an active browser session
AwajDigital::revokeSdkSession(agentId: 10);

Call Widget (Browser Embed)

This package handles backend token issuance and session revocation. The browser call widget (amarvoice-call.js) runs client-side in the browser and connects via WebRTC/SIP directly to AwajDigital.

Example Token Route

Create a secure backend endpoint in your Laravel application:

use Illuminate\Http\Request;
use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;

Route::middleware('auth:sanctum')->post('/api/call-center/token', function (Request $request) {
    $tokenData = AwajDigital::mintSdkToken($request->user()->call_center_agent_id);

    return response()->json($tokenData);
});

The frontend widget is loaded from AwajDigital's CDN on an allowlisted HTTPS origin:

<script src="https://dashboard.awajdigital.com/sdk/amarvoice-call.js"></script>

For complete client-side JavaScript widget options and event listeners, refer to the AwajDigital Browser Widget Documentation.

Exceptions

All exceptions thrown by this package extend MdAnisujjamanBd\AwajdigitalLaravel\Exceptions\AwajDigitalException.

Exception Class HTTP Status Trigger Condition
ClientValidationException None Thrown locally before sending HTTP requests (e.g. invalid phone number, file > 10MB, texts > 10, date range > 90 days).
AuthenticationException 401 Invalid or missing API Bearer token.
InsufficientBalanceException 402 Account balance is insufficient to initiate the broadcast.
PermissionDeniedException 403 Missing feature permission (e.g. Direct Broadcast, AI TTS) or unapproved sender. Provides $e->hint.
NotFoundException 404 Broadcast, survey, invoice, or agent ID not found.
ConflictException 409 Duplicate request_id reused within the 15-minute window on conflict endpoints.
ValidationFailedException 400, 413, 415, 422 Server-side validation failure. Access raw error details via $e->errors and $e->duplicatedNumber.
RateLimitedException 429 Rate limit exceeded (e.g. Direct TTS 1 req/sec). Retry delay in seconds via $e->retryAfterSeconds.
ServerErrorException 500, 502 Remote server error, gateway issue, or retry of a failed dynamic broadcast.
ApiException Any Generic fallback for unexpected HTTP responses.

Note

Client-side validation checks run before any network requests are dispatched, preventing unnecessary API calls and preserving your rate limits.

Testing Your Own App

When writing tests in your Laravel application, use AwajDigital::fake():

use Illuminate\Support\Facades\Http;
use MdAnisujjamanBd\AwajdigitalLaravel\Facades\AwajDigital;
use MdAnisujjamanBd\AwajdigitalLaravel\Modules\Broadcasts\DataTransferObjects\SendOtpData;

public function test_it_dispatches_otp_broadcast(): void
{
    // Preload standard success responses for all AwajDigital endpoints
    AwajDigital::fake();

    // Call your application logic
    $this->postJson('/api/request-voice-otp', [
        'phone' => '01712345678',
    ])->assertOk();

    // Assert that the OTP request was sent
    AwajDigital::assertSent(function ($request) {
        return str_contains($request->url(), '/broadcasts/otp')
            && $request->data()['phone_number'] === '01712345678';
    });
}

You can also pass custom stub overrides:

AwajDigital::fake([
    '*/balance' => Http::response(['success' => true, 'balance' => 9999.0], 200),
]);

AI-Assisted Development

This repository includes tailored .ai/ guidelines and agent skills for AI coding assistants. For host applications using Laravel Boost, a bundled skill is available under resources/boost/skills/awajdigital-laravel-development/SKILL.md to assist AI tools in writing accurate AwajDigital client code.

Contributing

Please review the Contributing Guide for details on code standards and testing.

Security

If you discover a security vulnerability, please review the Security Policy.

License

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