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

Extra Laravel Package

stampie/extra

stampie/extra extends Stampie, the PHP library for sending email through provider APIs, with additional adapters, helpers, and convenience classes. It simplifies adding extra mail-service integrations and common email-sending functionality to PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

stampie/extra is a small set of decorator mailers around stampie/stampie. It does not replace the base library; it gives you ready-made wrappers for logging, profiling, retrying, rate-limiting, tagging, and identity/from-address switching without touching your existing send calls.

Minimal setup:

composer require stampie/extra

You still need a base Stampie mailer and HTTP adapter. Then wrap it:

use Stampie\Mailer\Mailgun;
use Stampie\Extra\Retry\Mailer as RetryMailer;
use Stampie\Extra\Logger\Mailer as LoggerMailer;

$base = new Mailgun($adapter, $apiKey, $domain);

$mailer = new RetryMailer($base, 3);                 // retry transient failures
$mailer = new LoggerMailer($mailer, $psr3Logger);    // log every attempt

$mailer->send($message);

Look first at vendor/stampie/extra/src. The useful classes are the decorators: Logger\Mailer, Profiler\Mailer, Retry\Mailer, RateLimit\Mailer, Tagger\Mailer, and Identity\Mailer. They all implement Stampie\MailerInterface, so they are drop-in replacements for the base mailer.

The first realistic use case: you already send transactional mail through Stampie and want retry, logging, and rate limiting without changing every call site. Swap the mailer in one place, e.g. a Laravel service provider binding.

Note: the package was archived in May 2022. Pin a specific version, run composer audit, and expect to fork or vendor it if you need PHP 8.2+ compatibility fixes.

Implementation Patterns

Build an onion, outermost first. Decorator order is meaningful:

$mailer = new Mailgun($adapter, $key, $domain);       // transport
$mailer = new RateLimitMailer($mailer, $limiter);     // protect provider quota
$mailer = new RetryMailer($mailer, 3);                // retry what gets through
$mailer = new LoggerMailer($mailer, $logger);         // observe all attempts
$mailer = new ProfilerMailer($mailer);                // dev only

A retry inside a rate limiter can burn quota on repeated failures; a logger outside a retry sees every attempt, which is usually what you want for debugging.

Bind it once in Laravel. Do not construct decorators per request or per job:

$this->app->singleton(\Stampie\MailerInterface::class, function ($app) {
    $base = new \Stampie\Mailer\SendGrid($adapter, config('services.sendgrid.key'));

    $mailer = new \Stampie\Extra\Retry\Mailer($base, 3);
    $mailer = new \Stampie\Extra\Logger\Mailer($mailer, $app['log']->channel('mail'));

    return $mailer;
});

Resolve Stampie\MailerInterface in jobs and services.

Use Identity\Mailer for multi-tenant or multi-brand apps. Instead of scattering setFrom() calls, wrap the mailer with an identity object so all mail for a tenant uses consistent from/reply-to addresses. This keeps sending logic out of your message factories.

Use Tagger\Mailer for provider analytics. If your provider supports tags/categories (SendGrid, Mailgun, etc.), tagging at the mailer layer avoids adding provider headers in every message. Tags that a provider does not support are usually ignored — verify per transport.

Queue sends in Laravel, but avoid double retries. If you use Laravel queues and Retry\Mailer, decide which layer owns retries. A common pattern is: queue job handles re-queuing for application-level failures; Retry\Mailer handles short transient network/5xx blips inside a single attempt.

Testing. Implement a tiny Stampie\MailerInterface that records sent messages, and compose your decorators around it. Assert on captured messages rather than hitting a provider. Keep a config flag that swaps in this fake for local/test environments.

Message construction. Stampie messages expose from/to/subject/text/html/headers/attachments via Stampie\Message or your own MessageInterface implementation. Build a small factory or mapper so decorators only deal with MailerInterface, not message assembly.

Gotchas and Tips

  • Archived package. No upstream fixes. Treat stampie/extra as frozen: pin the version, test on your PHP version, and be prepared to copy the decorators into your app if you need changes.
  • Decorator order is not cosmetic. Logger outside retry records every attempt; logger inside records only successful sends. Rate limiting inside retry can be bypassed by retry loops. Decide deliberately.
  • Retries can duplicate mail. If the provider accepted the message but the HTTP response failed, a retry sends it again. Stampie has no idempotency key. Retry only on clearly transient failures (connection errors, 429, 5xx), not on ambiguous timeouts.
  • Rate limiting is only as distributed as your limiter. In-process counters do nothing across multiple queue workers. Use a shared backend (Redis, database, Symfony rate limiter, etc.) if you run more than one worker.
  • Logging may capture PII. Message bodies and recipient addresses are sensitive. Scrub or redact before writing to logs, and avoid debug-level body logging in production.
  • Identity decorators may mutate messages. If the same message object is reused, clone before sending or ensure the identity decorator does not permanently rewrite the message.
  • sendBatch support varies. If you rely on batch sending, confirm each decorator forwards sendBatch; a decorator that only implements send() will silently disable batching.
  • Catch the right exceptions. Stampie throws API/HTTP exceptions for provider failures. In Laravel jobs, map those to $this->release() or failed() appropriately rather than letting every exception bubble.
  • Profiler memory in long-running workers. A profiler that accumulates timings will grow unbounded in queue workers and Octane. Enable it only in local/dev or reset it periodically.
  • Attachments are held in memory. Base64 encoding large files multiplied by retries can spike memory. Stream or cap attachment sizes.
  • Config caching. Resolving the mailer from config inside a request works, but binding a singleton is cheaper and makes decorator state (rate limiter, profiler) predictable.
  • Extension point. Any class implementing Stampie\MailerInterface can sit in the chain. Writing your own decorator (metrics, tenant context, suppression list) is usually easier than modifying stampie/extra — and it survives the archived status.
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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
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