PHP code example of awaisjameel / texto

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

    

awaisjameel / texto example snippets


use Texto; // facade alias configured automatically

Texto::send('+15551234567', 'Hello world');

'providers' => [
    // ... other providers
    Awaisjameel\Texto\TextoServiceProvider::class,
],

'aliases' => [
    // ... other aliases
    'Texto' => Awaisjameel\Texto\Facades\Texto::class,
],

'retry' => [
    'max_attempts' => env('TEXTO_RETRY_ATTEMPTS', 3),
    'backoff_start_ms' => env('TEXTO_RETRY_BACKOFF_START', 200),
],

'webhook' => [
    'secret' => env('TEXTO_WEBHOOK_SECRET'),
    'rate_limit' => env('TEXTO_WEBHOOK_RATE_LIMIT', 300),
],

'status_polling' => [
    'enabled' => env('TEXTO_STATUS_POLL_ENABLED', false),
    'min_age_seconds' => env('TEXTO_STATUS_POLL_MIN_AGE', 60),
    'max_attempts' => env('TEXTO_STATUS_POLL_MAX_ATTEMPTS', 5),
    'queued_max_attempts' => env('TEXTO_STATUS_POLL_QUEUED_MAX_ATTEMPTS', 2),
    'backoff_seconds' => env('TEXTO_STATUS_POLL_BACKOFF', 300),
    'batch_limit' => env('TEXTO_STATUS_POLL_BATCH', 100),
],

'twilio' => [
    'account_sid' => env('TWILIO_ACCOUNT_SID'),
    'auth_token' => env('TWILIO_AUTH_TOKEN'),
    'from_number' => env('TWILIO_FROM_NUMBER'),
    'use_conversations' => env('TWILIO_USE_CONVERSATIONS', true),
    'timeout' => env('TWILIO_HTTP_TIMEOUT', 30),
    'sms_template_friendly_name' => env('TWILIO_SMS_TEMPLATE_FRIENDLY_NAME', 'texto_sms_template'),
    'mms_template_friendly_name' => env('TWILIO_MMS_TEMPLATE_FRIENDLY_NAME', 'texto_mms_template'),
    // Optional explicit template SIDs (skip auto discovery/creation if provided)
    'sms_template_sid' => env('TWILIO_SMS_TEMPLATE_SID'),
    'mms_template_sid' => env('TWILIO_MMS_TEMPLATE_SID'),
    'conversation_prefix' => env('TWILIO_CONVERSATION_PREFIX', 'Texto'),
    'conversation_webhook_url' => env('TWILIO_CONVERSATION_WEBHOOK_URL'),
    'conversation_cache_ttl' => env('TWILIO_CONVERSATION_CACHE_TTL', 604800),
],

'telnyx' => [
    'base_url' => env('TELNYX_BASE_URL', 'https://api.telnyx.com/v2/'),
    'api_key' => env('TELNYX_API_KEY'),
    'messaging_profile_id' => env('TELNYX_MESSAGING_PROFILE_ID'),
    'from_number' => env('TELNYX_FROM_NUMBER'),
    'webhook_secret' => env('TELNYX_WEBHOOK_SECRET'),
    'webhook_tolerance_seconds' => env('TELNYX_WEBHOOK_TOLERANCE', 300),
    'timeout' => env('TELNYX_HTTP_TIMEOUT', 30),
],

'testing' => [
    'skip_webhook_validation' => env('TEXTO_TESTING_SKIP_WEBHOOK_VALIDATION', false),
],

use Texto;

$result = Texto::send('+15551234567', 'Hello from Texto!');

// Returns SentMessageResult with status, provider ID, etc.
echo $result->status->value; // 'sent'
echo $result->providerMessageId; // 'SM1234567890abcdef'

$result = Texto::send('+15551234567', 'Check out this photo!', [
    'media_urls' => [
        'https://example.com/image.jpg',
        'https://example.com/video.mp4'
    ]
]);

// Send via Telnyx instead of default Twilio
$result = Texto::send('+15551234567', 'Via Telnyx', [
    'driver' => 'telnyx'
]);

// Send via Meta's WhatsApp Cloud API (free-form messages 

$result = Texto::send('+15551234567', 'Welcome to our service!', [
    'from' => '+15550009999', // Different sender number
    'metadata' => [
        'campaign' => 'welcome_series',
        'user_id' => 12345,
        'priority' => 'high'
    ]
]);

