191 lines
9.3 KiB
Markdown
191 lines
9.3 KiB
Markdown
# Mail Gateway for FOSSBilling
|
|
|
|
Mail Gateway imports email into FOSSBilling support tickets using the existing
|
|
FOSSBilling cron. Configure multiple IMAP mailboxes and route each one to a
|
|
separate helpdesk.
|
|
|
|
## Features
|
|
|
|
- Create customer tickets from recognised email addresses and guest tickets from unknown senders.
|
|
- Add replies to existing tickets using the ticket number in the subject.
|
|
- Check that the sender owns the ticket before accepting a reply.
|
|
- Filter recognised automatic messages and prevent duplicate imports.
|
|
- Move handled emails into Processed, Ignored or Failed folders.
|
|
- Manage mailbox connections and test them from the admin settings page.
|
|
|
|
## Requirements
|
|
|
|
- FOSSBilling with the Support module enabled and its cron running regularly.
|
|
- An IMAP server supporting native `MOVE` and a valid TLS certificate when using TLS.
|
|
- A receiving mail server with appropriate email authentication and anti-spoofing policies.
|
|
- The `webklex/php-imap` Composer package and its required PHP extensions.
|
|
|
|
The native PHP IMAP extension is not required. Composer checks dependency
|
|
requirements when installing. For installation through the settings page, the
|
|
web server also needs access to PHP CLI, Composer, `proc_open`, a writable module
|
|
directory and package downloads. If web installation is unavailable or the module
|
|
directory is deliberately not writable by the web server, installation over SSH
|
|
is the preferred fallback. Run this from the module directory as its owning user:
|
|
|
|
```bash
|
|
composer install --no-dev --prefer-dist --no-interaction --no-scripts --no-plugins --optimize-autoloader
|
|
```
|
|
|
|
This uses the supplied lock file. The web server still needs read access to the
|
|
installed dependencies; it does not need write access to them for importing.
|
|
|
|
## Installation
|
|
|
|
1. Place the module in `modules/Mailgateway`.
|
|
2. Activate Mail Gateway in FOSSBilling. Activation creates the module tables,
|
|
registers its sender-mismatch email template and attempts to install dependencies.
|
|
3. Open Mail Gateway's settings from the Extensions page. If dependencies were
|
|
not installed automatically, use **Install dependencies** or run
|
|
`composer install` in the module directory.
|
|
4. Configure the receiving email address, helpdesk, IMAP connection details and
|
|
inbox and destination folders, then save.
|
|
5. Select **Test Connection and Create Folders**. This verifies the connection
|
|
and creates missing destination folders without processing emails.
|
|
6. After a successful test, enable mailbox importing and save again. This also
|
|
configures ticket acknowledgement and notification subjects automatically.
|
|
|
|
**Notification template changes persist:** enabling importing or running
|
|
**Configure ticket notifications** enables the ticket acknowledgement and adds
|
|
missing ticket references to existing FOSSBilling notification subjects. These
|
|
changes apply to those templates throughout FOSSBilling. Disabling or uninstalling
|
|
Mail Gateway does not restore their original subjects or enabled state. If you
|
|
want to restore them later, keep a copy of the original settings and edit the
|
|
templates manually in FOSSBilling's Email settings.
|
|
|
|
Use **Add mailbox** to configure additional addresses. Each mailbox has its own
|
|
connection details, folders and helpdesk. All four folder paths must be distinct;
|
|
the inbox must already exist.
|
|
|
|
Importing remains disabled until dependencies are installed and the mailbox has
|
|
passed its connection and folder test. Changing connection details or folder
|
|
paths requires another successful test. The settings page shows the results and
|
|
explains any failures.
|
|
|
|
No additional cron entry is needed. The module polls every five minutes by
|
|
default, provided the FOSSBilling cron runs that often.
|
|
|
|
## Tickets and replies
|
|
|
|
Email from a customer's primary email address creates a customer ticket.
|
|
Unknown senders create guest tickets when guest tickets are enabled in Support.
|
|
New tickets go to the mailbox's selected helpdesk.
|
|
|
|
Replies are matched by a subject marker such as `[Ticket #123]`. The sender must
|
|
own the referenced ticket. Emails without a ticket marker create a new ticket;
|
|
reply headers are not used for matching.
|
|
|
|
Sender matching uses the email's From address; it does not prove that the sender
|
|
controls that address. Mail Gateway does not independently verify SPF, DKIM or
|
|
DMARC, and relies on the receiving mail server to apply authentication and
|
|
anti-spoofing policies before mail reaches the imported inbox. Configure those
|
|
policies to reject or quarantine suspicious messages outside that inbox.
|
|
A forged message accepted into the inbox could impersonate a customer or the
|
|
owner of a guest ticket. Guest reply ownership is based on the original sender's
|
|
email address, without an authenticated customer account.
|
|
|
|
Enabling mailbox importing automatically enables the `mod_support_ticket_open`
|
|
acknowledgement and adds `[Ticket #{{ ticket.id }}]` to its subject and enabled
|
|
staff notification subjects where missing. Existing wording is preserved and
|
|
disabled optional staff notifications stay disabled. Notifications are delivered
|
|
through FOSSBilling's email queue.
|
|
|
|
For an existing mailbox, use **Advanced → Configure ticket notifications** to run
|
|
the same setup. Notification status is shown in Advanced, with any problems also
|
|
displayed at the top of the page. Setup does not send test emails. You can edit
|
|
notification wording in FOSSBilling's Email settings; keep the ticket marker in
|
|
subjects so replies can be matched.
|
|
|
|
The included `mailgateway_sender_mismatch` template uses your company name and
|
|
email signature to tell senders when their address does not match the referenced
|
|
ticket. It is installed only if missing. Its wording can be edited or the
|
|
notification disabled in Email settings. Existing custom templates are preserved.
|
|
|
|
Messages use plain text when available, with HTML converted to text otherwise.
|
|
Quoted reply history is retained. Attachments stay in the archived email and are
|
|
not attached to tickets.
|
|
|
|
## Email handling
|
|
|
|
| Result | Destination |
|
|
| --- | --- |
|
|
| Imported ticket, reply or duplicate | Processed |
|
|
| Recognised automatic message | Ignored |
|
|
| Invalid message or rejected reply | Failed |
|
|
| Temporary connection or database failure | Inbox, for retry |
|
|
|
|
Only the configured inbox is imported, including already-read messages.
|
|
Duplicate tracking prevents repeated imports, including when a folder move needs
|
|
to be retried. To retry a rejected email after resolving its cause, move it from
|
|
Failed back to the inbox.
|
|
|
|
Recognised automatic messages receive no response. Unmarked automatic messages
|
|
cannot always be identified; a notification cooldown limits automated
|
|
acknowledgements and sender-mismatch notices to one per sender per hour by default.
|
|
|
|
## Configuration and maintenance
|
|
|
|
Mailbox settings are stored in the database, with passwords encrypted using
|
|
FOSSBilling's encryption helper. Leaving a password blank keeps the saved value;
|
|
use the password-clearing option to remove it.
|
|
|
|
Operational settings are in `config.php`, including polling limits, timeouts,
|
|
message size limits, notification cooldown and executable paths. Edit this file
|
|
over SSH; changes take effect on the next cron run or web request. By default,
|
|
each run handles up to 50 messages per mailbox, with a shared 90-second time
|
|
budget. Complete emails are limited to 5 MiB and ticket bodies to 65,535 bytes.
|
|
|
|
The settings page's **Advanced** section provides notification setup, Composer
|
|
installation and table setup. Table setup creates missing tables and the default
|
|
mismatch template without deleting existing data or replacing customised templates.
|
|
|
|
Deleting a mailbox removes its configuration while keeping emails, folders,
|
|
tickets and message tracking.
|
|
|
|
The following commands are available from the module directory:
|
|
|
|
```bash
|
|
# Test a saved mailbox without processing emails.
|
|
php tools/test-imap.php
|
|
|
|
# Test another mailbox and create missing destination folders.
|
|
php tools/test-imap.php --mailbox=billing@example.com --create-folders
|
|
|
|
# Import mail immediately.
|
|
php tools/poll.php --force
|
|
|
|
# Create missing tables and register the default email template.
|
|
php tools/setup.php
|
|
```
|
|
|
|
A connection test with `--create-folders` records the mailbox's readiness, just as
|
|
the settings-page test does. A read-only test does not change readiness.
|
|
|
|
## Compatibility note
|
|
|
|
The module loads its own Composer dependencies into the same PHP process as
|
|
FOSSBilling. Shared Symfony or Illuminate packages are not isolated by the module's
|
|
separate `vendor` directory. Check installation, connection testing and importing
|
|
on your FOSSBilling version before deploying; compatibility across clean
|
|
FOSSBilling installations and versions has not yet been established.
|
|
|
|
During imported ticket creation, the module temporarily wraps FOSSBilling's
|
|
`mod_service` factory to intercept email calls. This applies the acknowledgement
|
|
cooldown and suppresses the separate canned-response email while retaining its
|
|
ticket history. Other module lookups are delegated to the original factory,
|
|
which is restored in a `finally` block, including when creation fails.
|
|
|
|
Ticket-creation hooks also see this wrapped factory: email services obtained
|
|
during that scope are proxies, and matching notification codes are intercepted.
|
|
The installed FOSSBilling notification interfaces provide no per-ticket
|
|
suppression option. This integration should be reviewed when upgrading
|
|
FOSSBilling or adding hooks that send emails during ticket creation.
|
|
|
|
## License
|
|
|
|
Apache-2.0.
|