webteractive/mailulator 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

webteractive/mailulator

Composer 安装命令:

composer require --dev webteractive/mailulator

包简介

Self-hosted Laravel-native email testing service. Captures outbound email for inspection — installable into any Laravel app.

README 文档

README

Self-hosted, Laravel-native email testing. One package ships both sides:

  • Receiver — stores ingested email in an isolated database (default SQLite; any Laravel-supported driver works), serves a Vue 3 inbox UI at /mailulator.
  • Driver — a Symfony Mailer transport registered as mailulator. Set MAIL_MAILER=mailulator and outbound mail flows to the receiver — over HTTP for standalone deployments, in-process for in-app ones.

Requirements

  • PHP ^8.3
  • Laravel ^11 || ^12 || ^13

Install

composer require webteractive/mailulator
php artisan mailulator:install

mailulator:install publishes:

  • app/Providers/MailulatorServiceProvider.php — customize the auth gate here.
  • config/mailulator.php — receiver + driver config.

It then runs migrations against the isolated mailulator connection and creates a protected Default inbox (it cannot be renamed or deleted; at least one inbox must always exist).

The install prints the Default inbox's bearer token. In-app deployments don't need it for delivery, but save it anyway — any sender app you later point at this receiver will need it, and it isn't shown again.

Publish compiled UI assets:

php artisan vendor:publish --tag=mailulator-assets

Re-run this tag after each composer update.

Deployment modes

Two shapes, distinguished by where the inbox UI lives.

1. In-app — UI lives with the app it captures

The app sending the mail is also the app you read it from. Install Mailulator there, set MAIL_MAILER=mailulator, and the captured mail shows up at /mailulator on the same host. One app, one inbox, no plumbing.

# .env
MAIL_MAILER=mailulator

No URL, no token. The transport detects in-app mode (driver enabled + receiver enabled + no MAILULATOR_URL) and writes directly to the Default inbox via StoreIncomingEmail, bypassing HTTP entirely. Open /mailulator on the same app to read the captured mail.

Best for: local development, staging, demo environments — any app that just wants to "swallow" its own outbound mail and read it back in place.

2. Standalone — UI lives in a dedicated app, shared by many senders

A single Laravel app exists just to host inboxes and the UI. Any number of other apps point at it via MAILULATOR_URL and route to the right inbox via MAILULATOR_TOKEN. One UI, many senders.

On the standalone receiver — install the package as receiver-only:

# .env
MAILULATOR_RECEIVER_ENABLED=true
MAILULATOR_DRIVER_ENABLED=false

Create one inbox per sender app from the UI (or reuse the seeded Default). Each inbox has its own bearer token; that token is the only thing that ties a sender to its inbox.

On each sender app — install the package as driver-only and point it at the receiver with the inbox's token:

# .env
MAIL_MAILER=mailulator
MAILULATOR_URL=https://mailulator.your-domain.test
MAILULATOR_TOKEN=<token for this app's inbox>
MAILULATOR_RECEIVER_ENABLED=false
MAILULATOR_DRIVER_ENABLED=true

To onboard another sender app, repeat the sender-side .env with a different inbox token. The receiver doesn't care how many apps point at it. Open /mailulator on the receiver to read mail across all inboxes.

Gate

The SPA is gated. Edit app/Providers/MailulatorServiceProvider.php:

protected function gate(): void
{
    Gate::define('viewMailulator', fn ($user) =>
        in_array(optional($user)->email, [
            'you@example.com',
        ])
    );
}

Default: local environment only. Non-local without a customized gate → 403.

Optional hooks in the same provider:

public function boot(): void
{
    parent::boot();

    Mailulator::canViewInbox(fn ($user, $inboxId) =>
        $user->inboxes()->where('inboxes.id', $inboxId)->exists()
    );

    Mailulator::manage(fn ($user) => $user->is_admin ?? false);
}

Sender-side (.env)

Variable Default Purpose
MAIL_MAILER Set to mailulator to route outbound email through this driver.
MAILULATOR_URL Base URL of the receiver.
MAILULATOR_TOKEN Per-inbox bearer token printed by mailulator:install or the admin UI.
MAILULATOR_TIMEOUT 5 HTTP timeout (seconds) for ingest calls.
MAILULATOR_ON_FAILURE log log (warn + return), silent (return), or throw (raise TransportException).
MAILULATOR_DRIVER_ENABLED true Set false to install as receiver-only.