// In .env
TEXTO_QUEUE=true

// In code
$result = Texto::send('+15551234567', 'Queued message');
echo $result->status->value; // 'queued'

// Start a queue worker
php artisan queue:work

class NotificationController extends Controller
{
    public function sendAlert(Request $request)
    {
        $result = Texto::send(
            $request->phone,
            'Alert: ' . $request->message
        );

        // Automatically returns JSON response
        return $result;
    }
}

// In EventServiceProvider
protected $listen = [
    \Awaisjameel\Texto\Events\MessageSent::class => [
        \App\Listeners\LogMessageSent::class,
    ],
    \Awaisjameel\Texto\Events\MessageStatusUpdated::class => [
        \App\Listeners\TrackDeliveryStatus::class,
    ],
];

// Listener example
class TrackDeliveryStatus
{
    public function handle(MessageStatusUpdated $event)
    {
        $result = $event->result;

        // Log delivery metrics
        Log::info('Message delivered', [
            'provider_id' => $result->providerMessageId,
            'delivered_at' => now(),
        ]);
    }
}

$recipients = ['+15551234567', '+15559876543', '+15551111111'];
$messages = [];

foreach ($recipients as $phone) {
    $messages[] = Texto::send($phone, 'Bulk notification');
}

// Process results
$successful = collect($messages)->where('status.value', 'sent')->count();

// All of these work automatically
$phones = [
    '+1-555-123-4567',     // US format
    '555.123.4567',        // Local format (uses config region)
    '+44 20 7123 4567',    // UK format
    '0912345678',          // National format (parsed with config region)
];

foreach ($phones as $phone) {
    Texto::send($phone, 'International hello!');
}

use Awaisjameel\Texto\Contracts\DriverManagerInterface;
use Awaisjameel\Texto\Contracts\MessageSenderInterface;
use Awaisjameel\Texto\ValueObjects\{PhoneNumber, SentMessageResult};
use Awaisjameel\Texto\Enums\{Driver, Direction, MessageStatus};

// Override the sender resolved for the built-in 'twilio' driver.
app(DriverManagerInterface::class)->extend('twilio', function () {
    return new class implements MessageSenderInterface {
        public function send(PhoneNumber $to, string $body, ?PhoneNumber $from = null, array $mediaUrls = [], array $metadata = []): SentMessageResult {
            // ...call provider API...
            return new SentMessageResult(
                Driver::Twilio,
                Direction::Sent,
                $to,
                $from,
                $body,
                $mediaUrls,
                $metadata,
                MessageStatus::Sent,
                'custom-123'
            );
        }
    };
});

$result = Texto::send('+15551234567', 'Hello!', [
    'media_urls' => ['https://example.com/image.jpg'],
    'metadata' => ['campaign' => 'welcome']
]);

class PhoneNumber
{
    public readonly string $e164;

    public static function fromString(string $raw, ?string $region = null): self
}

final class SentMessageResult implements Responsable, JsonSerializable
{
    public readonly Driver $driver;
    public readonly Direction $direction;
    public readonly PhoneNumber $to;
    public readonly ?PhoneNumber $from;
    public readonly string $body;
    public readonly array $mediaUrls;
    public readonly array $metadata;
    public readonly MessageStatus $status;
    public readonly ?string $providerMessageId;
    public readonly ?string $errorCode;

    public function toArray(): array
    public function jsonSerialize(): array
    public function toResponse($request): JsonResponse
}

final class WebhookProcessingResult
{
    public readonly Driver $driver;
    public readonly Direction $direction;
    public readonly ?PhoneNumber $from;
    public readonly ?PhoneNumber $to;
    public readonly ?string $body;
    public readonly array $mediaUrls;
    public readonly array $metadata;
    public readonly ?string $providerMessageId;
    public readonly ?MessageStatus $status;

    public static function inbound(Driver $driver, PhoneNumber $from, PhoneNumber $to, ?string $body, array $media, array $metadata, ?string $providerMessageId = null): self
    public static function status(Driver $driver, ?string $providerMessageId, MessageStatus $status, array $metadata = []): self
}

enum MessageStatus: string
{
    case Queued = 'queued';      // Message queued for sending
    case Sending = 'sending';    // Message being sent
    case Sent = 'sent';          // Message sent successfully
    case Delivered = 'delivered'; // Message delivered to recipient
    case Read = 'read';          // Read by recipient (WhatsApp; terminal)
    case Received = 'received';  // Inbound message received
    case Failed = 'failed';      // Send failed permanently
    case Undelivered = 'undelivered'; // Message undelivered
    case Ambiguous = 'ambiguous'; // Status unknown after polling
}

