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

Sendy Laravel Package

hocza/sendy

A Laravel package for integrating the Sendy email newsletter platform. It provides a clean wrapper around Sendy’s API for subscribing and unsubscribing users, managing mailing lists, and handling configuration in Laravel applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish the package config:

composer require hocza/sendy
php artisan vendor:publish --provider="Hocza\Sendy\SendyServiceProvider" --tag=config

Set the Sendy connection values in .env:

SENDY_API_KEY=your-sendy-api-key
SENDY_INSTALLATION_URL=https://sendy.example.com
SENDY_LIST_ID=your-default-list-id

Look first at:

  1. The package README for the exact facade/client method signatures.
  2. config/sendy.php after publishing, to confirm config keys and URL handling.
  3. The package client class under vendor/hocza/sendy/src to see how Sendy’s plain-text API responses are returned or normalized.

A typical first use case is subscribing a user during registration or newsletter opt-in:

use Hocza\Sendy\Facades\Sendy;

Sendy::subscribe(
    config('sendy.list_id'),
    $user->email,
    $user->name,
    true // confirm meaning of boolean/double opt-in flag in README
);

Do not call Sendy inline in a web request for day-to-day use. Treat the first integration as: validate input, persist local preference, dispatch a queued job, and let the job call Sendy.

Implementation Patterns

Wrap the package behind an app service. Keep Sendy::subscribe() calls inside one NewsletterService or SendyListService. This lets you swap the package, add logging, normalize responses, and fake the integration in tests without spreading vendor calls through controllers.

final class NewsletterService
{
    public function subscribe(User $user, string $listId): void
    {
        // Call the package client here, not in controllers.
    }
}

Use queued jobs for all Sendy writes. Sendy is an external HTTP dependency. Dispatch a job after the local user/preference transaction commits:

DB::afterCommit(fn () => SubscribeToSendy::dispatch($user->id, $listId));

Add tries, backoff(), and a queue rate limit. Subscribe is usually idempotent enough to retry, but unsubscribe/delete semantics should be checked per endpoint.

Model lists explicitly. Map application segments or audiences to Sendy list IDs in config or a database table:

'lists' => [
    'newsletter' => env('SENDY_LIST_NEWSLETTER_ID'),
    'product_updates' => env('SENDY_LIST_PRODUCT_ID'),
],

Pass the list ID per call rather than relying on a single global list. This is the main scaling point once you have more than one audience.

Keep local preference as the source of truth. Store newsletter_opted_in, newsletter_opted_in_at, and list subscriptions locally. Sendy is the delivery system, not your application’s subscription state. On preference changes, update locally first, then queue the Sendy sync.

Use status checks for reconciliation, not every request. A scheduled command can check a small sample or recently changed users with the package’s status method, if exposed. Do not status-check on every page load or login.

Test by faking your wrapper, not Sendy. Bind a fake NewsletterService in tests and assert jobs are dispatched. If you test the package client itself, use Laravel’s HTTP fake only if the package uses Laravel’s HTTP client; otherwise mock the package client class.

Gotchas and Tips

  • Sendy returns plain text, not JSON. A successful subscribe often returns 1 or true, while failures return an error string such as Invalid email address. Do not treat every HTTP 200 as success. Inspect what the package returns and normalize it in your wrapper.
  • The boolean argument is easy to misread. In Sendy’s API it typically controls double opt-in behavior. Set it explicitly and test the actual email flow; do not rely on the package default.
  • Installation URL is self-hosted and easy to get wrong. Confirm whether the package expects the Sendy base URL, the /sendy path, or a full API endpoint. Avoid trailing-slash duplication and test with the exact production URL.
  • Config caching bites after env changes. Run php artisan config:clear or php artisan config:cache after changing Sendy credentials or list IDs.
  • List IDs are identifiers, not secrets, but still config. Put them in config/env rather than hard-coding them in jobs or controllers. Keep the API key out of logs and exception messages.
  • Unsubscribe and delete are not the same. Unsubscribe keeps the subscriber record and status; delete removes it. Choose deliberately for GDPR/account-deletion flows.
  • Already-subscribed responses vary by Sendy configuration. With double opt-in enabled, resubscribing may trigger another confirmation email or return a different message. Make the job tolerant of “already subscribed” outcomes.
  • Pin the package version. This is a small, low-maintenance integration. Wrapping it and pinning the version limits risk if the package or Sendy API changes.
  • Extension point: publish config and bind your own client. If you need custom HTTP options, timeouts, or logging, bind a subclass or adapter in a service provider rather than editing vendor files.
  • Log context, not credentials. Log email, list ID, job ID, and a redacted response. Never log the Sendy API key or full request payload containing it.
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.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings