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

Php Laravel Package

ghasedak/php

A lightweight PHP client for the Ghasedak SMS API, making it easy to send SMS, OTP codes, and bulk messages, check delivery status, and integrate messaging into Laravel or plain PHP applications with a simple, framework-agnostic interface.

View on GitHub
Deep Wiki
Context7

Getting Started

The package is a thin, Guzzle-based wrapper around Ghasedak's v2 HTTP API — not a Laravel package. There is no service provider, facade, or config file to publish. You wire it yourself in a few lines.

1. Install

composer require ghasedak/php

2. Get credentials

Log into the Ghasedak panel → Settings → API and copy the API key. Also note the line number (sender) you've provisioned; you cannot send from an arbitrary number.

3. First send

require 'vendor/autoload.php';

use Ghasedak\GhasedakApi;

$api = new GhasedakApi($_ENV['GHASEDAK_API_KEY']);

$response = $api->SendSimple(
    '09123456789',            // receptor — mobile number
    '3000xxxx',               // sender — your provisioned line
    'Test message from app'   // message body
);

var_dump($response);

Where to look first

  • src/GhasedakApi.php — the entire surface area lives in this one class. Read the method signatures before you trust the README, which is in Persian and partly outdated.
  • The README examples for SendSimple, SendOTP, and SendBulk.
  • composer.json — check the pinned Guzzle major version before installing into an existing project.

First real use case

The most common day-one need is a transactional OTP: a single short message to a single receptor, triggered from a login or verification flow. Start there, then expand to bulk and status checks once you've confirmed the flow works against your provisioned line.

Implementation Patterns

Wrap it in your own client, not the raw class

Because the package has no DI, config, or logging, treat GhasedakApi as a low-level transport. Wrap it:

namespace App\Services;

use Ghasedak\GhasedakApi;

class SmsService
{
    private GhasedakApi $client;

    public function __construct(string $apiKey)
    {
        $this->client = new GhasedakApi($apiKey);
    }

    public function send(string $to, string $message, ?string $sender = null)
    {
        return $this->client->SendSimple(
            $to,
            $sender ?? config('services.ghasedak.line'),
            $message
        );
    }
}

Bind it in AppServiceProvider with the key pulled from config/services.php, and keep the API key out of source control.

Laravel notification channel

For day-to-day Laravel work you'll usually want SMS to be a notification channel rather than a direct call. Implement a small channel that delegates to your SmsService:

public function send($notifiable, Notification $notification)
{
    $message = $notification->toSms($notifiable);
    $this->sms->send($notifiable->routeNotificationFor('sms'), $message);
}

Then queue the notification (ShouldQueue) so a slow Ghasedak response never blocks a request.

OTP pattern

SendOTP is the fastest path for verification codes — it accepts a receptor, the code, and optional template parameters depending on your panel configuration. Store the code server-side with an expiry and compare on submit; never trust the number alone.

Bulk and pair sends

  • SendBulk / SendBulk2 — multiple receptors in one call; cheaper and faster than looping SendSimple. Check the signature carefully — the two bulk methods have different argument shapes.
  • SendPair — paired send/return messaging, useful for two-way conversations.

Status, credit, and inbox polling

For operational tooling (a dashboard, an alert when credit is low), call GetCredit, CheckSMSStatus, and GetInbox. Schedule these via a queued job rather than inline in a request; they're simple GETs but still round-trip to a third party.

Retry and idempotency

The package does no retrying. Add a small retry wrapper around your SmsService for transient failures (timeouts, 5xx), and use the API's clientId / client_reference parameter where supported so a retried send isn't duplicated.

Gotchas and Tips

Responses are inconsistent. Some methods return a decoded object, others the raw body string, and errors come back with a numeric code plus a Persian message. Don't assert() on the shape — normalise inside your wrapper:

$body = json_decode((string) $response);
if (!isset($body->result) || $body->result->code !== 200) {
    throw new SmsException($body->message ?? 'Unknown Ghasedak error');
}

No connection reuse guarantees. Each call constructs the Guzzle request through the internal client; if you're sending dozens of messages, use the bulk endpoint instead of a loop over SendSimple.

Sender line must exist. A 400 from SendSimple is almost always an unprovisioned or mistyped sender. Test against your panel's Send page first, then copy the exact line number.

Receptor format. Ghasedak expects local Iranian format (09xxxxxxxxx). Passing +989... or 989... will often fail validation. Normalise at the boundary of your SmsService.

Unicode costs money. Persian text and emoji force the Unicode encoding, which reduces the characters-per-segment count and doubles the price. Keep OTP templates ASCII digits where possible to stay in a single GSM segment.

Guzzle pinning is the main integration risk. The package was last released in September 2022 and pins an older Guzzle major. In a modern Laravel 10/11 app you may hit a guzzlehttp/guzzle version conflict. Either install alongside and let Composer resolve (often fine), or replace the transport entirely — the API surface is small enough that a hand-written Http::post('https://api.ghasedak.me/v2/sms/send/simple', ...) is a viable, dependency-free alternative.

No tests, no facade, no config. Everything is your responsibility: DI binding, logging, masking the API key in exception messages, and rate limiting. The package also lacks typed exceptions, so map HTTP 401/403/429 to your own error classes.

Debugging tips. Enable Guzzle debug by constructing your own client if you need request/response logging — the package's internal client isn't exposed. For 401s, check the key isn't URL-encoded or padded with whitespace from .env. For silent failures, log the raw response body before decoding; the Persian error text tells you exactly which parameter was rejected.

Extension points. There are none beyond method calls — no middleware, event hooks, or transport injection. If you need customisation (proxy, timeout, mock transport for tests), you're better off copying the ~200 lines of GhasedakApi.php into your app and owning it. Given the low activity on the repo (last release 2022, no dependents), that's often the pragmatic move for a production integration.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core