Download the PHP package awaisjameel/texto without Composer

On this page you can find all versions of the php package awaisjameel/texto. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.

FAQ

After the download, you have to make one include require_once('vendor/autoload.php');. After that you have to import the classes with use statements.

Example:
If you use only one package a project is not needed. But if you use more then one package, without a project it is not possible to import the classes with use statements.

In general, it is recommended to use always a project to download your libraries. In an application normally there is more than one library needed.
Some PHP packages are not free to download and because of that hosted in private repositories. In this case some credentials are needed to access such packages. Please use the auth.json textarea to insert credentials, if a package is coming from a private repository. You can look here for more information.

  • Some hosting areas are not accessible by a terminal or SSH. Then it is not possible to use Composer.
  • To use Composer is sometimes complicated. Especially for beginners.
  • Composer needs much resources. Sometimes they are not available on a simple webspace.
  • If you are using private repositories you don't need to share your credentials. You can set up everything on our site and then you provide a simple download link to your team member.
  • Simplify your Composer build process. Use our own command line tool to download the vendor folder as binary. This makes your build process faster and you don't need to expose your credentials for private repositories.
Please rate this library. Is it a good library?

Informations about the package texto

Texto

Unified, extensible Laravel gateway for sending & receiving SMS/MMS over Twilio & Telnyx, plus WhatsApp through Meta's Cloud API. Batteries included: queueing, retries, events, webhooks, polling, typed value objects.

Latest Version on Packagist Tests Downloads

