Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Laravel Algeria Sms Laravel Package

djouamaah/laravel-algeria-sms

A Laravel package for integrating Algerian SMS gateways into your applications, offering a simple way to send text messages and add SMS notifications to your PHP projects.

View on GitHub
Deep Wiki
Context7

Getting Started

This is a v1.0.0 first release, so treat the README/config file as the primary documentation — there is no legacy surface area to unlearn.

  1. Install and scaffold:

    composer require djouamaah/laravel-algeria-sms
    php artisan vendor:publish --tag=algeria-sms-config
    php artisan migrate
    

    The migration creates sms_opt_outs (and whatever OTP/log tables the package ships) — run it before anything else or optOut() and OTP verification will fail at runtime rather than at boot.

  2. Look first at config/algeria-sms.php. That is where the default driver, named providers, OTP policy (TTL, max attempts, resend cooldown, hourly cap), quiet-hours window, and locale live.

  3. In local/testing set the driver to log and send your first message:

    AlgeriaSms::send('0555 12 34 56', 'Votre commande est arrivée.');
    

    Confirm normalization works by passing the number in several formats (+213555123456, 00213555123456, 0555 12 34 56) — the package accepts all Algerian formats and derives the operator from the prefix (05 Ooredoo, 06 Mobilis, 07 Djezzy).

  4. First real use case: OTP on registration.

    AlgeriaSms::otp()->send($phone, 'register');
    AlgeriaSms::otp()->verify($phone, $code, 'register');
    

    The context argument ('register', 'login', 'reset') namespaces codes so a login code cannot be replayed against a password reset.

  5. Only after the log driver works end-to-end should you configure a real transport. Local Algerian providers do not publish API contracts, so you either fill in the generic http driver from your provider's contract docs, or register your own driver with AlgeriaSms::extend().

Implementation Patterns

Transport selection. Use log in local/testing, the generic http driver in production against whichever REST provider you have a contract with, and AlgeriaSms::extend() when a provider needs signing, XML, or multi-step auth that the generic driver can't express. Register named providers in config and switch per-environment rather than hardcoding a driver at call sites — it keeps staging on log while production goes out over HTTP.

Custom driver skeleton. Wrap provider specifics in a class implementing the package's driver contract, resolve credentials from config/services.php, map your app's message object to the provider payload, and translate the provider response into the package's success/failure result so MessageSent/MessageFailed fire correctly. Throw (don't silently return) so failed jobs retry.

OTP flows. Always pass a context. Catch the package's throttle exceptions and surface them as validation errors ("please wait N seconds") rather than 500s. Verification should be the only thing that consumes an attempt — don't call verify() speculatively in a loop. Because codes are stored as HMAC, you cannot inspect or recover them; if you need audit trails, log issuance (phone hash + context + timestamp), never the code.

Notifications. Register the algeria-sms channel and implement toAlgeriaSms() on the notification. This is the cleanest path for anything user-facing (order shipped, appointment reminder), because it composes with Notifiable routing and lets you set the phone per-notification.

Validation. Use the AlgerianMobile rule at the edge (form requests) so you never persist a number the sender can't normalize. Normalize once on write and store the canonical form; the operator prefix is then free routing metadata.

Marketing / bulk. Use AlgeriaSms::marketing($phones, SmsMessage::make(...)->gsm()). This path is the only one that automatically queues, batches, skips opted-out numbers, and respects quiet hours (21:00–08:00 Africa/Algiers). It requires a running queue worker. For very large lists, chunk at the call site too, so a single job payload stays small and one bad chunk doesn't poison the batch.

Opt-outs. Wire optOut() to your inbound webhook / customer-support tooling and call it as soon as a recipient asks. isOptedOut() is cheap — check it explicitly for transactional sends if your compliance policy treats opt-out as global rather than marketing-only. Never delete rows from sms_opt_outs; use optIn() so you keep the history.

Events for observability. Listen to MessageSent and MessageFailed to write to your own SMS log table, increment metrics, and alert on failure rate. MessageFailed is where you detect a provider outage before customers do.

Encoding-aware composition. Call ->gsm() on French copy to strip accented characters and keep messages in GSM-7 (160 chars/segment). Use the segment counter before sending to sanity-check cost on Arabic copy.

Testing. AlgeriaSms::fake() plus the usual Queue::fake() / Notification::fake(). Assert on AlgeriaSms::assertSent(...), and separately test the OTP throttle paths with time travel (travel()) rather than sleeping.

Gotchas and Tips

  • The http driver is a blank slate. The package deliberately does not ship a provider contract. You must read your provider's docs and map payload, auth headers, and success/failure response shapes yourself. Budget real time for this; a wrong success check means silent non-delivery.
  • Arabic is UCS-2: 70 characters per segment, not 160. Any mixed Arabic/French copy is UCS-2 too. Multiply your segment count by your per-SMS price before launching a campaign — this is the most common cost surprise.
  • Quiet hours are 21:00–08:00 Africa/Algiers and apply to marketing. Ensure your app/queue timezone handling doesn't fight this; if you schedule marketing jobs from a UTC server, let the package decide deferral rather than computing hours yourself. Transactional OTPs are not subject to quiet hours — don't assume they are.
  • APP_KEY rotation invalidates all outstanding OTPs. They are HMAC'd with the app key. Plan key rotation for a low-traffic window, or accept that in-flight verifications fail.
  • Throttle state lives in the cache. In a multi-server or load-balanced setup, use a shared cache store (Redis/database). The array or per-node file store will let users bypass the hourly cap and resend cooldown.
  • Normalize before optOut(). If you store the raw user-typed string in sms_opt_outs, a later send with a differently formatted number won't match the opt-out and you'll text someone who asked you to stop. Normalize at the boundary, and be aware the opt-out check is keyed on the normalized value.
  • Marketing sends require a queue worker. Without one, nothing is dispatched and you'll get no error — just silence. Verify queue:work is running in every environment where marketing is enabled, and monitor failed jobs.
  • Batching means partial failure is normal. A batch can succeed for 80% of recipients. Don't wrap a marketing call in a transaction or treat one MessageFailed as a total failure; consume the events to reconcile.
  • Don't guess operator-based routing from memory. Use the package's prefix mapping (05/06/07) rather than hardcoding — it also gives you a free validation signal.
  • Extension point: AlgeriaSms::extend() is your seam for anything the generic driver can't do (request signing, token refresh, delivery reports polling). Register it in a service provider, not inline, so config:cache doesn't break resolution.
  • Publish the config before config:cache in deploy scripts, and re-run php artisan migrate on deploy — a cached config referencing missing keys produces confusing "driver not configured" errors at send time rather than boot time.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle