Recipients from contacts
Campaigns resolves recipients straight from contacts-for-laravel, so you can address a campaign from the contact records you already keep instead of copying email strings around. Give your model the HasContacts trait:
use Illuminate\Foundation\Auth\User as Authenticatable;
use RoundlyConsulting\Contacts\Concerns\HasContacts;
final class User extends Authenticatable
{
use HasContacts;
}
$user->addEmail('[email protected]', primary: true);
$user->addPhone('+12025550100', primary: true);Then pass owners, contacts or iterables of them to ->to():
use App\Models\User;
use RoundlyConsulting\Campaigns\Facades\Campaigns;
use RoundlyConsulting\Contacts\Enums\ContactType;
Campaigns::create('Spring sale', '<p>The spring sale starts today.</p>')
->onlyVerified() // skip owners/contacts without a verified contact
->viaContactType(ContactType::Email) // which contact kind to resolve (email, phone, …)
->to($user) // HasContacts owner -> its primary email
->to($contact) // a Contact record -> its value
->to(User::query()->where('newsletter', true)->get()) // an iterable of owners
->dispatch();How recipients are resolved
- An owner resolves to its contact of the send kind — the primary one first, otherwise the first in order.
- A Contact record resolves to its own value; contacts with an empty value are skipped.
- The display name is the owner’s name attribute, then the contact’s name, then its label, then the address itself.
- Owners with no matching contact — or, under onlyVerified(), no verified one — are skipped silently, never fatal.
- An owner passed twice — say $user and again inside a collection — still gets one message: its address is already on the campaign.
- Resolution is read-only: Campaigns never writes to your contacts.
Set the rules before to()
Recipients are resolved the moment you call ->to(), so onlyVerified() and viaContactType() only affect the to() calls that come after them. Without them, the OnlyVerifiedRecipients and DefaultRecipientContactType options apply (config: recipients.only-verified and recipients.contact-type). onlyVerified(false) turns verification off for one campaign even when the default is on.
Phone numbers and SMS
viaContactType(ContactType::Phone) — or the plain string phone — resolves phone contacts instead of emails. Pair it with SendCampaignNotification or your own job to deliver over SMS:
Campaigns::create('Delivery update', 'Your parcel is on its way.')
->viaContactType('phone') // a ContactType value works as a plain string too
->to($customers) // each owner resolves to its primary phone number
->dispatch();A string that isn’t a ContactType value (email, phone, address, url, social, custom) throws a ValueError. Plain strings and CampaignRecipient objects keep working unchanged alongside contacts.
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.