mysteryinfosolutions/crazytel-sms
Composer 安装命令:
composer require mysteryinfosolutions/crazytel-sms
包简介
Laravel package for sending SMS via the Crazytel API (https://developer.crazytel.io)
README 文档
README
A small Laravel package for sending SMS through the Crazytel API
(POST /api/v2/sms/send and POST /api/v2/sms/bulk-send), plus account balance,
phone numbers, verified caller IDs, and SMS delivery tracking.
Install
If you're publishing this as a local/private package, add it to your app's composer.json
as a path repository, or just copy the src/, config/, and composer.json into a
packages/crazytel-sms directory in your Laravel app. Then:
composer require mysteryinfosolutions/crazytel-sms:@dev php artisan vendor:publish --tag=crazytel-sms-config
This publishes config/crazytel-sms.php.
Configure
Add to your .env:
CRAZYTEL_API_KEY=your_sms_api_key_from_the_crazytel_portal
CRAZYTEL_SMS_FROM=61412345678
Notes:
- The SMS API key is generated separately in the Crazytel portal (not the same as your general account API key).
frommust be a verified Caller ID / SMS sender number starting with04or614.CRAZYTEL_BASE_URLdefaults tohttps://crazytel.io— override only if Crazytel gives you a different base URL for your account.
Usage
Facade
use Crazytel\Sms\Facades\CrazytelSms; // Uses the default "from" number from config $result = CrazytelSms::send('0412345678', 'Your OTP is 123456'); if ($result->success) { // Keep $result->uuid to look up delivery status/events later logger()->info("SMS {$result->status}, uuid {$result->uuid}, cost {$result->price} {$result->priceUnit}"); } // Override the sender per-call CrazytelSms::send('61412345678', 'Hello!', from: '61498765432'); // Optional: suppression list + an idempotency key so a retry can't double-send CrazytelSms::send('0412345678', 'Hello!', optOutList: 'marketing', idempotencyKey: 'order-42-otp');
Sends go through the current POST /api/v2/sms/send endpoint. The $result->uuid
is the message's stable ID for later delivery-tracking lookups.
Dependency injection
use Crazytel\Sms\CrazytelSms; class ReminderController { public function __invoke(CrazytelSms $sms) { $sms->send('0412345678', 'Your appointment is tomorrow at 10am.'); } }
Bulk send
use Crazytel\Sms\Facades\CrazytelSms; $batch = CrazytelSms::sendBulk( to: ['0412345678', '0498765432'], message: 'System maintenance tonight 11pm-1am AEST.', optOutList: 'announcements', // optional, recommended for campaigns ); // Batch summary echo "{$batch->queued} queued, {$batch->rejected} rejected, {$batch->skipped} skipped"; // Per-recipient results — the result is iterable and countable foreach ($batch as $result) { // $result->to, $result->success, $result->status, $result->uuid, $result->statusDetail }
sendBulk() returns a Crazytel\Sms\Messages\BulkSmsResult (from
POST /api/v2/sms/bulk-send): batch counters as properties, plus the
per-recipient SmsResult list you can iterate directly.
Error handling
Both send() and sendBulk() throw Crazytel\Sms\Exceptions\CrazytelSmsException on
HTTP failure (400 malformed body, 401 unauthorized, 402 insufficient balance, 403 sender
not allowed, 422 invalid SMS data, 429 rate limited, 500 server error, or 502 SMS service
unreachable), and also for invalid phone number formats.
use Crazytel\Sms\Exceptions\CrazytelSmsException; try { CrazytelSms::send($to, $message); } catch (CrazytelSmsException $e) { logger()->error($e->getMessage(), $e->context()); }
Laravel Notifications
You can also route notifications through Crazytel:
use Crazytel\Sms\Channels\CrazytelSmsChannel; use Crazytel\Sms\Messages\CrazytelSmsMessage; use Illuminate\Notifications\Notification; class AppointmentReminder extends Notification { public function via($notifiable): array { return [CrazytelSmsChannel::class]; } public function toCrazytelSms($notifiable): CrazytelSmsMessage { return CrazytelSmsMessage::create("Reminder: your appointment is at {$this->time}."); } }
On your notifiable model (e.g. User), define where the SMS should go:
public function routeNotificationForCrazytelSms(): string { return $this->phone_number; }
Then register the channel in a service provider if you want to resolve it via the
container automatically — Laravel will resolve CrazytelSmsChannel from the container,
which in turn resolves CrazytelSms (already bound by CrazytelSmsServiceProvider).
Account resources
Besides sending SMS, the Crazytel client exposes a few read-only account
endpoints. Resolve it via the Crazytel facade, dependency injection, or
app(\Crazytel\Sms\Crazytel::class).
use Crazytel\Sms\Facades\Crazytel; // Credit balance $balance = Crazytel::balance()->get(); echo $balance->balance; // e.g. 42.50 echo $balance->accountCode; // Your DIDs (optionally filtered by country/state/city/number_type/did_number) foreach (Crazytel::phoneNumbers()->list() as $number) { echo "{$number->didNumber} ({$number->state}) \${$number->monthlyFee}/mo\n"; } $did = Crazytel::phoneNumbers()->find('61399999999'); // full details in $did->raw // Verified Caller IDs — validate a "from" before you send foreach (Crazytel::callerIds()->verified() as $cli) { echo "{$cli->number} ({$cli->nickname})\n"; } if (! Crazytel::callerIds()->isVerified('0412345678')) { // don't attempt the send — it would 422 } // SMS delivered/failed reporting for a window (defaults: last 30 days) $summary = Crazytel::smsCenter()->summary(from: now()->subDays(7), to: now()); echo "delivered: {$summary->outboundDelivered}, failed: {$summary->outboundFailed}\n"; echo "cost: \$" . $summary->totalCostDollars();
balance(), phoneNumbers(), callerIds(), and smsCenter() throw
Crazytel\Sms\Exceptions\CrazytelException on HTTP failure (SMS sending still
throws the more specific CrazytelSmsException, which extends it).
Delivery tracking
send()/sendBulk() return a uuid per message — use it to confirm a
customer-care SMS actually reached the handset, not just that Crazytel
accepted it:
$result = CrazytelSms::send('0412345678', 'Your appointment is tomorrow at 10am.'); // Full message record (status, text, timestamps) $message = Crazytel::smsCenter()->message($result->uuid); echo $message->status; // e.g. "delivered" // Delivery lifecycle events: accepted -> sent -> delivered (or failed) foreach (Crazytel::smsCenter()->events($result->uuid) as $event) { echo "{$event->occurredAt}: {$event->type} — {$event->description}\n"; } // Inbound-forward attempts (if this message was forwarded to a webhook/email/number) foreach (Crazytel::smsCenter()->forwards($result->uuid) as $attempt) { echo "{$attempt->destinationType} -> {$attempt->destination}: {$attempt->status}\n"; } // Email-to-SMS reply records, if applicable foreach (Crazytel::smsCenter()->emailReplies($result->uuid) as $reply) { echo "{$reply->fromEmail}: {$reply->status}\n"; }
events(), forwards(), and emailReplies() are cursor-paginated — each
returns a CursorPage (iterable/countable). Pass the page's nextCursor back
in as $cursor to fetch the next page:
$page = Crazytel::smsCenter()->events($uuid, limit: 50); while ($page->hasMore()) { $page = Crazytel::smsCenter()->events($uuid, cursor: $page->nextCursor, limit: 50); }
The Crazytel::sms() resource is equivalent to the standalone CrazytelSms
facade/class — both send through the same code.
Number format
Numbers must be Australian mobiles starting with 04 (e.g. 0412345678) or 614
(e.g. 61412345678). Crazytel converts these to E.164 internally.
API reference used
POST /api/v2/sms/send,POST /api/v2/sms/bulk-send(SMS — current V2 endpoints; the deprecated V1/api/v1/sms/*endpoints are no longer used)GET /api/v1/balance/(balance)GET /api/v1/phone-numbers,GET /api/v1/phone-numbers/{did_number}(DIDs)GET /api/v1/account/verified-cli/(verified Caller IDs)GET /api/v1/sms_center/stats/summary(SMS reporting)GET /api/v1/sms_center/stats/messages/{uuid}(message detail)GET /api/v1/sms_center/stats/messages/{uuid}/events(delivery events)GET /api/v1/sms_center/stats/messages/{uuid}/forwards(forward attempts)GET /api/v1/sms_center/stats/messages/{uuid}/email-replies(email replies)- Auth: header
X-Crazytel-Api-Key: your_api_key - Full spec: https://crazytel.io/docs
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 1
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-12