Plugin System Overview
Opterius Mail includes a plugin system that lets you extend or modify the application's behaviour without editing core application files. Plugins are PHP classes that hook into specific points in the mail workflow — composing, sending, logging in, reading a message, or rendering settings. When a new version of Opterius Mail is released, your plugins remain intact and do not need to be rewritten.
Architecture
plugins/
└── my-plugin/
└── plugin.php (main class: extends App\Plugins\Plugin)
At boot time, the App\Plugins\PluginManager service provider scans the plugins/ directory, instantiates each plugin's main class, calls its boot() method, and registers its hook handlers. Plugin loading is alphabetical by directory name.
All plugins extend the App\Plugins\Plugin abstract class and implement only the hooks they need.
Available Hooks
| Constant | Trigger point | Arguments passed | Can modify |
|---|---|---|---|
Plugin::HOOK_COMPOSE |
Before the compose view is rendered | $data array (to, cc, subject, body, mode) |
Yes — modify compose fields |
Plugin::HOOK_SEND |
Just before a message is dispatched via SMTP | $message object (all headers + body) |
Yes — modify or cancel send |
Plugin::HOOK_LOGIN |
After a successful IMAP authentication | $user (email, name) |
No — read-only |
Plugin::HOOK_MESSAGE_VIEW |
After a message is fetched from IMAP, before it is passed to the view | $message array |
Yes — modify body/headers |
Plugin::HOOK_SETTINGS |
When the settings page is rendered | $settings, $view |
Yes — add settings sections |
Use Cases
Corporate Signature Injection
Hook into HOOK_COMPOSE to append a standardised HTML signature to every outgoing message, regardless of what the user typed. Signatures can be pulled from a database or LDAP.
S/MIME or PGP Encryption
Hook into HOOK_SEND to encrypt or sign the outgoing message before it leaves the server.
Message Archiving
Hook into HOOK_SEND to send a copy of every outgoing message to an external archiving system (Mattermost, a compliance API, S3, etc.).
Custom Branding
Hook into HOOK_COMPOSE and HOOK_SETTINGS to inject company-specific branding elements, links, and notices.
Login Audit Logging
Hook into HOOK_LOGIN to write a login record to an external system (SIEM, audit database, Slack notification for privileged accounts).
HTML Sanitisation or Transformation
Hook into HOOK_MESSAGE_VIEW to post-process the HTML body before it reaches the user — stripping tracking pixels, rewriting external links to go through a proxy, or highlighting keywords.
Plugin Loading Order
Plugins are loaded alphabetically by their directory name in plugins/. If plugin B depends on plugin A having already run, name A's directory so it sorts before B (e.g., a-core-plugin and b-extension-plugin).
To disable a plugin without deleting it, rename its directory with a leading underscore or a dot:
mv plugins/my-plugin plugins/_my-plugin
The PluginManager skips directories that begin with _ or ..
Plugin Manager API
Within a plugin, you can access the plugin manager and application container:
// Access another plugin by name
$otherPlugin = app('plugins')->get('other-plugin-name');
// Access the Laravel application container
$config = app('config')->get('mail-ui.template');
// Access the authenticated user (IMAP session)
$userEmail = auth('imap')->user()->email;
Community Plugins
When publishing a plugin for others to use, follow the naming convention:
opterius-mail-plugin-{name}
For example: opterius-mail-plugin-signature, opterius-mail-plugin-smime.
Document your plugin's required .env keys and any Artisan commands it introduces.