enum Driver: string
{
    case Twilio = 'twilio';
    case Telnyx = 'telnyx';
    case Whatsapp = 'whatsapp';
}

enum Direction: string
{
    case Sent = 'sent';
    case Received = 'received';
}

class MessageSent
{
    public function __construct(public readonly SentMessageResult $result) {}
}

class MessageReceived
{
    public function __construct(public readonly WebhookProcessingResult $result) {}
}

class MessageStatusUpdated
{
    public function __construct(public readonly WebhookProcessingResult $result) {}
}

class MessageFailed
{
    public function __construct(
        public readonly SentMessageResult $result,
        public readonly ?string $reason = null
    ) {}
}

interface MessageSenderInterface
{
    public function send(PhoneNumber $to, string $body, ?PhoneNumber $from = null, array $mediaUrls = [], array $metadata = []): SentMessageResult;
}

interface MessageRepositoryInterface
{
    public function storeSent(SentMessageResult $result): Model;
    public function storeInbound(WebhookProcessingResult $result): Model;
    public function storeStatus(WebhookProcessingResult $result): ?Model;
    public function updatePolledStatus(Message $message, MessageStatus $status, array $extraMetadata = []): Message;
    public function upgradeQueued(int $id, SentMessageResult $result): ?Model;
}

interface DriverManagerInterface
{
    public function sender(?Driver $driver = null): MessageSenderInterface;
    public function extend(string $name, callable $factory): void;
}

app(\Awaisjameel\Texto\Contracts\DriverManagerInterface::class)
    ->extend('twilio', fn () => new \Awaisjameel\Texto\Drivers\FakeSender());

app(DriverManagerInterface::class)->extend('twilio', fn() => new FakeSender());

// 1. Add a case to the Driver enum (e.g. case Vonage = 'vonage';) and map its statuses in StatusMapper.
// 2. Register the sender for that driver:
app(DriverManagerInterface::class)->extend('vonage', function() {
    return new class implements MessageSenderInterface {
        public function send(PhoneNumber $to, string $body, ?PhoneNumber $from = null, array $mediaUrls = [], array $metadata = []): SentMessageResult {
            // Your implementation
        }
    };
});

// config/queue.php
'connections' => [
    'database' => [
        'driver' => 'database',
        'table' => 'jobs',
        'queue' => 'default',
        'retry_after' => 90, // Increase for messaging jobs
    ],
],

// Monitor queue health
$pendingJobs = DB::table('jobs')->where('queue', 'like', 'texto%')->count();
if ($pendingJobs > 1000) {
    Log::warning('High texto queue backlog', ['count' => $pendingJobs]);
}

// Monitor failure rates
$failureRate = Message::where('status', 'failed')
    ->where('created_at', '>', now()->subHour())
    ->count() / Message::where('created_at', '>', now()->subHour())->count();

if ($failureRate > 0.1) { // 10% failure rate
    // Alert or take action
}

// Analyze costs by provider and campaign
$costs = Message::selectRaw('
        driver,
        SUM(cost_estimate) as total_cost,
        COUNT(*) as message_count,
        AVG(cost_estimate) as avg_cost
    ')
    ->whereNotNull('cost_estimate')
    ->where('created_at', '>', now()->subMonth())
    ->groupBy('driver')
    ->get();

// Implement cost thresholds
if ($costs->sum('total_cost') > 1000) { // Monthly budget
    // Send alert or implement throttling
}

// Use environment variables for secrets
// Never commit API keys to version control

// Implement rate limiting per user/phone
RateLimiter::for('texto-send', function (Request $request) {
    return Limit::perMinute(10)->by($request->user()->id);
});

// Validate phone numbers strictly
$phone = PhoneNumber::fromString($request->phone, 'US'); // Specify region
if (!$phone) {
    throw new InvalidPhoneNumberException();
}

try {
    $result = Texto::send($phone, $message, $options);
} catch (TextoSendFailedException $e) {
    // Log detailed error
    Log::error('Message send failed', [
        'phone' => $phone,
        'error' => $e->getMessage(),
        'driver' => config('texto.driver')
    ]);

    // Implement fallback logic
    if (config('texto.driver') === 'twilio') {
        // Try Telnyx as fallback
        $result = Texto::send($phone, $message, ['driver' => 'telnyx'] + $options);
    }

    // Notify user or take alternative action
}

// Unit tests for drivers
class TwilioSenderTest extends TestCase
{
    public function test_sends_message_successfully()
    {
        // Mock Twilio client
        $this->mock(TwilioClient::class, function ($mock) {
            $mock->shouldReceive('messages->create')
                ->once()
                ->andReturn((object)['sid' => 'SM123']);
        });

        $result = app(TwilioSender::class)->send(
            PhoneNumber::fromString('+15551234567'),
            'Test message'
        );

        $this->assertEquals(MessageStatus::Sent, $result->status);
    }
}

// Integration tests with fake driver
class MessagingIntegrationTest extends TestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        // Use fake driver for integration tests
        app(DriverManagerInterface::class)->extend('twilio', fn() => new FakeSender());
    }
}