Texto provides a unified, extensible Laravel package for carrier-grade SMS/MMS and WhatsApp messaging. Built for Laravel 10–13 (PHP 8.1+), it abstracts provider complexities (Twilio, Telnyx, Meta's WhatsApp Cloud API) through consistent contracts and value objects, enabling seamless integration with enterprise messaging workflows.

Key Features:


Table of Contents

  1. Motivation & Philosophy
  2. Feature Overview
  3. Quick Start
  4. Installation
  5. Configuration (config/texto.php)
  6. Usage Examples
  7. Queueing & Async Flow
  8. Events & Observability
  9. Data Model & Persistence
  10. Webhooks (Inbound + Status)
  11. Security (Signatures, Secrets, Rate Limiting)
  12. Status Polling (Adaptive Fallback)
  13. Retry & Backoff Strategy
  14. Twilio Conversations & Content Templates
  15. Overriding a Built‑in Driver
  16. API Reference (Value Objects, Enums, Events, Interfaces)
  17. Console Commands
  18. Testing, Fakes & Local Development
  19. Architecture Overview
  20. Troubleshooting & FAQ
  21. Performance Considerations & Best Practices
  22. Roadmap
  23. Contributing
  24. Security Policy
  25. Migration Guide
  26. License & Credits

Provider deep dives: WhatsApp Cloud API guide


1. Motivation & Philosophy

Building messaging features in Laravel applications often involves wrestling with provider-specific APIs that have inconsistent interfaces, error handling, and webhook formats. Without proper abstraction, code becomes littered with conditional logic that breaks when switching providers or adding new ones.

Texto solves this by providing a clean, consistent interface that:

The philosophy is simple: messaging should be a first-class citizen in your Laravel app, not an afterthought that requires constant maintenance.


2. Feature Overview

Core Messaging

Reliability & Performance

Advanced Twilio Features

Observability & Events

Security & Compliance

Developer Experience


3. Quick Start


4. Installation

Prerequisites

Before installing Texto, ensure your Laravel application meets these requirements:

Quick Installation

The fastest way to get started:

This command will:

Manual Installation

For more control over the installation process:

Provider Setup

If you're not using package auto-discovery, add the service provider to config/app.php:

Verification

After installation, verify everything is working:

This will send a test message using your configured provider and settings.

Environment Variables


5. Configuration (config/texto.php)

After installation, you'll find the configuration file at config/texto.php. Here's a comprehensive guide to all available options:

Core Settings

Key Default Description
driver 'twilio' Active messaging provider ('twilio', 'telnyx', or 'whatsapp')
store_messages true Whether to persist messages in the database
queue false Enable async message sending via Laravel queues
validation.region 'US' Default region for parsing non‑E.164 phone numbers (TEXTO_DEFAULT_REGION)

Retry Configuration

Controls exponential backoff retry behavior for failed API calls:

Webhook Security

Status Polling (Fallback)

Configures fallback polling for messages stuck in transient states:

Twilio Configuration

Twilio-specific settings for both classic and Conversations API modes (the base_urls array pinning the Messaging, Conversations, and Content API hosts is also part of this block).

Telnyx Configuration

Telnyx API credentials, messaging profile configuration, the base64-encoded Ed25519 public key used to verify webhook signatures, the maximum accepted webhook timestamp age, and a transport timeout (seconds) for outbound REST calls.

WhatsApp Configuration

Configure access_token, phone_number_id, app_secret, and verify_token in the whatsapp block. WhatsApp uses Meta's signed webhook at /texto/webhook/whatsapp and does not support status polling. See the complete WhatsApp Cloud API guide for setup, templates, media, and webhook configuration.

Testing Configuration

Settings for testing environments to skip webhook signature validation.


6. Usage Examples

Basic SMS Sending

Send a simple text message:

MMS with Media Attachments

Send messages with images, videos, or other media:

Per-Message Driver Override

Temporarily use a different provider for specific messages:

Custom Sender Number and Metadata

Use different sender numbers and attach custom metadata:

Asynchronous Queue Processing

For high-throughput applications, enable queuing:

Controller Response

Return messages directly from controllers (auto-converts to JSON):

Event-Driven Processing

Listen to messaging events for analytics and automation:

Bulk Messaging

Send multiple messages efficiently:

International Number Handling

Texto automatically handles international formatting:


7. Queueing & Async Flow

  1. In queue mode, Texto::send() stores a queued row (status queued).
  2. Dispatches SendMessageJob with deterministic primary key.
  3. Job invokes Texto::send(... ['queued_job'=>true,'queued_message_id'=>X]) to perform real API send.
  4. Repository upgrades the exact queued record (no racey pattern matching).
  5. Status webhooks or polling complete remaining transitions.

Benefits: immediate API responses, backpressure via Laravel queue, deterministic DB state.

Note: The queued job now includes a snapshot of the active driver configuration (API keys, profile IDs, etc.) so workers and scheduled pollers have the same credentials that were present when the message was enqueued. Ensure your queue transport (e.g., database table, Redis) is appropriately protected since provider secrets travel with the job payload.


8. Events & Observability

Event Fired When Payload
MessageSent Successful provider send SentMessageResult
MessageFailed Send attempt threwTextoSendFailedException SentMessageResult, error message
MessageReceived Inbound webhook parsed WebhookProcessingResult
MessageStatusUpdated Stored message status advanced (webhook) WebhookProcessingResult

Subscribe in EventServiceProvider or use listeners/jobs for analytics, billing, triggers.

Structured logging is emitted at info / debug levels for sends, polling promotions, template initialization, and failures.


9. Data Model & Persistence

Table: texto_messages

Column Notes
direction sent / received
driver twilio / telnyx / whatsapp
from_number / to_number E.164 formatted
body Nullable for pure media inbound
media_urls JSON array
status Normalized enum (queued, sending, sent, delivered, read, received, failed, undelivered, ambiguous)
provider_message_id SID / Telnyx ID (nullable until known)
error_code Provider error (if any)
segments_count (Telnyx) part count
cost_estimate (Telnyx) estimated cost
metadata Arbitrary JSON (includes polling counters, conversation info)
sent_at / received_at / status_updated_at Timestamps

Ambiguous terminal state occurs when polling exhausts attempts without a provider id or final disposition.


10. Webhooks

Auto‑registered routes:

Provider Endpoint Methods
Twilio /texto/webhook/twilio POST (inbound + status)
Telnyx /texto/webhook/telnyx POST (inbound + status)
WhatsApp /texto/webhook/whatsapp GET (Meta subscription verify handshake) + POST (inbound + status, batched)

Each provider publishes inbound and status callbacks to a single endpoint. Texto inspects each payload to determine whether it is an inbound message or a delivery status update, ensuring identical processing across providers. WhatsApp webhooks arrive batched; every entry in the batch is processed individually.

Twilio Conversations events authored by your own configured from_number (the echo of a message Texto itself sent) are recognized as authentic and intentionally ignored, so outbound messages are never re‑recorded as inbound.

Each request passes through RateLimitTextoWebhook – a per‑minute throttle (webhook.rate_limit). Authenticity is enforced by each provider's cryptographic signature inside the handler (Twilio X-Twilio-Signature, Telnyx Ed25519, Meta X-Hub-Signature-256). The VerifyTextoWebhookSecret middleware (X-Texto-Secret header, TEXTO_WEBHOOK_SECRET) is not attached to these routes — providers cannot send custom headers — it is shipped for guarding your own application‑defined endpoints.

Inbound payloads are normalized into WebhookProcessingResult then persisted via EloquentMessageRepository.


11. Security

Mechanism Description
Twilio Signature X-Twilio-Signature validated (HMAC‑SHA1 over the full public URL + sorted POST params). Behind a TLS‑terminating proxy, configure TrustProxies so the public URL is reconstructed.
Telnyx Signature Ed25519 signature validated against the Telnyx public webhook key (ext-sodium), with timestamp tolerance (TELNYX_WEBHOOK_TOLERANCE).
WhatsApp Signature Meta's X-Hub-Signature-256 (HMAC‑SHA256 of the raw body with WHATSAPP_APP_SECRET) validated; GET verify handshake uses WHATSAPP_VERIFY_TOKEN.
Shared Secret Header VerifyTextoWebhookSecret middleware checks X-Texto-Secret against TEXTO_WEBHOOK_SECRET — for your own endpoints, not the packaged provider routes.
Rate Limiting RateLimitTextoWebhook throttles every packaged webhook endpoint per minute.
Phone Parsing All numbers canonicalized using libphonenumber.

Signature validation can be skipped in test environments via TEXTO_TESTING_SKIP_WEBHOOK_VALIDATION=true.


12. Status Polling (Fallback)

Some production networks delay webhooks or they can be transiently disabled. Polling covers that gap.

Enable via TEXTO_STATUS_POLL_ENABLED=true. The service provider auto‑schedules StatusPollJob each minute. Logic:

Metadata counters (poll_attempts, last_poll_at, flags) are merged into metadata JSON for auditability.


13. Retry & Backoff

Retry::exponential() wraps critical provider API calls (send operations). Configured by retry.max_attempts & retry.backoff_start_ms. Delay doubles each attempt until max attempts reached. Exceptions escalate as TextoSendFailedException leading to MessageFailed event emission and (optionally) DB record with status failed.


14. Twilio Conversations & Content Templates

The Conversations API is the default. You opt in to the classic Messages API (one call per SMS, outbound-only) by setting TWILIO_USE_CONVERSATIONS=false. In Conversations mode, Texto:

  1. Lazily initializes Conversations sub‑client.
  2. Ensures (or creates) SMS / MMS Content Templates (friendly names configurable).
  3. Creates (or reuses) a Conversation per send (deduplicates participant collisions & reuses existing).
  4. Optionally attaches per‑conversation webhook (config conversation_webhook_url or metadata override).
  5. Sends message using template variables (splitting long body into up to 5 × 100‑char chunks). Falls back to body variant if template fails.

Captured metadata includes: conversation_sid, conversation_reused, optional conversation_webhook_sid.

Successful sends cache their conversation SID per (from, to) pair (default 7 days, TWILIO_CONVERSATION_CACHE_TTL seconds, 0 disables), so repeat sends to the same recipient skip the conversation setup calls and only POST the message. If a cached conversation was closed or deleted in the meantime, the full setup flow runs once automatically. A conversation created for a send that ultimately fails is deleted again (best effort) so failed sends leave no orphans.

On the classic Messages path, metadata['webhook_url'] is passed to Twilio as the per‑message StatusCallback (mirroring the Telnyx driver), so delivery receipts reach /texto/webhook/twilio without configuring callbacks on the number or messaging service.

Webhook signature note: Twilio signs the public URL of your webhook. If the app runs behind a TLS‑terminating proxy or load balancer, configure Laravel's TrustProxies middleware so fullUrl() reconstructs the public https:// URL — otherwise every signature validation fails.

Per‑Instance Credentials (no container singletons)

The package no longer binds the low‑level provider API adapters (TwilioMessagingApiInterface, TelnyxMessagingApiInterface, …) into the container. Adapters capture credentials at construction, so a boot‑time singleton would silently keep using stale (or another tenant's) credentials under per‑send driver_config overrides. Every sender now constructs its adapters from its own configuration, and each adapter authenticates its HTTP calls with its own credentials. Tests and custom integrations inject fake adapters through the sender constructors, e.g. new TwilioSender($config, $fakeMessagingApi).

The HTTP macro Http::twilio() is still credential‑aware; it omits Basic Auth when credentials are missing so generic tests can stub endpoints without failures.

Content Template Creation Robustness

Template creation logic now tolerates varied (mock) response shapes and will parse a sid from either a direct field or nested content record arrays. No behavioral change is required for production usage; failures still fall back to body‑only send paths.


15. Overriding a Built‑in Driver

extend() swaps the sender used for an existing built‑in driver (twilio, telnyx, or whatsapp). The name must match a recognized Driver enum value — extending an unknown name throws a TextoException. To add a genuinely new provider, add a Driver enum case (see below), not extend().

Sender requirements:

Adding a brand‑new provider: introduce a new case in the Driver enum, map its raw statuses in StatusMapper, and register the sender. Each extend() name is bound to a Driver enum case, so a new provider cannot be resolved until its enum case exists. Contributing it back via PR is encouraged.


16. API Reference

Texto Facade

The main entry point for all messaging operations.

Texto::send(string $to, string $body, array $options = []): SentMessageResult

Send an SMS or MMS message.

Parameters:

Options:

Note: When supplying driver_config, remember that any secrets included will travel with the queued job payload and logs you emit. Use encrypted queues or other safeguards appropriate for your environment.

Returns: SentMessageResult object

Example:

Value Objects

PhoneNumber

Represents a validated, E.164 formatted phone number.

Methods:

SentMessageResult

Immutable result object returned after sending a message.

WebhookProcessingResult

Result object for webhook processing.

Enums

MessageStatus

Normalized message status values.

Driver

Available messaging providers.

Direction

Message direction.

Events

MessageSent

Fired when a message is successfully sent.

MessageReceived

Fired when an inbound message is received via webhook.

MessageStatusUpdated

Fired when a stored message's status advances via a provider status webhook.

MessageFailed

Fired when a message send attempt fails.

Exceptions

TextoException

Base exception for all Texto-related errors.

TextoSendFailedException

Thrown when message sending fails.

TextoWebhookValidationException

Thrown when webhook validation fails (bad signature or malformed payload). It renders as an HTTP 403 response so providers treat the request as permanently unacceptable and stop retrying, rather than receiving a 500 that triggers retry storms.

Interfaces

MessageSenderInterface

Contract for message sending implementations.

MessageRepositoryInterface

Contract for message persistence.

DriverManagerInterface

Contract for driver management.

Console Commands

php artisan texto:install

Install and configure Texto.

php artisan texto:test-send {to} {body?} {--driver=}

Send a test message.

Parameters:


17. Console Commands

Command Description
texto:install Publish config + migration then run migrate.
texto:test-send {to} {body?} Fire a manual test message (optional--driver=).

18. Testing, Fakes & Local Development

Run full suite:


19. Architecture Overview

Layer Responsibility
Texto facade/root Orchestrates send workflow, queue placeholder creation, events.
DriverManager Resolves concrete sender implementation (built‑ins + extensions).
Drivers (TwilioSender, TelnyxSender, WhatsappSender) Provider API invocation + provider‑specific metadata enrichment. Each constructs its own API adapters from its config.
StatusMapper Converts raw provider statuses / events to internal enum.
EloquentMessageRepository Persistence & deterministic queued upgrade + polling updates.
Jobs (SendMessageJob, StatusPollJob) Async send & periodic status reconciliation.
Webhook Handlers Parse & validate inbound/status payloads per provider.
Support Utilities (Retry, PollingParameterResolver) Cross‑cutting helpers.
Value Objects / Enums Strongly typed domain primitives.

Design goals: minimal public API surface (Texto::send), encapsulated provider variance, explicit lifecycle events, observability via logs + metadata.


20. Troubleshooting & FAQ

Common Issues

Q: Messages stuck in queued status A: This usually indicates queue processing issues.

Q: Webhook signature validation fails (401 errors) A: Signature validation ensures webhook authenticity.

Q: Twilio Conversations template creation warnings A: Template auto-provisioning may fail due to permissions.

Q: Telnyx cost/segment data missing A: Cost and segment information is only provided in specific response scenarios.

Q: Messages failing with provider errors A: Check provider account status and configuration.

Q: High memory usage with large message volumes A: Optimize for high-throughput scenarios.

Status Definitions

Q: What does ambiguous status mean? A: Messages reach ambiguous status when polling exhausts all attempts without determining final delivery status.

Q: Difference between failed and undelivered? A: These represent different failure modes:

Configuration Issues

Q: How to disable message persistence? A: Set TEXTO_STORE_MESSAGES=false in your environment.

Q: Phone number validation too strict A: Adjust the default region for number parsing.

Provider-Specific Issues

Q: Twilio rate limiting A: Twilio enforces sending limits based on account type.

Q: Telnyx webhook delays A: Telnyx webhooks may have higher latency than Twilio.

Performance Tuning

Q: Optimizing for high volume A: Several configuration options for performance:

Q: Database performance with many messages A: The texto_messages table can grow quickly.

Development & Testing

Q: Testing without sending real messages A: Use the fake driver for testing:

Q: Local development with webhooks A: Webhooks require public URLs for provider access.

Extending Texto

Q: Adding a new provider (e.g., Vonage) A: extend() only overrides the senders of built‑in drivers (twilio, telnyx, whatsapp); passing an unrecognized name (such as 'vonage') throws a TextoException. A genuinely new provider needs its own Driver enum case so the manager can resolve it:

Q: Custom webhook handling A: Extend webhook handlers for custom logic:


21. Performance Considerations & Best Practices

Database Optimization

For high-volume applications, optimize the texto_messages table:

Queue Configuration

For reliable message processing at scale:

Run multiple workers for high throughput:

Monitoring & Alerting

Implement monitoring for critical messaging operations:

Cost Optimization

Track and optimize messaging costs:

Security Best Practices

Secure your messaging infrastructure:

Error Handling & Resilience

Implement comprehensive error handling:

Testing Strategies

Comprehensive testing approach:

Scaling Considerations

For enterprise-level messaging:

  1. Horizontal Scaling: Deploy across multiple servers with shared queue
  2. Database Sharding: Split message storage across multiple databases
  3. CDN for Media: Use CDNs for MMS media to reduce bandwidth
  4. Provider Redundancy: Implement multi-provider failover logic
  5. Caching: Cache frequently used phone number validations
  6. Async Processing: Always use queues for production deployments

Compliance & Data Protection

Handle sensitive messaging data appropriately:

22. Roadmap

Planned Features

Community Contributions

We welcome contributions! Areas of particular interest:

Version Compatibility

Texto Version Laravel Version PHP Version Status
1.x 10.x - 13.x 8.1+ Active

See the CHANGELOG.md for upgrade notes.


23. Contributing

We welcome contributions from the community! Here's how to get involved:

Development Setup

Contribution Guidelines

  1. Open an Issue First: For significant changes, open a descriptive issue to discuss the proposed changes.
  2. Code Quality: All contributions must pass quality checks:

  3. Testing: Add tests for new features and bug fixes:

    • Unit tests for classes and methods
    • Integration tests for full workflows
    • Use the FakeSender for testing without external APIs
  4. Documentation: Update documentation for user-visible changes:

    • README.md for new features and usage examples
    • Inline code documentation (PHPDoc)
    • CHANGELOG.md for version history
  5. Type Safety: Keep new public APIs strongly typed using PHP 8.1+ features (enums, readonly properties, constructor promotion).

Code Style

Follow Laravel's coding standards with Pint configuration:

Testing Strategy

Pull Request Process

  1. Branch Naming: Use descriptive branch names:

    • feature/add-vonage-driver
    • fix/webhook-validation-bug
    • docs/improve-api-reference
  2. Commit Messages: Follow conventional commits:

    • feat: add Vonage driver support
    • fix: resolve webhook signature validation
    • docs: update API reference section
  3. PR Description: Include:

    • Clear description of changes
    • Screenshots for UI changes (if applicable)
    • Test coverage information
    • Breaking changes (if any)
  4. Review Process: All PRs require review and must pass CI checks.

Areas for Contribution

High Priority:

Medium Priority:

Good for Beginners:

Community Support

Recognition

Contributors are recognized in:

Thank you for contributing to Texto! 🎉


24. Security Policy

Report vulnerabilities privately via GitHub Security Advisories. Do not disclose publicly until patched. Avoid sharing live credentials or full raw webhook payloads containing PII in issues.


25. Migration Guide

Upgrading Versions

Unreleased (next version)

Breaking: the low-level provider API adapters (TwilioMessagingApiInterface, TelnyxMessagingApiInterface, WhatsappApiInterface, …) are no longer bound in the service container. If you resolved them via app(...), construct them directly with the credentials they should use (e.g. new TelnyxMessagingApi($apiKey)), or inject a custom implementation through the sender constructors (new TwilioSender($config, $fakeMessagingApi)). See CHANGELOG.md for the full list of changes.

From 1.0.x to 1.1.x

No breaking changes. New features include:

Migration Steps:

  1. Update package: composer update awaisjameel/texto
  2. Review new configuration options in config/texto.php
  3. Update environment variables if needed
  4. Test webhook endpoints with new validation

From 0.x to 1.x

Breaking changes in the 1.0 release:

Configuration Changes:

API Changes:

Migration Steps:

  1. Backup your database
  2. Update to 1.x: composer update awaisjameel/texto
  3. Run php artisan texto:install to update config and migrations
  4. Update any code using status strings to use MessageStatus enums
  5. Test thoroughly in staging environment

Environment Variable Changes

Old Variable New Variable Notes
- TEXTO_STORE_MESSAGES Control message persistence
- TEXTO_QUEUE Enable async processing
- TEXTO_WEBHOOK_SECRET Shared secret for webhook auth
- TEXTO_STATUS_POLL_ENABLED Enable status polling fallback

Database Schema Changes

Version 1.x adds new columns to texto_messages:

These are nullable and backward compatible.

Webhook URL Changes

Webhook routes remain the same but include enhanced validation:

Ensure your provider console webhook URLs match exactly.

Testing Changes

Update your tests to use the new FakeSender:

26. License & Credits

License

Released under the MIT License. See LICENSE.md for details.

Credits

Created by: awaisjameel

Inspiration & Thanks:

Contributors

We'd like to thank all contributors who have helped make Texto better:

Sponsors

Support Texto's development:

GitHub Sponsors

Related Projects


Made with ❤️ for the Laravel community


Quick Reference Cheat Sheet


Support & Community


Built with ❤️ for the Laravel community by awaisjameel


All versions of texto with dependencies

PHP Build Version
Package Version
Requires php Version ^8.1
spatie/laravel-package-tools Version ^1.92.7
illuminate/contracts Version ^10.0||^11.0||^12.0||^13.0
illuminate/support Version ^10.0||^11.0||^12.0||^13.0
giggsey/libphonenumber-for-php Version ^9.0
ext-sodium Version *
Composer command for our command line client (download client) This client runs in each environment. You don't need a specific PHP version etc. The first 20 API calls are free. Standard composer command

The package awaisjameel/texto contains the following files

Loading the files please wait ...