Email Configuration
The ticket system uses email for ticket creation (inbound), notifications (outbound), and client communication. Email is fetched and sent via Microsoft 365 OAuth (Graph API).
Email Accounts Overview
Navigate to Admin → Emails to manage email accounts.
| Account | Purpose |
|---|---|
| System Email | Default sender for system notifications |
| Department Emails | Per-department inbound/outbound addresses |
| Alert Email | Sender for internal staff alerts |
| Auto-Response Email | Sender for client auto-replies |
Adding a New Email Account
Step 1: Create Email in Admin Panel
- Navigate to Admin → Emails → Add New Email
- Fill in:
| Field | Description |
|---|---|
| Email Address | The email address (e.g., [email protected]) |
| Email Name | Display name for outbound emails |
| Department | Route inbound emails to this department |
| Priority | Default priority for tickets from this email |
| Auto-Response | Enable/disable auto-reply |
Step 2: Configure OAuth (Microsoft 365)
- Go to the email account's Remote Mailbox tab
- Select Microsoft 365 OAuth as the fetch method
- Enter Azure AD credentials:
- Tenant ID
- Client ID
- Client Secret
- Click Authorize — complete Microsoft login
- Test fetch: verify "Last Fetch" timestamp updates
Step 3: Configure Outgoing (SMTP via Graph)
- Go to the Sending Email tab
- Select Microsoft Graph API as the send method
- OAuth tokens are shared with the fetch configuration
- Send a test email to verify
See Microsoft 365 Integration for Azure AD setup details.
Email Templates
System Templates
Navigate to Admin → Emails → Templates to customize:
| Template | Trigger |
|---|---|
| New Ticket Auto-Response | Client creates a ticket |
| New Ticket Alert | Staff notification of new ticket |
| New Message Alert | Staff notification of client reply |
| Response/Reply Template | Staff reply wrapper |
| Ticket Assignment Alert | Staff assigned to ticket |
| Ticket Transfer Alert | Ticket transferred |
| Overdue Alert | SLA breached |
| Ticket Closed | Confirmation to client |
Template Variables
Templates use %{variable} syntax:
| Variable | Value |
|---|---|
%{ticket.number} | Ticket display number |
%{ticket.subject} | Ticket subject line |
%{ticket.status} | Current status name |
%{ticket.priority} | Priority level |
%{ticket.dept} | Department name |
%{ticket.staff} | Assigned staff name |
%{ticket.createDate} | Creation date |
%{ticket.lastMessage} | Most recent message |
%{recipient.name} | Email recipient name |
%{url} | Ticket URL (uses ?number= format) |
URL Format in Templates
Always use ticket number in URLs:
<a href="tickets.php?number=%{ticket.number}">View Ticket #%{ticket.number}</a>
Email Threading
How Replies Are Matched to Tickets
When an inbound email arrives, the system matches it to an existing ticket:
- Message-ID / In-Reply-To — Checks if the email references a previous message from this ticket
- References header — Checks the full reference chain
- Subject line pattern — Extracts
[#XXXXXX]ticket number from subject
If no match is found, a new ticket is created.
Thread Subject Format
Outbound emails include the ticket number in the subject:
[#108749] Re: Checkout page error
This ensures client replies are threaded correctly even if email headers are stripped.
Auto-Reply Detection
The system detects and discards auto-replies to prevent loops:
| Header | Pattern |
|---|---|
X-Auto-Responded-Suppress | Any value present |
Auto-Submitted | auto-replied, auto-generated |
X-Autoreply | Any value present |
Precedence | bulk, junk, list |
| Subject patterns | "Out of Office", "Automatic reply", "Undeliverable" |
Inline Images
HTML emails with inline images (CID references) are handled:
- MIME multipart email parsed
- CID-referenced attachments extracted
- Images saved to osTicket file storage
- HTML
src="cid:..."references replaced with attachment URLs - Images display correctly in ticket thread view
Email Fetching Schedule
| Setting | Value |
|---|---|
| Fetch Method | Microsoft 365 OAuth (Graph API) |
| Frequency | Every cron run (1 minute intervals) |
| Batch Size | Up to 20 emails per fetch |
| Read Status | Marks fetched emails as read |
| Folder | Inbox (configurable) |
Verifying Email Fetch
- Check Admin → Emails → (account) for "Last Fetch" timestamp
- Query the system log:
SELECT * FROM ost_syslog
WHERE title LIKE '%mail%'
ORDER BY created DESC
LIMIT 10;
Troubleshooting
| Issue | Solution |
|---|---|
| Emails not being fetched | Check OAuth token is valid; re-authorize if needed |
| Auto-replies creating tickets | Check auto-reply detection rules; add custom filter |
| Images not displaying | Verify inline image processing is working; check file permissions |
| Duplicate tickets from same email | Check email threading; verify Message-ID headers preserved |
| "Send failed" errors | Verify Graph API send permission; check OAuth token |
| Template variables not replacing | Ensure correct syntax %{variable} with curly braces |
| Emails going to spam | Configure SPF, DKIM, DMARC for the sending domain |
Best Practices
- One email account per department — cleaner routing and management
- Test after OAuth re-authorization — always verify fetch/send after token refresh
- Monitor "Last Fetch" timestamps — stale timestamps indicate fetching is broken
- Keep auto-response templates brief — acknowledge receipt without overwhelming clients
- Include ticket number in subject — ensures proper threading
- Set up mailbox monitoring — alert if emails stop being fetched for more than 5 minutes