mg-techlegend/laravel-notify-africa 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

mg-techlegend/laravel-notify-africa

Composer 安装命令:

composer require mg-techlegend/laravel-notify-africa

包简介

Laravel Notify Africa is a lightweight Laravel package for sending SMS via the Notify Africa API. It provides a clean, expressive interface for single and bulk messaging, integrates with Laravel Notifications, and simplifies SMS delivery without dealing with raw HTTP requests.

README 文档

README

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Send SMS through the Notify Africa HTTP API from Laravel apps. This package provides a small typed client, a fluent message builder, structured response objects, Laravel Notification channel support, and a facade—using Laravel’s HTTP client (no direct Guzzle usage in your code).

Installation

composer require mg-techlegend/laravel-notify-africa

Publish the configuration file:

php artisan vendor:publish --tag="laravel-notify-africa-config"

Laravel discovers the service provider and facade automatically from composer.json (extra.laravel.providers and extra.laravel.aliases). No manual registration is required in typical apps.

Set the following in your .env (values are read only through config/notify-africa.php):

Variable Description
NOTIFY_AFRICA_API_TOKEN Bearer API token from Notify Africa
NOTIFY_AFRICA_SENDER_ID Default sender ID (can be overridden per message)
NOTIFY_AFRICA_BASE_URL Optional; default https://api.notify.africa
NOTIFY_AFRICA_TIMEOUT Request timeout in seconds (default 10)
NOTIFY_AFRICA_CONNECT_TIMEOUT Connect timeout in seconds (default 5)
NOTIFY_AFRICA_HTTP_RETRY_ATTEMPTS Total HTTP attempts per call (default 1 = no retries); see HTTP retries
NOTIFY_AFRICA_HTTP_RETRY_DELAY_MS Delay in milliseconds between retries (default 250)
NOTIFY_AFRICA_DEFAULT_COUNTRY_CODE Optional; see Phone numbers
NOTIFY_WABA_API_KEY WhatsApp (WABA) API key — separate credential from SMS; see WhatsApp (WABA)
NOTIFY_WABA_BASE_URL Optional; default https://notify-web-assistant-api.beagile.africa
NOTIFY_WABA_TIMEOUT WABA request timeout in seconds (default 10)
NOTIFY_WABA_CONNECT_TIMEOUT WABA connect timeout in seconds (default 5)
NOTIFY_WABA_WEBHOOK_SECRET Optional; HMAC-SHA256 secret for verifying inbound WABA webhooks
NOTIFY_WABA_SIGNATURE_HEADER Optional; signature header name (default X-Notify-Signature)

Configuration

Published config: config/notify-africa.php.

  • api_token — required for real API calls (missing token throws when the client is built).
  • sender_id — default sender; omit on the message object to use this value.
  • http_retry_attempts / http_retry_delay_ms — optional resilient requests; see below.
  • default_country_calling_code — digits only, no + (e.g. 255). Used only for “local-looking” numbers; see below.

HTTP retries

When http_retry_attempts is greater than 1, the client retries only on connection failures and on HTTP 408, 425, 429, and 5xx responses. 4xx errors such as 401 and 422 are not retried.

Retries use Laravel’s HTTP client (throw: false on the pending request) so the last response is always parsed and mapped to the same package exceptions. Increasing retries can mean duplicate SMS if a request succeeds at the gateway but the response never reaches your server—keep attempts conservative unless you accept that trade-off.

Direct usage

Inject the entry service or use the facade:

use TechLegend\LaravelNotifyAfrica\Facades\LaravelNotifyAfrica;
use TechLegend\LaravelNotifyAfrica\LaravelNotifyAfrica as NotifyAfrica;
use TechLegend\LaravelNotifyAfrica\NotifyAfricaMessage;

// Facade
$response = LaravelNotifyAfrica::sendSms(
    LaravelNotifyAfrica::message()
        ->to('255689737459')
        ->content('Hello from Laravel!')
        // ->senderId('CUSTOM') // optional override
);

// Container (class or string alias registered by the package)
$notify = app(NotifyAfrica::class);
// $notify = app('notify-africa');

$response = $notify->sendSms(
    NotifyAfricaMessage::make()
        ->to('255689737459')
        ->content('Hello!')
);

$response is a SendSmsResponse with messageId, deliveryStatus (e.g. PROCESSING), and envelope metadata.

Bulk SMS

Uses the documented batch endpoint POST /api/v1/api/messages/batch (not a client-side loop):

use TechLegend\LaravelNotifyAfrica\Facades\LaravelNotifyAfrica;

$response = LaravelNotifyAfrica::sendBulkSms(
    ['255763765548', '255689737839'],
    'Same text for everyone',
    // optional third argument: sender ID override; otherwise config default is used
);

// $response->messageCount, creditsDeducted, remainingBalance

Delivery status

$status = LaravelNotifyAfrica::getMessageStatus('156022');
// $status->status, $status->deliveredAt, etc.

WhatsApp (WABA)

WhatsApp Business messaging uses its own base URL and API key — a different host and credential from SMS. Set NOTIFY_WABA_API_KEY (and, if needed, NOTIFY_WABA_BASE_URL). The HTTP retry and default country calling code settings are shared with the SMS client.

The WhatsApp service is resolved lazily, so SMS-only apps never need WABA credentials configured until they call whatsapp().

use TechLegend\LaravelNotifyAfrica\Facades\LaravelNotifyAfrica;

// Plain text
LaravelNotifyAfrica::whatsapp()->sendText('255700000001', 'Habari! Karibu BrightSmile.');

// Pre-approved template (parameters keyed by position)
LaravelNotifyAfrica::whatsapp()->sendTemplate('255700000001', 'hello_world', [
    '1' => 'John',
    '2' => 'BrightSmile',
]);

