PHPackages                             ekandreas/filament-resonator - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Mail &amp; Notifications](/categories/mail)
4. /
5. ekandreas/filament-resonator

ActiveLibrary[Mail &amp; Notifications](/categories/mail)

ekandreas/filament-resonator
============================

A Filament plugin for managing email inbox with Resend and AI-powered features via Prism

v0.1.0-beta(4mo ago)00[5 issues](https://github.com/ekandreas/filament-resonator/issues)MITPHPPHP ^8.4CI failing

Since Jan 3Pushed 4mo agoCompare

[ Source](https://github.com/ekandreas/filament-resonator)[ Packagist](https://packagist.org/packages/ekandreas/filament-resonator)[ Docs](https://github.com/ekandreas/filament-resonator)[ RSS](/packages/ekandreas-filament-resonator/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (13)Versions (2)Used By (0)

Filament Resonator
==================

[](#filament-resonator)

A powerful email inbox plugin for [Filament 4](https://filamentphp.com) with [Resend](https://resend.com) integration and AI-powered features via [Prism](https://prism.echolabs.dev/).

[![Filament](https://camo.githubusercontent.com/a57d676474640cd4ec21b394cb3221fd57c5a52defd6406505de3de24edfd29a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f46696c616d656e742d342e782d6f72616e6765)](https://camo.githubusercontent.com/a57d676474640cd4ec21b394cb3221fd57c5a52defd6406505de3de24edfd29a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f46696c616d656e742d342e782d6f72616e6765)[![Laravel](https://camo.githubusercontent.com/5b99ec644e12357132ddb95970822afd67efedef92fcccb6270926adebd8b101/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31322e782d726564)](https://camo.githubusercontent.com/5b99ec644e12357132ddb95970822afd67efedef92fcccb6270926adebd8b101/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c61726176656c2d31322e782d726564)[![PHP](https://camo.githubusercontent.com/7d8bce3c50835bb31a0a0375c5e6dc9ac4dd377735e76ab70f5cb851ce835235/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342b2d626c7565)](https://camo.githubusercontent.com/7d8bce3c50835bb31a0a0375c5e6dc9ac4dd377735e76ab70f5cb851ce835235/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e342b2d626c7565)[![License](https://camo.githubusercontent.com/5caa455d8debc46fb23abbadb45a733a937f3910a73fc875c2f7820468e1bb54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e)](https://camo.githubusercontent.com/5caa455d8debc46fb23abbadb45a733a937f3910a73fc875c2f7820468e1bb54/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d677265656e)

Features
--------

[](#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
---------------------

[](#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
----------------

[](#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
----------

[](#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
---------------

[](#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
----------

[](#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
------------

[](#installation)

### Step 1: Install via Composer

[](#step-1-install-via-composer)

```
composer require ekandreas/filament-resonator
```

### Step 2: Publish and run migrations

[](#step-2-publish-and-run-migrations)

```
php artisan vendor:publish --tag="resonator-migrations"
php artisan migrate
```

### Step 3: Publish config (optional)

[](#step-3-publish-config-optional)

```
php artisan vendor:publish --tag="resonator-config"
```

### Step 4: Configure Prism

[](#step-4-configure-prism)

Resonator uses [Prism](https://prism.echolabs.dev/) 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

[](#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
-------------

[](#configuration)

### Environment Variables

[](#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-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
--------------------

[](#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

[](#spam-detection-schema)

```
$schema = new ObjectSchema(
    name: 'spam_detection',
    properties: [
        new BooleanSchema('is_spam'),
        new StringSchema('reason'),
    ],
    requiredFields: ['is_spam']
);
```

### Contact Enrichment Schema

[](#contact-enrichment-schema)

```
$schema = new ObjectSchema(
    name: 'contact_info',
    properties: [
        new StringSchema('name'),
        new StringSchema('phone'),
        new StringSchema('company'),
    ]
);
```

### Supported Prism Providers

[](#supported-prism-providers)

ProviderModel ExamplesConfigOpenAI`gpt-4o-mini`, `gpt-4o``OPENAI_API_KEY`Anthropic`claude-3-haiku`, `claude-3-sonnet``ANTHROPIC_API_KEY`Ollama`llama3`, `mistral`Local installationPlugin Options
--------------

[](#plugin-options)

```
ResonatorPlugin::make()
    ->folders(true)      // Enable folder management
    ->snippets(true)     // Enable reply snippets
    ->spamFilters(true)  // Enable spam filter management
```

Scheduled Syncing
-----------------

[](#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
-----------------

[](#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
--------------------

[](#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
--------------

[](#system-folders)

The following folders are created automatically:

FolderSlugIconPurposeInbox`inbox`📥Incoming messagesSent`sent`📤Outgoing messagesArchive`archive`📦Archived threadsSpam`spam`🛡️Spam messagesTrash`trash`🗑️Deleted messagesAI Features
-----------

[](#ai-features)

### Spam Detection Flow

[](#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

[](#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
---------------------

[](#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
------------

[](#translations)

Resonator includes translations for the following languages:

LanguageCodeFileEnglish`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
---------

[](#extending)

### Custom Folder Types

[](#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

[](#custom-snippets)

```
use EkAndreas\Resonator\Models\ResonatorSnippet;

ResonatorSnippet::create([
    'name' => 'Welcome Message',
    'shortcut' => 'welcome',
    'subject' => 'Welcome to Our Service',
    'body' => 'Thank you for reaching out...',
    'is_active' => true,
]);
```

### Listening to Events

[](#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
--------------

[](#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
-------

[](#testing)

```
composer test
```

Requirements
------------

[](#requirements)

- PHP 8.4+
- Laravel 12.x
- Filament 4.x
- Resend account with API key
- LLM API key (OpenAI, Anthropic, or local Ollama)

Dependencies
------------

[](#dependencies)

PackageVersionDescription`php`^8.4PHP 8.4 or higher`filament/filament`^4.0Filament admin panel (includes Livewire 3)`illuminate/contracts`^12.0Laravel 12 contracts`prism-php/prism`^1.0AI integration layer`saloonphp/saloon`^3.0HTTP client for Resend API`spatie/laravel-package-tools`^1.16Package 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
---------

[](#changelog)

Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](CONTRIBUTING.md) for details.

Security
--------

[](#security)

If you discover any security related issues, please email  instead of using the issue tracker.

Credits
-------

[](#credits)

- [Andreas Ek](https://github.com/ekandreas)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance77

Regular maintenance activity

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity37

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Unknown

Total

1

Last Release

127d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6ad1e6a1276000f63c5c50d2365a627f1bacedf751589dcde2787e2d5f70884e?d=identicon)[EkAndreas](/maintainers/EkAndreas)

---

Top Contributors

[![ekandreas](https://avatars.githubusercontent.com/u/1794603?v=4)](https://github.com/ekandreas "ekandreas (4 commits)")

---

Tags

laravelaiemailresendprismfilamentinbox

###  Code Quality

TestsPest

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/ekandreas-filament-resonator/health.svg)

```
[![Health](https://phpackages.com/badges/ekandreas-filament-resonator/health.svg)](https://phpackages.com/packages/ekandreas-filament-resonator)
```

###  Alternatives

[bezhansalleh/filament-shield

Filament support for `spatie/laravel-permission`.

2.8k2.9M88](/packages/bezhansalleh-filament-shield)[vormkracht10/laravel-mails

Laravel Mails can collect everything you might want to track about the mails that has been sent by your Laravel app.

24149.7k](/packages/vormkracht10-laravel-mails)[croustibat/filament-jobs-monitor

Background Jobs monitoring like Horizon for all drivers for FilamentPHP

254255.2k6](/packages/croustibat-filament-jobs-monitor)[ramnzys/filament-email-log

This package provides a Filament resource to view all Laravel outgoing emails.

5211.3k](/packages/ramnzys-filament-email-log)[guava/filament-modal-relation-managers

Allows you to embed relation managers inside filament modals.

7565.0k4](/packages/guava-filament-modal-relation-managers)[tapp/filament-google-autocomplete-field

Filament plugin that provides a Google Autocomplete field

3098.1k](/packages/tapp-filament-google-autocomplete-field)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
