ekandreas/filament-resonator
Composer 安装命令:
composer require ekandreas/filament-resonator
包简介
A Filament plugin for managing email inbox with Resend and AI-powered features via Prism
README 文档
README
A powerful email inbox plugin for Filament 4 with Resend integration and AI-powered features via Prism.
Features
- 📧 Full Email Inbox - Send, receive, and manage emails directly in Filament
- 🧵 Thread Grouping - Automatic conversation threading via headers
- 📁 Folder Management - Inbox, Sent, Archive, Spam, Trash + custom folders
- 🤖 AI Spam Detection - Automatic spam classification using Prism + LLM
- 👤 Contact Enrichment - Extract contact info from emails via AI
- 📝 Reply Snippets - Pre-defined templates for quick responses
- 🔄 Auto Sync - Scheduled syncing via artisan command
- 🌍 Multilingual - 9 languages included (EN, SV, DE, FR, ES, NB, FI, DA, PT)
Architecture Overview
graph TB
subgraph "Filament Panel"
IR[InboxResource]
FR[FolderResource]
SR[SnippetResource]
SFR[SpamFilterResource]
end
subgraph "Core"
RP[ResonatorPlugin]
RSP[ResonatorServiceProvider]
end
subgraph "Actions"
SE[SyncEmails]
SR2[SendReply]
CO[CleanupOldMessages]
end
subgraph "Jobs"
DS[DetectSpam]
EC[EnrichContact]
end
subgraph "External Services"
RESEND[(Resend API)]
PRISM[Prism]
LLM[(OpenAI / Anthropic / Ollama)]
end
RP --> IR
RP --> FR
RP --> SR
RP --> SFR
IR --> SE
IR --> SR2
SE --> RESEND
SR2 --> RESEND
CO --> RESEND
DS --> PRISM
EC --> PRISM
PRISM --> LLM
Loading
Technology Stack
graph LR
subgraph "Frontend"
F[Filament 4]
B[Blade Views]
L[Livewire]
end
subgraph "Backend"
LA[Laravel 12]
SP[Spatie Package Tools]
end
subgraph "Email"
RE[Resend API]
SA[Saloon HTTP]
end
subgraph "AI Layer"
PR[Prism PHP]
OA[OpenAI]
AN[Anthropic]
OL[Ollama]
end
F --> LA
B --> F
L --> F
LA --> SP
LA --> SA
SA --> RE
LA --> PR
PR --> OA
PR --> AN
PR --> OL
Loading
Data Model
erDiagram
ResonatorFolder ||--o{ ResonatorThread : contains
ResonatorThread ||--o{ ResonatorEmail : contains
ResonatorThread }o--o{ ResonatorContact : has
ResonatorEmail ||--o{ ResonatorAttachment : has
User ||--o{ ResonatorThread : handles
User ||--o{ ResonatorSpamFilter : creates
ResonatorFolder {
bigint id PK
string name
string slug UK
string icon
string color
boolean is_system
integer sort_order
}
ResonatorThread {
bigint id PK
bigint folder_id FK
string subject
string participant_email
string participant_name
boolean is_starred
boolean is_read
datetime last_message_at
bigint handled_by FK
datetime handled_at
}
ResonatorEmail {
bigint id PK
bigint thread_id FK
string resend_id UK
string message_id
string in_reply_to
boolean is_inbound
string from_email
string from_name
json to
string subject
longtext html
longtext text
datetime sent_at
}
ResonatorAttachment {
bigint id PK
bigint email_id FK
string resend_id
string filename
string content_type
bigint size
}
ResonatorContact {
bigint id PK
string email UK
string name
string phone
string company
string unsubscribe_token UK
datetime unsubscribed_at
}
ResonatorSnippet {
bigint id PK
string name
string shortcut UK
string subject
longtext body
integer sort_order
boolean is_active
}
ResonatorSpamFilter {
bigint id PK
string email UK
text reason
bigint created_by FK
}
Loading
Email Sync Flow
sequenceDiagram
participant Scheduler
participant SyncEmails
participant Resend
participant Database
participant DetectSpam
participant Prism
participant LLM
Scheduler->>SyncEmails: resonator:sync
SyncEmails->>Resend: GET /emails/receiving
Resend-->>SyncEmails: List of emails
loop For each email
SyncEmails->>Resend: GET /emails/receiving/{id}
Resend-->>SyncEmails: Email details
SyncEmails->>SyncEmails: Check spam filter
SyncEmails->>SyncEmails: Find/create thread
SyncEmails->>Database: Create ResonatorEmail
SyncEmails->>Database: Create ResonatorAttachment(s)
SyncEmails->>DetectSpam: Dispatch job (5s delay)
end
DetectSpam->>Prism: Structured prompt
Prism->>LLM: Analyze email content
LLM-->>Prism: JSON response
Prism-->>DetectSpam: {is_spam, reason}
alt is_spam = true
DetectSpam->>Database: Move thread to spam folder
end
SyncEmails-->>Scheduler: {synced, skipped, spam, errors}
Loading
Reply Flow
sequenceDiagram
participant User
participant ViewThread
participant SendReply
participant Mail
participant Resend
participant Database
User->>ViewThread: Click Reply
User->>ViewThread: Select snippet (optional)
User->>ViewThread: Write message
User->>ViewThread: Submit
ViewThread->>SendReply: execute(thread, body)
SendReply->>SendReply: Build signature
SendReply->>SendReply: Set In-Reply-To headers
SendReply->>Mail: Send via Laravel Mail
Mail->>Resend: POST /emails
Resend-->>Mail: {id, status}
SendReply->>Database: Create ResonatorEmail (is_inbound=false)
SendReply->>Database: Move thread to Sent folder
SendReply->>Database: Mark as handled
SendReply-->>ViewThread: Success
ViewThread-->>User: Notification + Redirect
Loading
Installation
Step 1: Install via Composer
composer require ekandreas/filament-resonator
Step 2: Publish and run migrations
php artisan vendor:publish --tag="resonator-migrations"
php artisan migrate
Step 3: Publish config (optional)
php artisan vendor:publish --tag="resonator-config"
Step 4: Configure Prism
Resonator uses Prism for AI features. Configure your preferred provider in config/prism.php:
// config/prism.php return [ 'providers' => [ 'openai' => [ 'api_key' => env('OPENAI_API_KEY'), ], // Or use Anthropic, Ollama, etc. ], ];
Step 5: Register the plugin
In your Filament Panel Provider:
use EkAndreas\Resonator\ResonatorPlugin; public function panel(Panel $panel): Panel { return $panel // ... ->plugins([ ResonatorPlugin::make(), ]); }
Configuration
Environment Variables
# Required - Resend RESEND_KEY=re_xxxxxxxxxxxx # Required for AI features - Choose one provider OPENAI_API_KEY=sk-xxxxxxxxxxxx # or ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxx # Optional - Mail settings RESONATOR_FROM_ADDRESS=hello@example.com RESONATOR_FROM_NAME="My App" # Optional - AI settings RESONATOR_AI_ENABLED=true RESONATOR_AI_PROVIDER=openai RESONATOR_AI_MODEL=gpt-4o-mini # Optional - Features RESONATOR_SPAM_DETECTION=true RESONATOR_CONTACT_ENRICHMENT=true RESONATOR_CLEANUP_ENABLED=true RESONATOR_CLEANUP_DAYS=30
Config File
// config/resonator.php return [ 'resend' => [ 'key' => env('RESEND_KEY'), ], 'mail' => [ 'from_address' => env('RESONATOR_FROM_ADDRESS'), 'from_name' => env('RESONATOR_FROM_NAME'), ], 'ai' => [ 'enabled' => env('RESONATOR_AI_ENABLED', true), 'provider' => env('RESONATOR_AI_PROVIDER', 'openai'), 'model' => env('RESONATOR_AI_MODEL', 'gpt-4o-mini'), ], 'spam_detection' => [ 'enabled' => env('RESONATOR_SPAM_DETECTION', true), 'delay_seconds' => 5, ], 'contact_enrichment' => [ 'enabled' => env('RESONATOR_CONTACT_ENRICHMENT', true), 'max_emails_to_analyze' => 3, 'max_text_length' => 3000, ], 'navigation' => [ 'group' => 'Resonator', 'sort' => 100, ], 'pagination' => [ 'default' => 25, 'options' => [25, 50, 100], ], ];
Prism AI Integration
Resonator leverages Prism's structured output feature for reliable AI responses:
graph TD
subgraph "Prism Structured Output"
A[Email Content] --> B[System Prompt]
B --> C[ObjectSchema]
C --> D{Provider}
D --> E[OpenAI]
D --> F[Anthropic]
D --> G[Ollama]
E --> H[JSON Response]
F --> H
G --> H
H --> I[Validated Data]
end
Loading
Spam Detection Schema
$schema = new ObjectSchema( name: 'spam_detection', properties: [ new BooleanSchema('is_spam'), new StringSchema('reason'), ], requiredFields: ['is_spam'] );
Contact Enrichment Schema
$schema = new ObjectSchema( name: 'contact_info', properties: [ new StringSchema('name'), new StringSchema('phone'), new StringSchema('company'), ] );
Supported Prism Providers
| Provider | Model Examples | Config |
|---|---|---|
| OpenAI | gpt-4o-mini, gpt-4o |
OPENAI_API_KEY |
| Anthropic | claude-3-haiku, claude-3-sonnet |
ANTHROPIC_API_KEY |
| Ollama | llama3, mistral |
Local installation |
Plugin Options
ResonatorPlugin::make() ->folders(true) // Enable folder management ->snippets(true) // Enable reply snippets ->spamFilters(true) // Enable spam filter management
Scheduled Syncing
Add to your routes/console.php or scheduler:
use Illuminate\Support\Facades\Schedule; Schedule::command('resonator:sync')->everyFiveMinutes();
Or in app/Console/Kernel.php:
protected function schedule(Schedule $schedule): void { $schedule->command('resonator:sync')->everyFiveMinutes(); }
Command Reference
# Sync emails and cleanup old messages php artisan resonator:sync # Sync without cleanup php artisan resonator:sync --no-cleanup # Custom cleanup period php artisan resonator:sync --cleanup-days=60
Navigation Structure
graph LR
subgraph "Resonator Menu Group"
A[📥 Inbox] --> A1[View Threads]
A --> A2[Compose]
A --> A3[Sync]
B[📁 Folders] --> B1[Manage Folders]
C[📝 Snippets] --> C1[Manage Templates]
D[🛡️ Spam Filters] --> D1[Manage Blocked]
end
Loading
System Folders
The following folders are created automatically:
| Folder | Slug | Icon | Purpose |
|---|---|---|---|
| Inbox | inbox |
📥 | Incoming messages |
| Sent | sent |
📤 | Outgoing messages |
| Archive | archive |
📦 | Archived threads |
| Spam | spam |
🛡️ | Spam messages |
| Trash | trash |
🗑️ | Deleted messages |
AI Features
Spam Detection Flow
flowchart TD
A[New Email Received] --> B{Is Inbound?}
B -->|No| END[Skip]
B -->|Yes| C[Queue DetectSpam Job]
C --> D[Wait 5 seconds]
D --> E[Build Prompt]
E --> F[Prism Structured Call]
F --> G[LLM Analysis]
G --> H{AI Response}
H -->|is_spam: true| I[Move to Spam Folder]
H -->|is_spam: false| J[Keep in Inbox]
I --> K[Log Result]
J --> K
Loading
Contact Enrichment
flowchart TD
A[Thread Created] --> B[Queue EnrichContact Job]
B --> C{Contact Complete?}
C -->|Yes| END[Skip]
C -->|No| D[Collect Last 3 Emails]
D --> E[Limit Text to 3000 chars]
E --> F[Prism Structured Call]
F --> G[LLM Extraction]
G --> H[Extract: name, phone, company]
H --> I{Found New Data?}
I -->|Yes| J[Update Contact]
I -->|No| END2[Skip]
Loading
Thread Matching Logic
flowchart TD
A[New Email] --> B{Has In-Reply-To?}
B -->|Yes| C[Find by Message-ID]
C --> D{Found?}
D -->|Yes| E[Add to Existing Thread]
D -->|No| F{Match Subject + Sender?}
B -->|No| F
F -->|Yes| G[Within 30 days?]
G -->|Yes| E
G -->|No| H[Create New Thread]
F -->|No| H
Loading
Translations
Resonator includes translations for the following languages:
| Language | Code | File |
|---|---|---|
| English | en |
resources/lang/en/resonator.php |
| Swedish | sv |
resources/lang/sv/resonator.php |
| German | de |
resources/lang/de/resonator.php |
| French | fr |
resources/lang/fr/resonator.php |
| Spanish | es |
resources/lang/es/resonator.php |
| Norwegian | nb |
resources/lang/nb/resonator.php |
| Finnish | fi |
resources/lang/fi/resonator.php |
| Danish | da |
resources/lang/da/resonator.php |
| Portuguese | pt |
resources/lang/pt/resonator.php |
To add more languages:
php artisan vendor:publish --tag="resonator-translations"
Then create your translation file in lang/vendor/resonator/{locale}/resonator.php.
Extending
Custom Folder Types
use EkAndreas\Resonator\Models\ResonatorFolder; ResonatorFolder::create([ 'name' => 'VIP', 'slug' => 'vip', 'icon' => 'heroicon-o-star', 'color' => 'warning', 'is_system' => false, ]);
Custom Snippets
use EkAndreas\Resonator\Models\ResonatorSnippet; ResonatorSnippet::create([ 'name' => 'Welcome Message', 'shortcut' => 'welcome', 'subject' => 'Welcome to Our Service', 'body' => '<p>Thank you for reaching out...</p>', 'is_active' => true, ]);
Listening to Events
// In a service provider use EkAndreas\Resonator\Models\ResonatorEmail; ResonatorEmail::created(function ($email) { if ($email->is_inbound) { // Notify team, trigger webhooks, etc. } });
File Structure
src/
├── Actions/
│ ├── CleanupOldMessages.php
│ ├── SendReply.php
│ └── SyncEmails.php
├── Commands/
│ └── SyncInboxCommand.php
├── Filament/
│ └── Resources/
│ ├── FolderResource.php
│ ├── InboxResource.php
│ ├── SnippetResource.php
│ └── SpamFilterResource.php
├── Http/
│ └── Integrations/
│ └── Resend/
│ ├── ResendConnector.php
│ └── Requests/
├── Jobs/
│ ├── DetectSpam.php
│ └── EnrichContact.php
├── Models/
│ ├── ResonatorAttachment.php
│ ├── ResonatorContact.php
│ ├── ResonatorEmail.php
│ ├── ResonatorFolder.php
│ ├── ResonatorSnippet.php
│ ├── ResonatorSpamFilter.php
│ └── ResonatorThread.php
├── ResonatorPlugin.php
└── ResonatorServiceProvider.php
Testing
composer test
Requirements
- PHP 8.4+
- Laravel 12.x
- Filament 4.x
- Resend account with API key
- LLM API key (OpenAI, Anthropic, or local Ollama)
Dependencies
| Package | Version | Description |
|---|---|---|
php |
^8.4 | PHP 8.4 or higher |
filament/filament |
^4.0 | Filament admin panel (includes Livewire 3) |
illuminate/contracts |
^12.0 | Laravel 12 contracts |
prism-php/prism |
^1.0 | AI integration layer |
saloonphp/saloon |
^3.0 | HTTP client for Resend API |
spatie/laravel-package-tools |
^1.16 | Package development utilities |
graph TD
A[filament-resonator] --> B[filament/filament ^4.0]
A --> C[spatie/laravel-package-tools ^1.16]
A --> D[saloonphp/saloon ^3.0]
A --> E[prism-php/prism ^1.0]
B --> F[Livewire 3]
B --> G[Laravel 12]
E --> H[OpenAI]
E --> I[Anthropic]
E --> J[Ollama]
Loading
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security
If you discover any security related issues, please email security@elseif.se instead of using the issue tracker.
Credits
License
The MIT License (MIT). Please see License File for more information.
ekandreas/filament-resonator 适用场景与选型建议
ekandreas/filament-resonator 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 0 次下载、GitHub Stars 达 0, 最近一次更新时间为 2026 年 01 月 03 日, 在 PHP 生态内属于活跃度较高的组件。
它主要适用于以下技术方向: 「email」 「laravel」 「inbox」 「prism」 「ai」 「filament」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。
我们在过去多个企业项目中使用过 ekandreas/filament-resonator 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。
基于 ekandreas/filament-resonator 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。
线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。
承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。
与 ekandreas/filament-resonator 相关的其它包
同方向 / 同关键字的高下载量 PHP Composer 包推荐,方便对比选型:
Talk is a Laravel based realtime messaging, chatting and conversation system. It helps to develop users messaging, chatting and conversations in easy way.
yii2 extension to read and process mails from IMAP and PHP
Laravel package for managing inbox notifications with FCM support
Inbox pattern process implementation for your Laravel Applications
Email-like inbox messaging plugin for Filament v5 — threads, starring, trash, forwarding, read receipts, and multi-tenancy out of the box.
Extensible library for building notifications and sending them via different delivery channels.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 19
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-01-03