// Multiple recipients (string or array; numbers are normalised like SMS)
LaravelNotifyAfrica::whatsapp()->sendText(['255700000001', '255700000002'], 'Hi');

sendText posts to POST /v1/waba-api/messages/text and sendTemplate to POST /v1/waba-api/messages/template, both with Authorization: Bearer {NOTIFY_WABA_API_KEY}. Both return a WhatsAppSendResponse with apiStatus, envelopeMessage, and a results array of WhatsAppRecipientResult (to, success, messageId, error). Failures map to the same exceptions as SMS (see Exceptions).

Inbound and delivery webhooks

Register your webhook URL in the Notify Portal, then handle inbound messages and delivery reports with WabaWebhookHandler:

use Illuminate\Http\Request;
use TechLegend\LaravelNotifyAfrica\Waba\WabaWebhookHandler;

Route::post('/webhooks/waba', function (Request $request, WabaWebhookHandler $handler) {
    $result = $handler->handle($request);
    // ['successful' => bool, 'event_type' => string, 'data' => [...], 'message' => string, 'status_code' => int]

    return response()->json($result, $result['status_code']);
});

When NOTIFY_WABA_WEBHOOK_SECRET is set, the handler verifies an HMAC-SHA256 signature from the configured header (NOTIFY_WABA_SIGNATURE_HEADER, default X-Notify-Signature); a bad or missing signature yields a 401-shaped result. The inbound payload schema is undocumented, so every request is logged in full (via Log::info) and parsed defensively into normalised fields from, text, wa_message_id, business_number, and event_type (with the raw payload kept under raw). Confirm the real field names from the first logged delivery and adjust if needed.

Exceptions

Exception When
NotifyAfricaAuthenticationException HTTP 401 / 403
NotifyAfricaValidationException HTTP 400 / 422, or JSON envelope status ≠ 200 with HTTP 200
NotifyAfricaRequestException Other failures, non-JSON responses, 5xx, connection issues

All extend NotifyAfricaException and expose ?array $payload with the decoded JSON when available.

Local validation (empty phone, empty message, missing sender, invalid notification setup) throws InvalidArgumentException before any HTTP call. Many messages are prefixed with [Notify Africa] so logs are easy to filter.

Laravel notifications

Use the channel class in via() and implement toNotifyAfrica() on your notification. The notifiable must define routeNotificationForNotifyAfrica() returning the recipient number (string).

use Illuminate\Notifications\Notification;
use TechLegend\LaravelNotifyAfrica\Channels\NotifyAfricaChannel;
use TechLegend\LaravelNotifyAfrica\NotifyAfricaMessage;

class OrderShippedSms extends Notification
{
    public function via(object $notifiable): array
    {
        return [NotifyAfricaChannel::class];
    }

    public function toNotifyAfrica(object $notifiable): NotifyAfricaMessage
    {
        return NotifyAfricaMessage::make()
            ->content('Your order has shipped.');
        // Phone comes from routeNotificationForNotifyAfrica() when `to()` is omitted
    }
}

On your notifiable (e.g. User model):

public function routeNotificationForNotifyAfrica(): string
{
    return $this->phone; // e.g. 2557… (see below)
}

If toNotifyAfrica() already sets ->to(...), that number is used; otherwise the channel applies the routed number.

Phone numbers

The API expects international format without a leading + (e.g. 255XXXXXXXXX). The package strips spaces and non-digits and removes a leading +.

If you set default_country_calling_code (e.g. 255) and the number looks “local” (9–10 digits after normalization), that prefix is prepended. This is a simple heuristic—not a substitute for libphonenumber or full validation. Prefer passing fully qualified international numbers in production.

Testing your app

In tests, use Laravel’s HTTP client fakes so no real SMS is sent:

use Illuminate\Support\Facades\Http;

Http::fake([
    'https://api.notify.africa/api/v1/api/messages/send' => Http::response([
        'status' => 200,
        'message' => 'SMS sent successfully',
        'data' => ['messageId' => '1', 'status' => 'PROCESSING'],
    ], 200),
]);

If you change notify-africa config inside a test, clear resolved singletons or boot a fresh application before resolving NotifyAfricaClient, since it is registered as a singleton.

Testing this package

composer test
composer analyse   # PHPStan
composer format    # Pint

Assumptions (v1)

  • Error semantics follow common HTTP usage (401/403 auth, 400/422 validation). If the live API differs, adjust mapping in NotifyAfricaClient::mapFailure() and keep tests in sync.
  • Bulk sending uses the official batch API; behavior matches Notify Africa SMS API.
  • No database tables, queues, webhooks, or logging persistence in v1.

Changelog

See CHANGELOG.md.

Contributing

See CONTRIBUTING.md.

Security

Please review our security policy on how to report security vulnerabilities.

Credits

Notify Africa and iPF Softwares

The SMS API behind this package is Notify Africa, built and operated by iPF Softwares. Documentation: SMS API. Official PHP client (separate from this Laravel package): notify-africa-php.

License

The MIT License. See LICENSE.md.

mg-techlegend/laravel-notify-africa 适用场景与选型建议

mg-techlegend/laravel-notify-africa 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 12 次下载、GitHub Stars 达 1, 最近一次更新时间为 2026 年 03 月 21 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「laravel」 「TechLegend」 「laravel-notify-africa」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 mg-techlegend/laravel-notify-africa 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 mg-techlegend/laravel-notify-africa 我们能提供哪些服务?
定制开发 / 二次开发

基于 mg-techlegend/laravel-notify-africa 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 12
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 1
  • 点击次数: 44
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 1
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-03-21