11 KiB
DigitalData.MessagingService
A .NET 8 messaging service for sending and receiving emails via SMTP, IMAP, POP3 and OAuth2, with RabbitMQ-based async delivery.
Email Account Configuration
Each account is configured under EmailAccounts.Accounts in appsettings.Secrets.json.
Different providers require different configuration fields. See provider-specific sections below.
Common fields (all providers)
{
"Id": 1,
"Username": "user@example.com",
"Password": "your_password",
"SmtpServer": "smtp.example.com",
"SmtpPort": 465,
"SmtpUseSsl": true,
"UseOAuth2": false,
"ImapServer": "imap.example.com",
"ImapPort": 993,
"ImapUseSsl": true,
"Pop3Server": "pop.example.com",
"Pop3Port": 995,
"Pop3UseSsl": true,
"IncomingProtocol": 1
}
Passwordis always retained. WhenUseOAuth2 = true, SMTP/IMAP/POP3 connections use OAuth2 tokens instead of the password. WhenUseOAuth2 = false, the password is used directly. TheIncomingProtocolfield independently controls which protocol is used for receiving emails.
IncomingProtocol values
| Value | Meaning |
|---|---|
0 |
None — send-only account, skipped by sync worker |
1 |
IMAP with username/password |
2 |
POP3 with username/password |
3 |
IMAP with OAuth2 |
4 |
POP3 with OAuth2 |
OAuth2Provider values
| Value | Meaning |
|---|---|
0 |
None |
1 |
Microsoft (Azure AD / Microsoft 365) |
2 |
Google (Gmail / Google Workspace) |
Provider-specific OAuth2 Configuration
Google (Gmail / Google Workspace)
Google uses user-delegated OAuth2 (authorization code flow). A one-time interactive authorization is required to obtain a refresh token. The refresh token is then stored in the database and reused automatically for all subsequent operations.
The refresh token survives application restarts. It will not be overwritten by the seed process unless
OAuth2RefreshTokenis explicitly set to a non-empty value inappsettings.Secrets.json.
Required fields
{
"UseOAuth2": true,
"OAuth2ClientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"OAuth2ClientSecret": "GOCSPX-YOUR_CLIENT_SECRET",
"OAuth2RefreshToken": "",
"OAuth2TenantId": "",
"OAuth2Provider": 2
}
Google Cloud Console setup (one-time)
- Go to console.cloud.google.com and create or select a project.
- Enable the Gmail API under APIs & Services ? Library.
- Go to APIs & Services ? Credentials ? + Create Credentials ? OAuth 2.0 Client ID:
- Application type: Web application
- Authorized redirect URIs: add
https://YOUR_HOST/api/oauth2/google/callback(e.g.https://localhost:7261/api/oauth2/google/callbackfor local development)
- Go to APIs & Services ? OAuth consent screen:
- Add the Gmail account under Test users (required while app is in Testing mode).
Obtaining the refresh token via the built-in authorization endpoint
The application provides a built-in OAuth2 flow — no external tools needed.
-
Open a browser and navigate to:
GET /api/oauth2/google/authorize/{accountId}Example:
https://localhost:7261/api/oauth2/google/authorize/3 -
You will be redirected to Google's consent screen. If you see "Google hasn't verified this app", click Continue — this is expected while the app is in Testing mode.
-
Sign in with the Gmail account and grant access.
-
Google redirects back to
/api/oauth2/google/callbackautomatically. The application exchanges the authorization code for a refresh token and saves it to the database. -
A success response is returned:
{ "success": true, "username": "user@gmail.com", "message": "..." } -
The sync worker and all IMAP/SMTP operations will now work automatically.
?? The refresh token must be re-obtained if
invalid_grantis returned. This happens if the token is unused for 6 months or if the user revokes access.
Microsoft 365 / Exchange Online (Azure AD)
Microsoft uses application-level OAuth2 (client credentials flow — no user interaction required). Tokens are acquired automatically using the client ID, secret and tenant ID. No authorization endpoint needs to be visited.
Required fields
{
"UseOAuth2": true,
"OAuth2ClientId": "YOUR_APP_CLIENT_ID",
"OAuth2ClientSecret": "YOUR_APP_CLIENT_SECRET_VALUE",
"OAuth2TenantId": "yourorg.onmicrosoft.com",
"OAuth2Provider": 1
}
Azure Portal setup (one-time)
- Go to portal.azure.com ? Azure Active Directory ? App registrations ? + New registration.
- Go to Certificates & secrets ? + New client secret ? copy the Value (not the ID).
- Set this as
OAuth2ClientSecret.
- Set this as
- Go to API permissions ? + Add a permission ? APIs my organization uses ? Office 365 Exchange Online:
- Add Application permissions:
IMAP.AccessAsApp,SMTP.SendAsApp,POP.AccessAsApp - Click Grant admin consent
- Add Application permissions:
- In Exchange Online PowerShell, register the service principal for the mailbox:
New-ServicePrincipal -AppId <ClientId> -ServiceId <ObjectId> -DisplayName "MessagingService" Add-MailboxPermission -Identity "user@yourorg.onmicrosoft.com" -User <ObjectId> -AccessRights FullAccess - Set
OAuth2TenantIdto the full domain (e.g.yourorg.onmicrosoft.com) or tenant GUID.
??
OAuth2ClientSecretmust be the Value shown at secret creation time, not the Secret ID (GUID). The value is only visible once — if lost, create a new secret.
??
OAuth2TenantIdmust be a full domain (yourorg.onmicrosoft.com), a tenant GUID, orcommon. Short names likeyourorgare not valid and will causeAADSTS900023.
No browser-based authorization is required for Microsoft — the application acquires tokens automatically on first use and caches them in memory until 5 minutes before expiry.
Email Account Configuration
Each account is configured under EmailAccounts.Accounts in appsettings.Secrets.json.
Different providers require different configuration fields. See provider-specific sections below.
Common fields (all providers)
{
"Id": 1,
"Username": "user@example.com",
"Password": "your_password",
"SmtpServer": "smtp.example.com",
"SmtpPort": 465,
"SmtpUseSsl": true,
"UseOAuth2": false,
"ImapServer": "imap.example.com",
"ImapPort": 993,
"ImapUseSsl": true,
"Pop3Server": "pop.example.com",
"Pop3Port": 995,
"Pop3UseSsl": true,
"IncomingProtocol": 1
}
Passwordis always retained. WhenUseOAuth2 = true, SMTP/IMAP/POP3 connections use OAuth2 tokens instead of the password. WhenUseOAuth2 = false, the password is used directly. TheIncomingProtocolfield independently controls which protocol is used for receiving emails.
IncomingProtocol values
| Value | Meaning |
|---|---|
0 |
None — send-only account, skipped by sync worker |
1 |
IMAP with username/password |
2 |
POP3 with username/password |
3 |
IMAP with OAuth2 |
4 |
POP3 with OAuth2 |
OAuth2Provider values
| Value | Meaning |
|---|---|
0 |
None |
1 |
Microsoft (Azure AD / Microsoft 365) |
2 |
Google (Gmail / Google Workspace) |
Provider-specific OAuth2 Configuration
Google (Gmail / Google Workspace)
Google uses user-delegated OAuth2 (not client credentials). A one-time authorization flow is required to obtain a refresh token.
Required fields
{
"UseOAuth2": true,
"OAuth2ClientId": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"OAuth2ClientSecret": "GOCSPX-YOUR_CLIENT_SECRET",
"OAuth2RefreshToken": "1//04YOUR_REFRESH_TOKEN",
"OAuth2TenantId": "",
"OAuth2Provider": 2
}
Setup — obtaining the refresh token (one-time)
- Go to console.cloud.google.com and create or select a project.
- Enable the Gmail API under APIs & Services ? Library.
- Go to APIs & Services ? Credentials ? + Create Credentials ? OAuth 2.0 Client ID.
- Application type: Web application
- Authorized redirect URIs:
https://developers.google.com/oauthplayground
- Go to APIs & Services ? OAuth consent screen:
- Add the Gmail account under Test users (required while app is in Testing mode).
- Go to developers.google.com/oauthplayground:
- Click ?? Settings ? enable "Use your own OAuth credentials"
- Enter your Client ID and Client Secret (from step 3)
- Close settings
- In the scope input (Step 1), enter
https://mail.google.com/? Authorize APIs - Sign in with the Gmail account ? grant access
- Click Exchange authorization code for tokens (Step 2)
- Copy the
refresh_tokenvalue from the response - Set
OAuth2RefreshTokeninappsettings.Secrets.json
?? The refresh token must be obtained using your own client credentials in Playground settings. If obtained with Playground's default credentials, it will not work with your client secret.
?? Google refresh tokens expire if unused for 6 months, or if the user revokes access. The token must be re-obtained if
invalid_grantis returned.
Microsoft 365 / Exchange Online (Azure AD)
Microsoft uses application-level OAuth2 (client credentials flow — no user interaction required).
Required fields
{
"UseOAuth2": true,
"OAuth2ClientId": "YOUR_APP_CLIENT_ID",
"OAuth2ClientSecret": "YOUR_APP_CLIENT_SECRET_VALUE",
"OAuth2TenantId": "yourorg.onmicrosoft.com",
"OAuth2Provider": 1
}
Setup
- Go to portal.azure.com ? Azure Active Directory ? App registrations ? + New registration.
- Go to Certificates & secrets ? + New client secret ? copy the Value (not the ID).
- Set this as
OAuth2ClientSecret.
- Set this as
- Go to API permissions ? + Add a permission ? APIs my organization uses ? Office 365 Exchange Online:
- Add Application permissions:
IMAP.AccessAsApp,SMTP.SendAsApp,POP.AccessAsApp - Click Grant admin consent
- Add Application permissions:
- In Exchange Online PowerShell, register the service principal for the mailbox:
New-ServicePrincipal -AppId <ClientId> -ServiceId <ObjectId> -DisplayName "MessagingService" Add-MailboxPermission -Identity "user@yourorg.onmicrosoft.com" -User <ObjectId> -AccessRights FullAccess - Set
OAuth2TenantIdto the full domain (e.g.yourorg.onmicrosoft.com) or tenant GUID.
??
OAuth2ClientSecretmust be the Value shown at secret creation time, not the Secret ID (GUID). The value is only visible once — if lost, create a new secret.
??
OAuth2TenantIdmust be a full domain (yourorg.onmicrosoft.com), a tenant GUID, orcommon. Short names likeyourorgare not valid and will causeAADSTS900023.