Skip to content

Microsoft 365 / Exchange Online Email Setup

Professional-level guide for integrating Microsoft 365 (Exchange Online) email with Odoo, including catchall addresses, mail flow rules, and OAuth2 authentication.

Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│                 MICROSOFT 365 / EXCHANGE ONLINE                      │
└─────────────────────────────────────────────────────────────────────┘

                         Your Domain: yourdomain.com
                    ┌───────────────┼───────────────┐
                    │               │               │
                    ▼               ▼               ▼
            ┌───────────┐   ┌───────────┐   ┌───────────┐
            │  Aliases  │   │ Catchall  │   │ Mail Flow │
            │           │   │ (Transport│   │   Rules   │
            │ sales@    │   │   Rule)   │   │           │
            │ support@  │   │     ↓     │   │ purchase+ │
            │ info@     │   │ catchall@ │   │ sale+     │
            └─────┬─────┘   └─────┬─────┘   └─────┬─────┘
                  │               │               │
                  └───────────────┼───────────────┘
                    ┌─────────────────────────┐
                    │  Shared/Service Mailbox │
                    │   odoo@yourdomain.com   │
                    └────────────┬────────────┘
                    ┌────────────┼────────────┐
                    │            │            │
                    ▼            ▼            ▼
              ┌──────────┐ ┌──────────┐ ┌──────────┐
              │  IMAP    │ │   SMTP   │ │  Azure   │
              │ Incoming │ │ Outgoing │ │  OAuth2  │
              └────┬─────┘ └────┬─────┘ └────┬─────┘
                   │            │            │
                   └────────────┼────────────┘
                    ┌─────────────────────────┐
                    │         ODOO            │
                    │                         │
                    │  • Fetchmail Service    │
                    │  • mail.thread routing  │
                    │  • Email sending        │
                    └─────────────────────────┘

Prerequisites

Requirement Description
Microsoft 365 Business Basic or higher (Exchange Online)
Admin Access Exchange Admin or Global Admin
Azure AD Access For OAuth2 app registration
Domain Verified Custom domain configured in M365
Odoo Access Admin access to Odoo instance

Key Differences from Google Workspace

Feature Google Workspace Microsoft 365
Catchall Built-in feature Transport rule workaround
Admin Portal Google Admin Console Exchange Admin Center + Azure Portal
OAuth Setup Google Cloud Console Azure Portal (Entra ID)
Pattern Routing Default Routing rules Mail Flow (Transport) rules
Shared Mailbox User aliases Shared Mailbox (no license)

Step 1: Create Service Account or Shared Mailbox

You have two options:

Option A: Shared Mailbox (No License Required)

  1. Go to Exchange Admin Center
  2. Navigate to Recipients → Mailboxes → Add a shared mailbox
  3. Create mailbox:
Field Value
Display name Odoo System
Email address odoo@yourdomain.com

Shared Mailbox Benefits

  • No license required (cost savings)
  • Up to 50GB storage
  • Multiple users can access

Option B: Service Account (Licensed User)

  1. Go to Microsoft 365 Admin Center
  2. Navigate to Users → Active users → Add a user
  3. Create user:
Field Value
Display name Odoo Service
Username odoo@yourdomain.com
License Exchange Online (minimum)

Shared Mailbox + OAuth Limitation

Shared mailboxes require special OAuth configuration. For simpler setup, use a licensed service account.

Step 2: Enable IMAP and SMTP AUTH

For Individual Mailbox

Using PowerShell:

# Connect to Exchange Online
Connect-ExchangeOnline

# Enable IMAP
Set-CASMailbox -Identity "odoo@yourdomain.com" -ImapEnabled $true

# Enable SMTP AUTH (required for sending)
Set-CASMailbox -Identity "odoo@yourdomain.com" -SmtpClientAuthenticationDisabled $false

# Verify settings
Get-CASMailbox -Identity "odoo@yourdomain.com" | FL Imap*, Smtp*

For Organization-Wide (if SMTP AUTH is disabled)

# Check organization setting
Get-TransportConfig | FL SmtpClientAuthenticationDisabled

# Enable if needed (affects all users)
Set-TransportConfig -SmtpClientAuthenticationDisabled $false

Via Exchange Admin Center

  1. Go to Recipients → Mailboxes
  2. Select the Odoo mailbox
  3. Click Manage email apps settings
  4. Enable IMAP and Authenticated SMTP