// Implement data retention policies
Message::where('created_at', '<', now()->subMonths(6))
    ->whereIn('status', ['delivered', 'failed'])
    ->delete();

// Encrypt sensitive metadata
$message->metadata = encrypt(json_encode([
    'ssn' => $sensitiveData, // Encrypted storage
    'campaign' => 'public_data'
]));

// Implement audit logging
Log::channel('messaging-audit')->info('Message sent', [
    'id' => $message->id,
    'to' => $message->to_number, // Log for compliance
    'timestamp' => now(),
    'user_id' => auth()->id()
]);

// Good: Use type hints and return types
public function send(PhoneNumber $to, string $body): SentMessageResult

// Good: Use enums for fixed values
public function __construct(public readonly MessageStatus $status)

// Good: Comprehensive PHPDoc
/**
 * Send an SMS/MMS message using the active driver.
 *
 * @param  string  $to  E.164 formatted recipient number
 * @param  string  $body  Message body text
 * @param  array{media_urls?:string[], metadata?:array}  $options
 */

// Unit test example
test('phone number validation', function () {
    $phone = PhoneNumber::fromString('+15551234567');
    expect($phone->e164)->toBe('+15551234567');
});

// Integration test example
test('message sending workflow', function () {
    // Use fake driver to avoid external calls
    app(DriverManagerInterface::class)->extend('twilio', fn() => new FakeSender());

    $result = Texto::send('+15551234567', 'Test message');

    expect($result->status)->toBe(MessageStatus::Sent);
    expect($result->providerMessageId)->toBeString();
});

// Old (0.x)
'driver' => env('TEXTO_DRIVER', 'twilio'),

// New (1.x) - same, but additional options available
'driver' => env('TEXTO_DRIVER', 'twilio'),
'store_messages' => env('TEXTO_STORE_MESSAGES', true),
'queue' => env('TEXTO_QUEUE', false),

// Old (0.x)
Texto::send('+15551234567', 'Hello');

// New (1.x) - same API, enhanced return type
$result = Texto::send('+15551234567', 'Hello');
$result->status; // Now returns MessageStatus enum

// Old approach
// Custom mock setup

// New approach
app(DriverManagerInterface::class)->extend('twilio', fn() => new FakeSender());

// Basic SMS
$result = Texto::send('+15551234567', 'Hello World!');

// MMS with media
$result = Texto::send('+15551234567', 'Check this out!', [
    'media_urls' => ['https://example.com/image.jpg']
]);

// Override provider per message
$result = Texto::send('+15551234567', 'Via Telnyx', [
    'driver' => 'telnyx'
]);

// Custom sender and metadata
$result = Texto::send('+15551234567', 'Promotional message', [
    'from' => '+15550009999',
    'metadata' => ['campaign' => 'spring_sale', 'priority' => 'high']
]);

// Async processing (when TEXTO_QUEUE=true)
$result = Texto::send('+15551234567', 'Queued message');
// $result->status === MessageStatus::Queued

// Event listeners
Event::listen(MessageSent::class, function ($event) {
    Log::info('Message sent', ['id' => $event->result->providerMessageId]);
});
bash
php artisan texto:test-send +15551234567 "Hello from Texto!"
bash
# Multiple workers for parallel processing
php artisan queue:work --queue=texto-high,texto-normal --max-jobs=1000 --sleep=3
php artisan queue:work --queue=texto-bulk --max-jobs=500 --sleep=5