PHP code example of graystackit / laravel-ahasend-api
1. Go to this page and download the library: Download graystackit/laravel-ahasend-api library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
graystackit / laravel-ahasend-api example snippets
use GraystackIT\Ahasend\AhasendService;
class OrderController
{
public function __construct(private readonly AhasendService $mailer) {}
public function confirm(): void
{
$this->mailer->sendHtml(
to: [['email' => '[email protected]', 'name' => 'Jane']],
subject: 'Order confirmed',
htmlContent: '<p>Your order is confirmed!</p>',
textContent: 'Your order is confirmed!',
);
}
}
$mailer->sendText(
to: [['email' => '[email protected]']],
subject: 'Hello',
textContent: 'Hello from Ahasend!',
);
use GraystackIT\Ahasend\Data\EmailMessage;
$message = new EmailMessage(
fromEmail: '[email protected]',
fromName: 'Sender',
to: [['email' => '[email protected]']],
subject: 'Custom',
htmlContent: '<p>Hello</p>',
);
$ahasendMessageId = $mailer->send($message);
// In EventServiceProvider or a listener class:
Event::listen(MailDelivered::class, function (MailDelivered $event): void {
// $event->messageId, $event->recipient, $event->deliveryAttempt, $event->payload
});
use App\Mail\OrderShipped;
use Illuminate\Support\Facades\Mail;
// Uses the default mailer if MAIL_MAILER=ahasend
Mail::to('[email protected]')->send(new OrderShipped($order));
// Or target the driver explicitly
Mail::mailer('ahasend')
->to('[email protected]')
->cc('[email protected]')
->send(new OrderShipped($order));
namespace App\Mail;
use Illuminate\Mail\Mailable;
use Illuminate\Mail\Mailables\Content;
use Illuminate\Mail\Mailables\Envelope;
class OrderShipped extends Mailable
{
public function __construct(public readonly Order $order) {}
public function envelope(): Envelope
{
return new Envelope(subject: 'Your order has shipped');
}
public function content(): Content
{
return new Content(
html: 'emails.order-shipped', // resources/views/emails/order-shipped.blade.php
text: 'emails.order-shipped-text',
);
}
public function attachments(): array
{
return [
Attachment::fromPath(storage_path("invoices/{$this->order->id}.pdf"))
->as('invoice.pdf')
->withMime('application/pdf'),
];
}
}
use GraystackIT\Ahasend\Traits\TracksAhasendMail;
use Illuminate\Mail\Mailable;
class OrderShipped extends Mailable
{
use TracksAhasendMail;
public function build(): self
{
$this->initAhasendTracking(recipient: $this->order->email);
return $this->subject('Your order has shipped')
->view('emails.order-shipped');
}
}
use GraystackIT\Ahasend\Services\MessageService;
use GraystackIT\Ahasend\Enums\MessageStatus;
class MyController
{
public function __construct(private readonly MessageService $messages) {}
}
$cancelled = $messages->cancel('msg-scheduled-001'); // true on success
use GraystackIT\Ahasend\Services\SmtpCredentialService;
class MyController
{
public function __construct(private readonly SmtpCredentialService $smtp) {}
}
// Global credential (can send from any domain)
$credential = $smtp->create('My Application');
// Scoped credential (restricted to specific domains)
$credential = $smtp->create(
name: 'My Application',
scope: 'scoped',
domains: ['yourdomain.com', 'anotherdomain.com'],
);
// Sandbox credential (no real emails sent)
$credential = $smtp->create('Test App', sandbox: true);
// Save the password — the API will not return it again.
echo $credential->id; // 'cred-xyz'
echo $credential->username; // 'smtp_my_application'
echo $credential->password; // 'generated-secret' (only available on create)
echo $credential->sandbox; // bool
echo $credential->scope; // 'global' or 'scoped'
echo $credential->domains; // string[] — the domains it's scoped to; empty when scope is 'global'
use GraystackIT\Ahasend\Services\SuppressionService;
class MyController
{
public function __construct(private readonly SuppressionService $suppressions) {}
}
$result = $suppressions->list(
limit: 50, // optional
after: 'cursor-xyz', // optional
before: 'cursor-abc', // optional
domain: 'example.com', // optional — filter by sending domain
email: '[email protected]', // optional — filter by recipient email
fromTime: '2026-01-01T00:00:00Z', // optional — RFC3339, created after
toTime: '2026-01-31T23:59:59Z', // optional — RFC3339, created before
);
foreach ($result['data'] as $suppression) {
echo $suppression->email;
}
// $result['pagination'] contains has_more / next_cursor / previous_cursor
$suppressions->delete('[email protected]'); // true on success
$suppressions->delete('[email protected]', domain: 'example.com'); // scoped to one domain
$suppressions->deleteAll(); // true on success — wipes the entire account list
$suppressions->deleteAll(domain: 'example.com'); // wipes only suppressions for this domain
use GraystackIT\Ahasend\Services\ReportService;
class MyController
{
public function __construct(private readonly ReportService $reports) {}
}
use GraystackIT\Ahasend\Services\DomainManager;
$domains = app(DomainManager::class);
// $owner is any Eloquent model — the package never interprets it.
$domain = $domains->add('acme.at', $owner);
foreach ($domain->outstandingRecords() as $record) {
echo "{$record->type->value} {$record->host} {$record->content}";
}
$domain = $domains->refresh($domain); // "check DNS" button
$domain->isVerified(); // true once every
use GraystackIT\Ahasend\Exceptions\DomainLimitExceededException;
try {
$domains->add('second.at', $owner);
} catch (DomainLimitExceededException $e) {
$e->blockingDomains; // ['first.at'] — offer "check DNS" or "delete" for these
}
use GraystackIT\Ahasend\Support\InboundChannels;
app(InboundChannels::class)->register(
name: 'payslip', // → POST /ahasend/inboundmail/payslip
domain: config('payroll.mail.receiving_domain'),
secret: config('payroll.mail.inbound_secret'), // e.g. PAYROLL_MAIL_SECRET
queue: null, // optional, see "Handoff" below
);
$this->app->bind(InboundScreen::class, VirusScreen::class);
final class VirusScreen implements InboundScreen
{
public function screen(InboundDelivery $delivery): ScreenVerdict
{
// ScreenVerdict::accept() — hand it to the listeners
// ScreenVerdict::discard() — drop it; no listener ever sees it
// ScreenVerdict::defer(300) — ask again in five minutes
}
public function gaveUp(InboundDelivery $delivery): void
{
// Deferred until the retry window closed; tell the sender if you like.
}
}
use GraystackIT\Ahasend\Events\InboundMailReceived;
class RouteInboundMail
{
public function handle(InboundMailReceived $event): void
{
// With a handoff queue this already runs in a worker. Without one, queue
// the real work: AhaSend retries on any non-2xx response, so slow
// synchronous handling produces duplicates. $deliveryId is stable across
// those retries — use it as the idempotency key.
ProcessInboundMail::dispatch($event->message, $event->deliveryId);
}
}
$message->text(); // reply-stripped body when the route produced one
$message->parentMessageIds(); // In-Reply-To, then References newest-first
$message->isAutomated(); // Auto-Submitted / Precedence / List-Id / X-Auto-Response-Suppress
$message->inlineAttachments(); // parts referenced by cid: in the HTML body
$message->attachments[0]->contents(); // decoded bytes
$message->spamScore;
$message->raw; // anything not modelled yet