PHP code example of ttbooking / mailspoon

1. Go to this page and download the library: Download ttbooking/mailspoon library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ttbooking / mailspoon example snippets


'local' => [
    'driver' => 'local',
    'root' => storage_path('app/private'),
    'serve' => true,
    'throw' => true,
],

'routes' => [
    'support' => [
        'endpoint' => 'https://support.example.com/api/mailgun/mime',
        'key' => 'key-support',

        // Необязательно: маркер просмотра и фильтры конкретно для этого
        // ящика — переопределяют глобальные `mark` и `filters` (см. ниже).
        'mark' => 'keyword:Mailspoon',
        'filters' => ['allow' => ['subject' => ['/invoice/i']]],
    ],
    'billing' => [
        'endpoint' => 'https://billing.example.com/api/mailgun/mime',
        'key' => 'key-billing',
    ],
    'archive-mailbox' => [
        // Приостановить ящик, не удаляя его настройки.
        'enabled' => false,
    ],
],

'routes' => [
    'legacy-support' => [
        'enabled' => false,
    ],
],

'filters' => [
    'allow' => [
        'subject' => ['/⚡/u'],              // регэксп (с разделителями)
        'from' => ['*@trusted.com'],        // или wildcard без учёта регистра
    ],
    'deny' => [
        'from' => ['no-reply@*', 'mailer-daemon@*'],
        'header' => ['Auto-Submitted' => 'auto-*'],
        'has_attachment' => false,
    ],
],

'filters' => [
    'allow' => [
        'header' => ['Content-Type' => '/report-type=disposition-notification/i'],
    ],
],

'routes' => [
    'operators' => [
        'endpoint' => 'https://crm.example.com/api/mailgun/mime',
        'key' => 'key-operators',
        'mark' => 'keyword:Mailspoon',
        'filters' => ['allow' => ['subject' => ['/⚡/u']]],
    ],
],

'schedule' => [
    // ...
    'pull' => [
        'default' => '*/5 * * * *',
        'secondary' => '0 * * * *',
    ],
],

use TTBooking\Mailspoon\Facades\Mailspoon;

Mailspoon::register('tenant-42', [
    'endpoint' => 'https://tenant-42.example.com/api/mailgun/mime',
    'key' => 'key-42',
    'schedule' => '*/5 * * * *',   // cron-poll этого ящика (как запись schedule.pull)
    'enabled' => true,             // та же семантика, что у маршрута в конфиге
    'mark' => 'keyword:Mailspoon',
    'filters' => ['allow' => ['subject' => ['/invoice/i']]],
]);

use DirectoryTree\ImapEngine\Laravel\Facades\Imap;
use TTBooking\Mailspoon\Facades\Mailspoon;

public function boot(): void
{
    // Выполняется в каждом процессе, включая фоновый mailspoon:pull из
    // планировщика, — поэтому подключение доступно и там.
    foreach (Mailbox::all() as $box) {            // ваша Eloquent-модель
        Imap::register($box->mailbox, $box->imap_config);    // подключение
        Mailspoon::register($box->mailbox, [                 // доставка + опрос
            'endpoint' => $box->endpoint,
            'key' => $box->key,
            'schedule' => $box->poll_cron,
            'enabled' => $box->enabled,
        ]);
    }
}

use DirectoryTree\ImapEngine\FileMessage;
use TTBooking\Mailspoon\Services\Doctor;
use TTBooking\Mailspoon\Services\Replay;
use TTBooking\Mailspoon\Services\ReplayCriteria;
use TTBooking\Mailspoon\Services\Deliverer;
use TTBooking\Mailspoon\Services\FilterTester;

// Диагностика — DoctorReport со списком проверок (mailbox/name/status/message).
$report = app(Doctor::class)->run(['support']);   // пусто = все ящики; ->run([], send: true) — с подписанным письмом
return response()->json($report);                  // { "ok": false, "checks": [ ... ] }

// Переотправка — ReplayResult { count, messages: [...] }.
$result = app(Replay::class)->run(new ReplayCriteria(failed: true, mailbox: 'support'));
// Пустой критерий (ни id, ни failed) бросает InvalidArgumentException — мапьте в 422.

// Принудительный флаш — DeliverySummary { delivered, failed, total }.
$summary = app(Deliverer::class)->run(limit: 50);

// Сухой прогон фильтров — FilterTestResult { passes, decision, field, pattern, reason }.
// Принимает любой MessageInterface; для загруженного .eml — FileMessage, без IMAP.
$verdict = app(FilterTester::class)->test('support', new FileMessage($request->getContent()));
return response()->json($verdict);                 // { "passes": false, "decision": "denied_by_rule", ... }
// Работает и для выключенного ящика; малформленное правило бросает InvalidArgumentException.

use Illuminate\Support\Facades\Event;
use TTBooking\Mailspoon\Events\DeliveryPermanentlyFailed;

Event::listen(function (DeliveryPermanentlyFailed $event) {
    Notification::route('slack', config('services.slack.ops'))
        ->notify(new RelayStuckNotification($event->message));
});

use BeyondCode\Mailbox\Facades\Mailbox;
use BeyondCode\Mailbox\InboundEmail;

Mailbox::from('[email protected]', function (InboundEmail $email) {
    $subject = $email->subject();
    // ...
});
bash
composer �г Mailspoon → config/mailspoon.php
php artisan vendor:publish --tag=mailspoon-config

# конфиг IMAP-подключений → config/imap.php
php artisan vendor:publish --provider="DirectoryTree\ImapEngine\Laravel\ImapServiceProvider"

php artisan migrate
bash
php artisan mailspoon:pull default
php artisan mailspoon:pull default "INBOX/Archive"
bash
php artisan mailspoon:sentry default
bash
php artisan mailspoon:deliver
php artisan mailspoon:deliver --limit=100 --max-attempts=5
php artisan mailspoon:deliver --dry-run
bash
php artisan mailspoon:replay "<[email protected]>"   # конкретные письма
php artisan mailspoon:replay --failed                     # все проваленные
php artisan mailspoon:replay --failed --mailbox=support   # только один ящик
bash
php artisan mailspoon:doctor                  # все ящики из config/imap.php
php artisan mailspoon:doctor support          # только указанные
php artisan mailspoon:doctor --send           # + подписанное тестовое письмо