A receiver outage will not break the sender app's request unless MAILULATOR_ON_FAILURE=throw.

Receiver-side (.env)

Variable Default Purpose
MAILULATOR_RECEIVER_ENABLED true Turn receiver off to install as driver-only.
MAILULATOR_DB_CONNECTION mailulator Connection name to use. Set to any connection defined in your host app's config/database.php (e.g. mysql) to share that DB; leave as mailulator for an isolated, package-managed connection.
MAILULATOR_DB_DRIVER sqlite Driver for the auto-managed connection — only used when MAILULATOR_DB_CONNECTION=mailulator and the host hasn't pre-defined it.
MAILULATOR_SQLITE_PATH database_path('mailulator.sqlite') SQLite file, auto-touched.
MAILULATOR_DB_HOST / _PORT / _DATABASE / _USERNAME / _PASSWORD / _CHARSET Credentials for the auto-managed connection (non-SQLite drivers).
MAILULATOR_ATTACHMENTS_DISK local Filesystem disk for attachment bytes.
MAILULATOR_RATE_LIMIT 600 Ingest requests/min per inbox.
MAILULATOR_RETENTION_DAYS 30 Default retention for newly created inboxes. Per-inbox override available; null keeps forever.
MAILULATOR_UI_PATH mailulator SPA path prefix.
MAILULATOR_UI_DOMAIN Optional subdomain (e.g. mail.your-staging.com).
MAILULATOR_REALTIME_ENABLED true Master switch for realtime updates.
MAILULATOR_REALTIME polling polling or broadcast.
MAILULATOR_POLL_INTERVAL 3 Polling interval (seconds).
MAILULATOR_BROADCASTER reverb reverb or pusher when MAILULATOR_REALTIME=broadcast.

Ingest API

POST /api/emails — bearer-token authenticated, rate-limited per inbox.

Accepts JSON (base64 attachments) or multipart/form-data (UploadedFile attachments). Returns 201 { "id": <email_id> }.

Realtime

Three states, controlled by two env vars:

MAILULATOR_REALTIME_ENABLED MAILULATOR_REALTIME Behavior
true (default) polling (default) UI polls every MAILULATOR_POLL_INTERVAL seconds. Zero extra deps.
true broadcast Echo subscribes to mailulator.inbox.{id} private channels.
false Static UI. No polling, no broadcast.

To enable broadcasting, install Reverb / Pusher in the host app, then:

MAILULATOR_REALTIME=broadcast
MAILULATOR_BROADCASTER=reverb
MAILULATOR_ECHO_KEY=...
MAILULATOR_ECHO_CLUSTER=...      # Pusher only
MAILULATOR_ECHO_HOST=...          # Reverb only
MAILULATOR_ECHO_PORT=...
MAILULATOR_ECHO_SCHEME=https

EmailReceived dispatches to mailulator.inbox.{id} on every ingest. Channel authorization routes through Mailulator::canViewInbox. If MAILULATOR_REALTIME=broadcast is set without a configured MAILULATOR_ECHO_KEY, the client logs a warning and falls back to polling.

Inboxes

  • Each inbox has a name, optional retention period, optional color (UI accent), and a hashed bearer token.
  • The seeded Default inbox is protected — it cannot be renamed or deleted.
  • The last remaining inbox cannot be deleted regardless of name.
  • Regenerating a key invalidates the previous token immediately at the ingest boundary.

Retention

Set retention_days per inbox; the daily PruneEmails job deletes older emails and cleans their attachment files. null = keep forever.

The job is auto-scheduled. Ensure your host app runs schedule:run via cron or schedule:work.

Upgrade

composer update webteractive/mailulator
php artisan vendor:publish --tag=mailulator-assets --force
php artisan migrate --database=mailulator

License

MIT.

webteractive/mailulator 适用场景与选型建议

webteractive/mailulator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 04 月 25 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「mail」 「testing」 「email」 「laravel」 「staging」 「mailtrap」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 webteractive/mailulator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 webteractive/mailulator 我们能提供哪些服务?
定制开发 / 二次开发

基于 webteractive/mailulator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 0
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 38
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-25