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,
],
// 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'
);
}
};
});
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 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
}
};
});
// 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();
}
// 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());