An open API service indexing awesome lists of open source software.

https://github.com/whilesmartphp/eloquent-outreach

Host-agnostic user outreach for Laravel: compose messages with a call to action, target audiences, and track per-recipient deliveries across pluggable channels.
https://github.com/whilesmartphp/eloquent-outreach

Last synced: 24 days ago
JSON representation

Host-agnostic user outreach for Laravel: compose messages with a call to action, target audiences, and track per-recipient deliveries across pluggable channels.

Awesome Lists containing this project

README

          

# Whilesmart Eloquent Outreach

Host-agnostic user outreach for Laravel. Compose a message with a call to action, target an audience, and track a per-recipient delivery, all over channels your app implements. The package owns the workflow; your app owns how recipients are found, addressed, personalized, and sent.

## Installation

```bash
composer require whilesmart/eloquent-outreach
php artisan vendor:publish --tag=outreach-migrations
php artisan migrate
```

## Concepts

- **Outreach** — one composed message: subject, body, CTA (`cta_label` + `cta_url`), `channel`, `audience` criteria, status, optional `scheduled_at`, and rolled-up `stats`. Optional polymorphic `owner` (sender) and `campaign` (a campaign "has many" outreaches).
- **Delivery** — one row per recipient, with status and timestamps. This is what later per-recipient actions (resend, view, mark) hang off.

## What the host implements

```php
use Whilesmart\Outreach\Contracts\AudienceResolver; // criteria -> recipient models
use Whilesmart\Outreach\Contracts\MessageRenderer; // outreach + recipient -> RenderedMessage
use Whilesmart\Outreach\Contracts\OutreachChannel; // deliver a RenderedMessage
```

Bind your implementations in a service provider:

```php
$this->app->bind(AudienceResolver::class, MyAudienceResolver::class);
$this->app->bind(OutreachChannel::class, MyEmailChannel::class);
// MessageRenderer defaults to attribute token replacement ({{first_name}});
// bind your own for richer templating.
```

Safe defaults ship out of the box: the audience resolves to nobody and the channel sends nowhere until you bind real ones.

## Sending

```php
use Whilesmart\Outreach\Models\Outreach;
use Whilesmart\Outreach\Services\OutreachDispatcher;

$outreach = Outreach::create([
'channel' => 'email',
'subject' => 'Hi {{first_name}}',
'body' => 'We added something you will like.',
'cta_label' => 'Open Trakli',
'cta_url' => 'https://trakli.app/dashboard',
'audience' => ['type' => 'inactive', 'days' => 30],
]);

app(OutreachDispatcher::class)->dispatch($outreach);
```

The dispatcher resolves the audience, creates a `Delivery` per recipient, renders and sends each through the bound channel, rolls the results onto the outreach, and emits `OutreachDispatched`, `DeliverySucceeded`, and `DeliveryFailed` for the host to bridge.

## Campaigns

An outreach can belong to a campaign via the optional `campaign` morph, so a campaign (in your app or another package) can own many outreaches without this package depending on it.

## License

MIT. WhileSmart LTD.