Step 3: Set Up Catchall (Transport Rule Method)

Microsoft 365 doesn't have built-in catchall. Use transport rules instead.

Step 3.1: Create Dynamic Distribution Group

This group contains all valid recipients to exclude from catchall.

Using PowerShell:

# Connect to Exchange Online
Connect-ExchangeOnline

# Create Dynamic Distribution Group with all recipients
New-DynamicDistributionGroup -Name "All Mail Recipients" `
    -RecipientFilter "RecipientType -eq 'UserMailbox' -or RecipientType -eq 'MailUniversalDistributionGroup' -or RecipientType -eq 'MailUniversalSecurityGroup' -or RecipientType -eq 'MailContact' -or RecipientType -eq 'SharedMailbox'"

# Verify members
$DDG = Get-DynamicDistributionGroup "All Mail Recipients"
Get-Recipient -RecipientPreviewFilter $DDG.RecipientFilter | Select Name, PrimarySmtpAddress

Step 3.2: Change Domain to Internal Relay

This allows Exchange to accept emails for non-existent addresses.

Using PowerShell:

# View current domain type
Get-AcceptedDomain | FL Name, DomainType

# Change to Internal Relay
Set-AcceptedDomain -Identity "yourdomain.com" -DomainType InternalRelay

Via Exchange Admin Center:

  1. Go to Mail flow → Accepted domains
  2. Select your domain
  3. Change type to Internal Relay

Internal Relay Impact

This allows ALL emails to your domain to be accepted, even to non-existent addresses. Make sure your catchall rule is working before enabling this.

Step 3.3: Create Transport Rule for Catchall

Via Exchange Admin Center:

  1. Go to Mail flow → Rules
  2. Click + Add a rule → Create a new rule
  3. Configure:
Setting Value
Name Catchall to Odoo
Apply this rule if The recipient is not a member of "All Mail Recipients"
Do the following Redirect the message to odoo@yourdomain.com
Except if The sender is inside the organization
Priority Set lower than other rules

Using PowerShell:

New-TransportRule -Name "Catchall to Odoo" `
    -SentToMemberOf "All Mail Recipients" `
    -ExceptIfSentToMemberOf "All Mail Recipients" `
    -RedirectMessageTo "odoo@yourdomain.com" `
    -Priority 10

Dynamic Group Update Delay

Microsoft updates Dynamic Distribution Groups once per day. New users may not receive email until the next update. Force update with:

Set-DynamicDistributionGroup "All Mail Recipients" -RecipientFilter $((Get-DynamicDistributionGroup "All Mail Recipients").RecipientFilter)
(Limited to once per hour)

Instead of catchall, route specific Odoo patterns for better control.

Create Mail Flow Rules for Odoo Patterns

Rule 1: Purchase Order Replies

  1. Go to Mail flow → Rules → + Add a rule
  2. Configure:
Setting Value
Name Route Purchase+ to Odoo
Apply this rule if The recipient address includes: purchase+
Do the following Redirect the message to: odoo@yourdomain.com

Rule 2: Sales Order Replies

Setting Value
Name Route Sale+ to Odoo
Apply this rule if The recipient address includes: sale+
Do the following Redirect the message to: odoo@yourdomain.com

Rule 3: Helpdesk Replies

Setting Value
Name Route Helpdesk+ to Odoo
Apply this rule if The recipient address includes: helpdesk+
Do the following Redirect the message to: odoo@yourdomain.com

Using PowerShell (All Rules):

# Purchase Orders
New-TransportRule -Name "Route Purchase+ to Odoo" `
    -RecipientAddressContainsWords "purchase+" `
    -RedirectMessageTo "odoo@yourdomain.com"

# Sales Orders
New-TransportRule -Name "Route Sale+ to Odoo" `
    -RecipientAddressContainsWords "sale+" `
    -RedirectMessageTo "odoo@yourdomain.com"

# Helpdesk
New-TransportRule -Name "Route Helpdesk+ to Odoo" `
    -RecipientAddressContainsWords "helpdesk+" `
    -RedirectMessageTo "odoo@yourdomain.com"

# CRM Leads
New-TransportRule -Name "Route CRM+ to Odoo" `
    -RecipientAddressContainsWords "crm+","lead+" `
    -RedirectMessageTo "odoo@yourdomain.com"

Combined Rule with Regex

For advanced pattern matching:

New-TransportRule -Name "Route All Odoo Patterns" `
    -RecipientAddressMatchesPatterns "^(purchase|sale|helpdesk|crm|lead|project)\+.*@yourdomain\.com$" `
    -RedirectMessageTo "odoo@yourdomain.com"

Step 5: Configure Azure OAuth2 for Odoo

Microsoft deprecated Basic Auth. Use OAuth2 for secure authentication.

Step 5.1: Register Application in Azure Portal

  1. Go to Azure Portal
  2. Navigate to Microsoft Entra ID (formerly Azure Active Directory)
  3. Click App registrations → New registration
  4. Configure:
Field Value
Name Odoo Mail Integration
Supported account types Accounts in this organizational directory only
Redirect URI Web: https://yourodoo.com/microsoft_outlook/confirm
  1. Click Register
  2. Copy the Application (client) ID and Directory (tenant) ID

Step 5.2: Create Client Secret

  1. In your app registration, go to Certificates & secrets
  2. Click New client secret
  3. Add description: Odoo OAuth
  4. Set expiration (24 months recommended)
  5. Click Add
  6. Copy the secret value immediately (won't be shown again)

Step 5.3: Configure API Permissions

  1. Go to API permissions
  2. Click Add a permission
  3. Select Microsoft Graph
  4. Choose Delegated permissions
  5. Add these permissions:
Permission Purpose
User.Read Sign in and read user profile
IMAP.AccessAsUser.All Read email via IMAP
SMTP.Send Send email via SMTP
offline_access Maintain access (refresh token)
  1. Click Add permissions
  2. Click Grant admin consent for [Your Organization]

Step 5.4: Add Users to Application (Optional)

For additional security:

  1. Go to Enterprise applications
  2. Find your Odoo Mail Integration app
  3. Go to Users and groups
  4. Click Add user/group
  5. Add the Odoo service account

Step 6: Configure Odoo

Install Microsoft Outlook Module

  1. Go to Apps
  2. Search for Microsoft Outlook
  3. Install the module

Configure OAuth Credentials

  1. Go to Settings → General Settings
  2. Enable Custom Email Servers under Discuss
  3. Enter OAuth credentials:
Field Value
Client ID (from Azure Portal)
Client Secret (from Azure Portal)
  1. Click Save

Configure Outgoing Mail Server

  1. Go to Settings → Technical → Outgoing Mail Servers
  2. Create new server:
Field Value
Description Microsoft 365 OAuth
SMTP Server smtp.office365.com
SMTP Port 587
Connection Security TLS (STARTTLS)
Username odoo@yourdomain.com
Outlook OAuth Authentication Checked
  1. Click Connect your Outlook account
  2. Complete Microsoft authentication
  3. Click Test Connection

Configure Incoming Mail Server

  1. Go to Settings → Technical → Incoming Mail Servers
  2. Create new server:
Field Value
Name Microsoft 365 OAuth IMAP
Server Type Outlook OAuth Authentication
Username odoo@yourdomain.com
Outlook OAuth Authentication Checked
  1. Click Connect your Outlook account
  2. Click Test & Confirm

If OAuth isn't possible, use SMTP Relay:

Outgoing Server:

Field Value
SMTP Server yourdomain-com.mail.protection.outlook.com
SMTP Port 25
Connection Security TLS (STARTTLS)
Username (leave empty for relay)

Basic Auth Deprecation

Microsoft is phasing out Basic Authentication. Use OAuth2 for new setups.

Step 7: Configure Odoo Alias Domain

  1. Go to Settings → General Settings
  2. Under Discuss, set Alias Domain: yourdomain.com
  3. Click Save

Step 8: Verify Fetchmail Cron

  1. Go to Settings → Technical → Scheduled Actions
  2. Find Mail: Fetchmail Service
  3. Verify:
Setting Value
Active Checked
Interval 5 minutes

Testing the Setup

Test 1: Send Email from Odoo

  1. Create a Purchase Order
  2. Send RFQ to test email
  3. Verify email received
  4. Check headers for correct Reply-To

Test 2: Reply Routing

  1. Reply to the RFQ email
  2. Wait for fetchmail (or run manually)
  3. Check if reply appears in PO chatter

Test 3: Pattern Routing

  1. Send email to purchase+test@yourdomain.com
  2. Verify it arrives in Odoo mailbox

Test 4: Catchall (if configured)

  1. Send email to random123@yourdomain.com
  2. Verify it arrives in Odoo mailbox

Troubleshooting

OAuth Connection Failed

Issue Solution
Redirect URI mismatch Must match exactly in Azure and Odoo
Missing permissions Grant admin consent in Azure
Wrong tenant Verify Directory (tenant) ID
HTTPS required Odoo must use HTTPS for OAuth

Emails Not Being Received

Issue Solution
IMAP disabled Enable in Exchange Admin Center
Transport rule not working Check rule priority and conditions
Domain not Internal Relay Change domain type in Accepted Domains
DDG not updated Force update or wait 24 hours

Cannot Send Emails

Issue Solution
SMTP AUTH disabled Enable per-mailbox or org-wide
Authentication failed Re-authenticate OAuth in Odoo
Relay blocked Check connector settings

Check Message Trace

  1. Go to Exchange Admin Center
  2. Navigate to Mail flow → Message trace
  3. Search for specific email addresses
  4. View delivery status and applied rules

PowerShell Diagnostics

# Check mailbox settings
Get-CASMailbox -Identity "odoo@yourdomain.com" | FL

# Check transport rules
Get-TransportRule | FL Name, State, Priority

# Check accepted domains
Get-AcceptedDomain | FL Name, DomainType

# Test mail flow
Test-Mailflow -TargetEmailAddress "test@external.com"

# View message trace
Get-MessageTrace -RecipientAddress "odoo@yourdomain.com" -StartDate (Get-Date).AddDays(-1)

Complete Configuration Summary

Exchange Admin Center

Setting Location Value
Odoo Mailbox Recipients → Mailboxes odoo@yourdomain.com
IMAP Enabled Mailbox → Email apps Enabled
SMTP AUTH Mailbox → Email apps Enabled
Domain Type Mail flow → Accepted domains Internal Relay
Transport Rules Mail flow → Rules Catchall + Pattern rules

Azure Portal

Setting Location Value
App Registration Entra ID → App registrations Odoo Mail Integration
Client Secret App → Certificates & secrets Created
API Permissions App → API permissions IMAP, SMTP, User.Read
Redirect URI App → Authentication https://yourodoo.com/microsoft_outlook/confirm

Odoo

Setting Location Value
Outlook module Apps Installed
OAuth credentials General Settings Client ID + Secret
Alias domain General Settings → Discuss yourdomain.com
Outgoing server Technical → Outgoing Mail Microsoft 365 OAuth
Incoming server Technical → Incoming Mail Microsoft 365 OAuth IMAP
Fetchmail cron Technical → Scheduled Actions Active, 5 min

Security Best Practices

Practice Description
Use OAuth2 Never use Basic Auth in production
Service account Dedicated account for Odoo
Conditional Access Apply Azure AD policies to app
Audit logs Enable mailbox audit logging
Secret rotation Rotate client secrets before expiry
MFA exemption May need to exempt service account from MFA

Monthly Maintenance Checklist

  • Verify fetchmail cron is running
  • Check OAuth token is still valid
  • Check client secret expiry date
  • Review transport rules are working
  • Check message trace for delivery issues
  • Verify DDG membership is current
  • Check Odoo mailbox storage quota

PowerShell Quick Reference

# Connect to Exchange Online
Connect-ExchangeOnline

# Enable IMAP/SMTP for mailbox
Set-CASMailbox -Identity "odoo@yourdomain.com" -ImapEnabled $true -SmtpClientAuthenticationDisabled $false

# Create transport rule
New-TransportRule -Name "Route to Odoo" -RecipientAddressContainsWords "purchase+" -RedirectMessageTo "odoo@yourdomain.com"

# Check transport rules
Get-TransportRule | Select Name, State, Priority

# Message trace
Get-MessageTrace -RecipientAddress "odoo@yourdomain.com" -StartDate (Get-Date).AddDays(-1)

# Force DDG update
Set-DynamicDistributionGroup "All Mail Recipients" -RecipientFilter $((Get-DynamicDistributionGroup "All Mail Recipients").RecipientFilter)

# Disconnect
Disconnect-ExchangeOnline

Sources