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

Sendportal Core Laravel Package

mettle/sendportal-core

Core Laravel package powering SendPortal, a self-hosted email marketing platform. It provides models, services, and backend logic for managing subscribers, lists, campaigns, templates, and sending email through multiple providers.

View on GitHub
Deep Wiki
Context7

Getting Started

SendPortal Core is the Laravel domain package behind SendPortal-style email marketing: subscribers, tags, campaigns, messages, sending adapters, and provider webhooks. For v4.0.1, treat this as a maintenance patch with no obvious breaking changes called out, but with meaningful reliability fixes around sending, webhooks, merge tags, and subscription links. Upgrade and retest those paths rather than assuming a no-op patch.

Start with:

  • Install via Composer (mettle/sendportal-core), publish the package config/migrations using the package’s publish tags, and run migrations.
  • Confirm Laravel fundamentals first: database connection, queue driver, mailer config, scheduler, and app.timezone.
  • Inspect the package service provider, config file, models/services for Campaign, Subscriber, Message, and Tag, and the mail adapter/webhook handlers.
  • Run one end-to-end flow before building UI: create a subscriber/tag, create a campaign/template, queue a send, and receive a provider webhook.
  • If using SES, Postmark, Postal, or SMTP, validate that specific adapter path after v4.0.1 because several fixes land there.

First practical use case: add SendPortal Core to an existing Laravel app as the email-marketing domain layer, keep your app’s UI and business rules outside the vendor package, and use queues for both campaign sending and webhook processing.

Implementation Patterns

  • Keep package models/services as the domain layer and put app-specific behaviour in your own services, listeners, jobs, and policies. Avoid editing vendor files.
  • Use queued jobs for campaign sends and webhook handling. Run queue:work in every environment that sends mail or processes provider callbacks, and schedule campaign dispatch/processing as needed.
  • Configure one mail transport per environment and test the exact adapter. v4.0.1 includes fixes for Postal, SMTP failure reporting, SES webhook handling, and Postmark subscription-change webhooks.
  • For webhooks, use a thin controller: verify the provider signature if supported, store the raw payload, dispatch a job, and return quickly. Make handlers idempotent because providers retry.
  • If you use Postmark, add handling for the new SubscriptionChange webhook type. If you use SES, recheck your webhook mapping against the updated handler.
  • Render merge tags through the package’s normal content-merging path. Test {{email}}, {{first_name}}, and {{last_name}}, plus any spaced variants, because this release includes both a merge-tag spacing change and a revert.
  • Treat message IDs from provider headers as case-insensitive. v4.0.1 normalizes header case for message ID extraction, so custom parsers/reporting should normalize before lookup.
  • Use package events, config, and custom adapter bindings as extension points where available. Publish config/migrations rather than modifying package defaults.
  • For reporting, expect SMTP failures to be recorded more accurately after this release. Reconcile dashboards that previously counted failed SMTP sends as successful.

Gotchas and Tips

  • Run migrations after upgrading. v4.0.1 adds IDs to campaign statuses in a migration; check any custom seeders, status lookups, exports, or reporting that assume status records without stable IDs.
  • displayDate now defaults to the configured timezone. Set app.timezone explicitly and clear config cache after deployment; otherwise date display may shift in unexpected ways.
  • Merge-tag behaviour needs regression testing. The release includes “ignore spaces when merging subscriber tags” and then a revert of that change, so do not assume spaced tags like {{ first_name }} are safe without testing your installed version.
  • Subscription links that no longer resolve now return 404 instead of 500. Update custom error pages, monitoring, and UX flows that expected a server error.
  • Header-case normalization can affect bounce/complaint correlation and message lookup. If you store provider message IDs, normalize case on write and read.
  • Postal users should retest the adapter after the PostalAdapter fix. SMTP users should expect failed sends to be reported as failed, which may increase visible failure counts but improves accuracy.
  • The slow campaign query fix helps, but still review indexes on campaign/message/subscriber tables for large lists.
  • Webhook endpoints should be excluded from CSRF where appropriate, return 2xx quickly, and log raw payloads for debugging. Provider retries can create duplicate events, so dedupe by provider event ID/message ID.
  • After upgrade, clear cached config/routes and restart queue workers. Long-running workers can keep old code in memory.
  • No breaking changes are obvious from the v4.0.1 notes, but this patch touches sending status, webhook parsing, merge tags, timezone display, and migrations. Treat it as a “test sending and tracking end-to-end” release, not a blind composer update.
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
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
cgv/localized-resource