Hermes supports sending notifications to 4 external providers. Each notification has configured in the database which providers should receive it. The platform dispatches asynchronously and independently to each enabled provider.
|
Provider |
Type |
Mechanism |
|---|---|---|
|
|
|
JavaMailSender (SMTP) |
|
Google Chat |
Corporate messaging |
Webhook HTTP |
|
Slack |
Team messaging |
Webhook HTTP |
|
Microsoft Teams |
Corporate messaging |
Power Automate Webhook |
1. Configuration in application.yaml
1.1 Google Chat
anjana:
messaging:
google-chat:
webhook-url: https://chat.googleapis.com/v1/spaces/XXXXXXXXX/messages?key=YYYYYYY&token=ZZZZZZZ
How to obtain the Webhook URL:
-
Open the target Google Chat Space
-
Click on the Space name → Apps & integrations
-
Add webhooks → Assign a name → Save
-
Copy the generated URL (includes
keyandtokenas query parameters)
1.2 Slack
anjana:
messaging:
slack:
webhook-url: https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXX
How to obtain the Webhook URL:
-
Go to api.slack.com/apps → Create New App
-
Incoming Webhooks → Enable → Add New Webhook to Workspace
-
Select the target channel → Allow
-
Copy the generated Webhook URL
1.3 Microsoft Teams
anjana:
messaging:
teams:
webhook-url: https://TENANT.webhook.office.com/webhookb2/XXXXXXXX@YYYYYYYY/IncomingWebhook/ZZZZZZZZ/WWWWWWWW
Important note: Teams has deprecated Office 365 Connectors. It is mandatory to use Power Automate with the "Post to a channel when a webhook request is received" connector.
How to configure with Power Automate:
-
In Teams, go to the target channel → ... → Workflows
-
Search for "Post to a channel when a webhook request is received" → Add workflow
-
Name the flow → Next → copy the generated webhook URL
1.4 Email (SMTP)
spring:
mail:
host: smtp.example.com
port: 587
username: notifications@example.com
password: ${MAIL_PASSWORD}
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true
from: notifications@anjanadata.com
1.5 HTTP Timeouts (all webhook providers)
anjana:
messaging:
connectTimeoutSeconds: 10 # Maximum time to establish connection
readTimeoutSeconds: 30 # Maximum time waiting for response
writeTimeoutSeconds: 10 # Maximum time sending the request
1.6 Full configuration example
anjana:
messaging:
connectTimeoutSeconds: 10
readTimeoutSeconds: 30
writeTimeoutSeconds: 10
google-chat:
webhook-url: https://chat.googleapis.com/v1/spaces/XXXXXXXXX/messages?key=YYYYYYY&token=ZZZZZZZ
slack:
webhook-url: https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXX
teams:
webhook-url: https://TENANT.webhook.office.com/webhookb2/XXXXXXXX/IncomingWebhook/ZZZZZZZZ
spring:
mail:
host: smtp.gmail.com
port: 587
username: notifications@anjanadata.com
password: ${MAIL_PASSWORD}
properties:
mail.smtp.auth: true
mail.smtp.starttls.enable: true
mail:
from: notifications@anjanadata.com
2. Database Configuration
The external_sending field of the hermes.notification table controls which providers receive each type of notification. It is a comma-separated list of values.
2.1 Possible values
|
Value |
Provider |
|---|---|
|
|
|
|
|
Slack |
|
|
Microsoft Teams |
|
|
Google Chat |
2.2 Query current configuration
SELECT
notification_code,
subject,
severity,
external_sending
FROM hermes.notification
ORDER BY notification_code;
3. Format of sent messages
Each provider receives the message in a specific format automatically generated by Hermes. The subject and body are resolved via the translation keys (translation_key) configured in each notification, in all languages active on the platform.
3.1 Google Chat
{
"text": "Notification subject
Full notification body"
}
3.2 Slack
{
"text": "**Notification subject**
Full notification body"
}
3.3 Microsoft Teams (Adaptive Card)
{
"type": "message",
"attachments": [{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.2",
"body": [
{ "type": "TextBlock", "text": "Notification subject", "weight": "Bolder" },
{ "type": "TextBlock", "text": "Notification body", "wrap": true }
]
}
}]
}
3.4 Email
HTML email sent to the recipients configured in the notification, with the body built in all languages active in the installation.
4. Asynchronous execution pools
Each provider uses its own thread pool so as not to block the main thread. They are configurable in application.yaml:
anjana:
hermes:
mail-pool:
pool-size: 5
core-pool-size: 2
queue-capacity: 100
slack-pool:
pool-size: 3
core-pool-size: 1
queue-capacity: 50
teams-pool:
pool-size: 3
core-pool-size: 1
queue-capacity: 50
google-chat-pool:
pool-size: 3
core-pool-size: 1
queue-capacity: 50
|
Parameter |
Description |
|---|---|
|
|
Maximum number of concurrent threads for that provider |
|
|
Threads always active (even if there are no messages) |
|
|
Messages queued before starting to reject |
5. Sending flow
Workflow event (task created, assigned, completed...)
↓
NotificationService.dispatchToProviders()
↓
For each provider configured in external_sending:
├── EMAIL → EmailService (mailPoolTaskExecutor)
├── SLACK → SlackService (slackPoolTaskExecutor)
├── MICROSOFT_TEAMS → TeamsService (teamsPoolTaskExecutor)
└── GOOGLE_CHAT → GoogleChatService (googleChatPoolTaskExecutor)
↓
POST webhook / SMTP send
The providers are invoked in parallel and asynchronously, so a failure in one provider does not block or affect the others.
6. Verification and troubleshooting
6.1 Verify connectivity with curl
# Google Chat
curl -X POST \
"https://chat.googleapis.com/v1/spaces/XXXXXXXXX/messages?key=YYYYYYY&token=ZZZZZZZ" \
-H "Content-Type: application/json" \
-d '{"text": "Connectivity test from Anjana Data"}'
# Slack
curl -X POST https://hooks.slack.com/services/T00000000/B00000000/XXXX \
-H "Content-Type: application/json" \
-d '{"text": "Connectivity test from Anjana Data"}'
6.2 Relevant logs in Hermes
The services log errors at ERROR level when sending fails:
ERROR c.a.h.googlechat.service.GoogleChatService - Error sending message to Google Chat
ERROR c.a.h.slack.service.SlackService - Error sending message to Slack
ERROR c.a.h.teams.service.TeamsService - Error sending message to Teams
ERROR c.a.h.email.service.EmailService - Error sending email notification
6.3 Common issues
|
Symptom |
Probable cause |
Solution |
|---|---|---|
|
Messages are not arriving in Google Chat |
Webhook URL expired or incorrect |
Regenerate the webhook in the Google Chat Space |
|
401 error in Slack |
Token revoked |
Recreate the app/webhook in Slack |
|
Teams is not receiving messages |
Office 365 Connectors connector deprecated |
Migrate to Power Automate |
|
Timeout on send |
|
Increase the value (recommended: 30s) |
|
Field |
Notification with no providers configured |
Update it in the Administration Panel with the desired providers |
|
Duplicate messages |
Pool misconfigured with multiple workers |
Check |
Product Team · Anjana Data