You'll have to excuse the summary from Claude
Status Update: OAuth2 is functional for both IMAP and SMTP, but there's a bug preventing ticket reply emails. I am not yet sure if any other email sending functions are impacted as i have not tested yet.
Complete OAuth2 Setup Process
1. Azure App Registration
Go to Azure Portal → Azure Active Directory → App registrations
Create new registration:
Name: ITFlow Email Integration
Supported account types: Accounts in this organizational directory only
Redirect URI: Web - https://yourdomain.com/plugins/PHPMailer/get_oauth_token.php
Note Client ID, Client Secret, and Tenant ID
API Permissions (delegated):
Microsoft Graph: Mail.Read
, Mail.Send
Office 365 Exchange Online: IMAP.AccessAsUser.All
, SMTP.Send
Grant admin consent
2. Fixing get_oauth_token.php Dependencies The script fails with 500 error due to missing OAuth2 client libraries:
bash
$$
Create temp composer project to avoid conflicts
mkdir -p /tmp/oauth_deps && cd /tmp/oauth_deps
composer init --no-interaction --name="temp/oauth"
composer require league/oauth2-google stevenmaguire/oauth2-microsoft greew/oauth2-azure-provider
Copy to PHPMailer directory where the script expects them
cp -r vendor /var/www/yourdomain.com/plugins/PHPMailer/
chown -R www-data:www-data /var/www/yourdomain.com/plugins/PHPMailer/vendor/
$$
3. Generate Refresh Token
Access: https://yourdomain.com/plugins/PHPMailer/get_oauth_token.php
Select "Azure" as provider (not "Microsoft")
Enter Client ID, Secret, Tenant ID
Complete OAuth flow with the licensed mailbox account (not shared mailbox)
Copy the refresh token
4. Configure ITFlow
Settings → Mail Settings
Set both IMAP Provider and SMTP Provider to "Microsoft 365 (OAuth)"
IMAP Username: full email address
Fill OAuth fields with Azure app details and refresh token
Current Status
✅ IMAP email parsing: Working perfectly
✅ New ticket auto-reply emails: Working perfectly
❌ Ticket reply/update emails: Not working
Root Cause Analysis
The issue is that ticket reply emails aren't being queued at all due to a critical bug in the OAuth2 implementation.
The Problem: In ticket.php
, the email generation logic has this check:
php
$$
if ($ticket_reply_type == 'Public' && $send_email == 1 && !empty($config_smtp_host)) {
$$
However, when using OAuth2, config_smtp_host
is empty in the database:
sql
$$
SELECT config_smtp_host, config_smtp_provider FROM settings WHERE company_id = 1;
+------------------+----------------------+
| config_smtp_host | config_smtp_provider |
+------------------+----------------------+
| | microsoft_oauth |
+------------------+----------------------+
$$
Why New Ticket Emails Work vs Reply Emails Don't:
New ticket emails (add_ticket
handler) only check: !empty($config_smtp_host) && $config_ticket_client_general_notifications == 1
Mail queue (mail_queue.php
) automatically sets defaults for OAuth:
php
$$
if ($provider === 'microsoft_oauth') {
if (!$host) $host = 'smtp.office365.com';
$$
- Ticket reply emails check
!empty($config_smtp_host)
before reaching the mail queue, so they never get queued
Recommendations for Fix
The OAuth2 implementation should automatically populate SMTP/IMAP host settings when a provider is selected, or the ticket reply logic should be updated to handle empty config_smtp_host
when OAuth providers are configured.
Is it possible to have SMTP options separate to IMAP? This would allow the ticket email parser to still function with OAuth whilst having a dedicated SMTP server for sending until the bugs are ironed out.