Configuration
The published config/campaigns.php in full:
return [
'store' => env('CAMPAIGNS_STORE', \RoundlyConsulting\Campaigns\Stores\InMemoryCampaignStore::class),
'from-name' => env('CAMPAIGNS_FROM_NAME', ''),
'from-address' => env('CAMPAIGNS_FROM_ADDRESS', ''),
'recipients' => [
'only-verified' => env('CAMPAIGNS_ONLY_VERIFIED', false),
'contact-type' => env('CAMPAIGNS_RECIPIENT_CONTACT_TYPE', 'email'),
],
'sending-queue' => env('CAMPAIGNS_SENDING_QUEUE', 'default'),
'process-recipient-job' => \RoundlyConsulting\Campaigns\Jobs\SendCampaignEmail::class,
'notification' => env('CAMPAIGNS_NOTIFICATION'),
'notification-channel' => env('CAMPAIGNS_NOTIFICATION_CHANNEL', 'mail'),
];Every key
| Key | Default | Env | Purpose |
|---|---|---|---|
store | InMemoryCampaignStore::class | CAMPAIGNS_STORE | Where campaigns and recipients are kept — a Contracts\CampaignStore. DatabaseCampaignStore::class persists them; or point at your own. Any value that isn’t a CampaignStore class throws InvalidConfigurationException — it never falls back to the in-memory store. |
from-name | '' | CAMPAIGNS_FROM_NAME | Default sender name when a campaign is dispatched without ->from(). Seeds the DefaultFromName option. |
from-address | '' | CAMPAIGNS_FROM_ADDRESS | Default sender address when a campaign is dispatched without ->from(). Seeds the DefaultFromAddress option. Left blank, SendCampaignEmail sends from your mailer’s global mail.from address and name. |
recipients.only-verified | false | CAMPAIGNS_ONLY_VERIFIED | Skip owners and contacts without a verified contact when resolving recipients. Seeds OnlyVerifiedRecipients. Read strictly: true/1/on/yes or false/0/off/no; anything else throws InvalidConfigurationException. |
recipients.contact-type | CAMPAIGNS_RECIPIENT_CONTACT_TYPE | Contact kind resolved for an owner when ->viaContactType() is unset — a ContactType value: email, phone, address, url, social or custom. Seeds DefaultRecipientContactType. A typo throws InvalidConfigurationException instead of reading as email. | |
sending-queue | default | CAMPAIGNS_SENDING_QUEUE | Queue every per-recipient delivery job runs on — point a worker at it. The campaign’s job batch is opened on it when the campaign is prepared. Seeds the DefaultSendingQueue option. A blank value is not set (default); a non-string value throws. |
process-recipient-job | SendCampaignEmail::class | — | Job dispatched once per recipient. Must implement Contracts\ProcessesCampaignRecipient — any other value throws InvalidConfigurationException when the campaign starts, while it is still Pending. |
notification | null | CAMPAIGNS_NOTIFICATION | A Notifications\CampaignNotification subclass delivered by SendCampaignNotification. Any other class fails the send, recording the InvalidConfigurationException message on the recipient. |
notification-channel | CAMPAIGNS_NOTIFICATION_CHANNEL | Route channel of SendCampaignNotification’s on-demand notifiable. Seeds the DefaultChannel option. A blank value is not set (mail); a non-string value throws. |
Environment
Every key except process-recipient-job reads an env variable, so you rarely need to publish the config at all:
CAMPAIGNS_STORE='RoundlyConsulting\Campaigns\Stores\DatabaseCampaignStore'
CAMPAIGNS_FROM_NAME="Example Shop"
CAMPAIGNS_FROM_ADDRESS=[email protected]
CAMPAIGNS_ONLY_VERIFIED=false
CAMPAIGNS_RECIPIENT_CONTACT_TYPE=email
CAMPAIGNS_SENDING_QUEUE=campaigns
CAMPAIGNS_NOTIFICATION='App\Notifications\ProductLaunchNotification'
CAMPAIGNS_NOTIFICATION_CHANNEL=mailWrap class names in single quotes. Inside double quotes phpdotenv reads each backslash as the start of an escape sequence — \C, \S and \N are not valid ones — and refuses to load the .env file.
Strict values
A key that is not set — absent, null, or blank like a host’s CAMPAIGNS_SENDING_QUEUE= — takes its default. For the sender fields that default is '', which keeps the mailer’s own from; for notification it is none. A value that is set but unusable throws RoundlyConsulting\PackageToolkit\Exceptions\InvalidConfigurationException naming the key, instead of quietly falling back: a store or job class that doesn’t implement its contract, a contact type that isn’t a ContactType value, a non-string queue, channel or sender, a verified-only switch outside true/1/on/yes and false/0/off/no.
Config vs stored options
The send defaults — sender, recipient rules, sending queue and notification channel — are also runtime-editable options. The config value is only the seed: a stored option overrides it, and an explicit builder call overrides both. See Send defaults.
Campaigns without a sender
from-address is blank by default. A campaign with neither ->from() nor a from-address default (or a stored DefaultFromAddress option) still sends: SendCampaignEmail leaves the From header to your mailer, so the email goes out from the global mail.from address and name. Set CAMPAIGNS_FROM_ADDRESS, or call ->from(), only when campaigns should use a different sender.
Show your open-source love
This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.
More ways to support, including cryptoBy donating, you agree to our donation terms.
Want this built into your product?
We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.