Everyone

Plugin System Overview

An introduction to the Opterius Mail plugin architecture, available hooks, and how plugins extend the core application.

Last updated 2026-04-12
  • Plugin Loading Order
  • Plugin Manager API
  • Community Plugins
  • 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.