Notifications
Notifications deliver query results to recipients via Email, Microsoft Teams, or Jira.
Purpose
Notifications allow you to:
- Deliver query results automatically
- Support multiple delivery channels (Email, Teams, Jira)
- Format results as tables or CSV attachments
- Track delivery status and history
- Handle delivery failures gracefully
Notification Channels
Semantico supports three notification channels:
| Channel | Format | Use Case |
|---|---|---|
| HTML table + CSV attachment with full results | Scheduled reports, data exports, stakeholder delivery | |
| Microsoft Teams | Adaptive card with formatted table | Real-time alerts, team collaboration |
| Slack | Rich Table Blocks with 20 columns, 100 rows | Real-time alerts, team collaboration, superior table formatting |
| Jira | Issue creation with results | Incident tracking, workflow integration |
Reporting Feature: Email is the only channel that delivers complete query results as attachments. This makes it perfect for scheduled reporting where stakeholders need full datasets for analysis in Excel or other tools.
Email Notifications
Prerequisites
Email notifications require implementing IEmailAdapter in your application:
using Semantico.Core.Adapters.Mail;
public class SmtpEmailAdapter : IEmailAdapter
{
public async Task SendEmailAsync(string to, string subject, string body, QueryResultFile? queryResultAttachmentFile)
{
// Implement using your email provider
// (SMTP, SendGrid, AWS SES, etc.)
}
}
Register in your Program.cs:
builder.Services.AddSemantico(builder.Configuration, options =>
{
options.UsePostgreSql(builder.Configuration.GetConnectionString("SemanticoContext")!, "semantico");
options.AddSemanticoScheduler<YourScheduler>();
options.AddEmailAdapter<SmtpEmailAdapter>();
});
π See complete email adapter implementation β
Email Format
Emails include:
- Subject: Query name and execution timestamp
- Body:
- Query description
- Execution summary (rows returned, execution time)
- Results formatted as HTML table (first 20 rows)
- Link to execution history
- Attachment: CSV file with FULL results (regardless of row count)
Powerful Reporting Feature: Email attachments contain the complete query result set, making Semantico perfect for scheduled reports. Recipients can open the CSV directly in Excel for analysis.
Example email:
Subject: Daily User Count Report - 2025-10-22 09:00:00
Semantico Query Execution
Query: Daily Active Users
Description: Count of users active in last 24 hours
Executed: 2025-10-22 09:00:15
Execution Time: 0.34 seconds
Rows Returned: 1
Results:
+---------------+
| active_users |
+---------------+
| 1,247 |
+---------------+
View full execution history:
https://your-semantico-instance/notifications/12345
---
Sent by Semantico
Creating Email Recipient
- Navigate to Recipients β Create New Recipient
- Fill in details:
- Name:
DevOps Team - Type: Email
- Email Address:
devops@yourdomain.com
- Name:
- Click Save
Adding to Subscription
- Open your subscription
- In Recipients section, click Add Recipient
- Select your email recipient
- Click Save
Microsoft Teams Notifications
Prerequisites
Teams notifications require a webhook URL from your Teams channel.
Getting Teams Webhook URL
- Open your Teams channel
- Click β¦ (More options) next to channel name
- Select Connectors
- Search for Incoming Webhook
- Click Configure
- Enter webhook details:
- Name:
Semantico Alerts - Upload Image: (optional, Semantico logo)
- Name:
- Click Create
- Copy the webhook URL (youβll need this)
- Click Done
Teams Card Format
Teams notifications use Adaptive Cards with:
- Header: Query name and icon
- Summary: Execution details
- Results Table: Formatted data (up to 20 rows)
- Actions: βView Query Resultsβ button linking to notification details (when BaseUrl is configured)
Example Teams card:
βββββββββββββββββββββββββββββββββββββββ
β π Daily Active Users β
βββββββββββββββββββββββββββββββββββββββ€
β Executed: 2025-10-22 09:00:15 β
β Execution Time: 0.34s β
β Rows: 1 β
β β
β Results: β
β ββββββββββββββββββ β
β β active_users β β
β ββββββββββββββββββ€ β
β β 1,247 β β
β ββββββββββββββββββ β
β β
β [View Full History β] β
βββββββββββββββββββββββββββββββββββββββ
Creating Teams Recipient
- Navigate to Recipients β Create New Recipient
- Fill in details:
- Name:
Alerts Channel - Type: Teams
- Webhook URL: Paste your webhook URL
- Name:
- Click Test Webhook to verify
- Click Save
Configuring Clickable Links in Teams Notifications
To enable the βView Query Resultsβ button in Teams notifications, configure the BaseUrl setting in your application:
builder.Services.AddSemantico(builder.Configuration, options =>
{
options.UsePostgreSql(builder.Configuration.GetConnectionString("SemanticoContext")!, "semantico");
options.AddSemanticoScheduler<YourScheduler>();
// Set your Semantico UI base URL
options.BaseUrl = "https://yourdomain.com/semantico";
});
Or from appsettings.json:
{
"Semantico": {
"BaseUrl": "https://yourdomain.com/semantico"
}
}
builder.Services.AddSemantico(builder.Configuration, options =>
{
options.UsePostgreSql(builder.Configuration.GetConnectionString("SemanticoContext")!, "semantico");
options.AddSemanticoScheduler<YourScheduler>();
options.BaseUrl = builder.Configuration["Semantico:BaseUrl"];
});
When configured, Teams notifications will include a button that links to:
https://yourdomain.com/semantico/notifications/details/{notificationId}
This allows recipients to:
- View complete query results (not just first 20 rows)
- See execution metrics and history
- Access full notification details
- Explore related query executions
If
BaseUrlis not configured, Teams notifications are still sent but without the clickable button. The notification will contain the results table as usual.
π Learn more about BaseUrl configuration β
Testing Teams Webhook
Send a test message:
curl -X POST 'https://outlook.office.com/webhook/...' \
-H 'Content-Type: application/json' \
-d '{
"@type": "MessageCard",
"text": "Test from Semantico"
}'
You should see the message in your Teams channel immediately.
Slack Notifications
Prerequisites
Slack notifications require a webhook URL from your Slack workspace.
Getting Slack Webhook URL
- Go to https://api.slack.com/apps
- Click Create New App β From scratch
- Enter app details:
- App Name:
Semantico Alerts - Pick a workspace: Select your workspace
- App Name:
- Click Create App
- In the app settings, select Incoming Webhooks from the left menu
- Toggle Activate Incoming Webhooks to On
- Click Add New Webhook to Workspace
- Select the channel where notifications should be posted
- Click Allow
- Copy the Webhook URL (format:
https://hooks.slack.com/services/T00000000/B00000000/XXXX...)
Keep your webhook URL secure. Anyone with this URL can post messages to your Slack channel.
Slack Message Format
Slack notifications use Block Kit with superior table formatting:
- Header: Query name with professional styling
- Query Display (optional): SQL query in code block with syntax highlighting
- Summary: βShowing X of Y total recordsβ
- Results Table: Rich formatted table with:
- Up to 20 columns (vs Teamsβ 3-column limit)
- Up to 100 rows (vs Teamsβ 10-row limit)
- Bold headers using rich text formatting
- Smart column alignment: Numbers right-aligned, dates center-aligned, text left-aligned
- Configurable text wrapping: Enabled for long text, disabled for compact data
- Actions: βView Full Resultsβ button linking to notification details (when BaseUrl is configured)
Example Slack message:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β [Semantico] Production DB - Daily Sales Report β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Query: β
β ```sql β
β SELECT product_name, category, quantity, β
β revenue, created_at β
β FROM sales WHERE date = CURRENT_DATE β
β ORDER BY revenue DESC β
β ``` β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Results: Showing 10 of 247 total records β
β β
β ββββββββββββββ¬βββββββββββ¬βββββββββ¬βββββββββββ¬ββ...β
β β Product β Category β Qty β Revenue β ... β
β ββββββββββββββΌβββββββββββΌβββββββββΌβββββββββββΌββ...β
β β Widget Pro β Hardware β 342 β $12,456 β ... β
β β Gadget X β Hardware β 198 β $8,234 β ... β
β β Service Y β Software β 89 β $5,672 β ... β
β ββββββββββββββ΄βββββββββββ΄βββββββββ΄βββββββββββ΄ββ...β
β β
β [View Full Results β] β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Slack vs Teams Comparison
Slack provides significantly better table formatting than Teams:
| Feature | Microsoft Teams | Slack |
|---|---|---|
| Max Columns | 3 (self-imposed limit) | 20 |
| Max Rows | 10 (truncated) | 100 |
| Header Formatting | Basic bold text | Rich text with bold style |
| Column Alignment | Limited | Full control (left/center/right) |
| Text Wrapping | Always enabled | Configurable per column |
| Cell Formatting | Plain text only | Rich text with links, emoji |
Superior Table Display: Slackβs Table Block feature provides much better formatting for query results with wide tables or many rows. Consider using Slack for data-heavy notifications.
Creating Slack Recipient
- Navigate to Recipients β Create New Recipient
- Fill in details:
- Name:
Alerts Channel - Type: Slack
- Webhook URL: Paste your webhook URL
- Name:
- Click Save
Configuring Clickable Links in Slack Notifications
To enable the βView Full Resultsβ button in Slack notifications, configure the BaseUrl setting in your application:
builder.Services.AddSemantico(builder.Configuration, options =>
{
options.UsePostgreSql(builder.Configuration.GetConnectionString("SemanticoContext")!, "semantico");
options.AddSemanticoScheduler<YourScheduler>();
// Set your Semantico UI base URL
options.BaseUrl = "https://yourdomain.com/semantico";
});
Or from appsettings.json:
{
"Semantico": {
"BaseUrl": "https://yourdomain.com/semantico"
}
}
When configured, Slack notifications will include a button that links to:
https://yourdomain.com/semantico/notifications/{notificationId}
This allows recipients to:
- View complete query results (not just first 100 rows)
- See execution metrics and history
- Access full notification details
- Explore related query executions
If
BaseUrlis not configured, Slack notifications are still sent but without the clickable button. The notification will contain the results table as usual.
Testing Slack Webhook
Send a test message:
curl -X POST 'https://hooks.slack.com/services/T00000000/B00000000/XXXX...' \
-H 'Content-Type: application/json' \
-d '{
"text": "Test from Semantico",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": "This is a test notification from *Semantico*"
}
}
]
}'
You should see the message in your Slack channel immediately.
Advanced Table Features
Slack automatically handles:
- Smart data type detection: Numbers, dates, booleans, and text are detected and formatted appropriately
- Automatic alignment: Numbers right-aligned, dates center-aligned, text left-aligned
- Text wrapping: Long text automatically wraps within cells
- Date formatting: Dates displayed as YYYY-MM-DD HH:mm:ss
- Boolean display: True/False shown as Yes/No
Jira Notifications
Prerequisites
Jira notifications require:
- Jira Cloud or Server instance
- API token or credentials
- Project key and issue type
Creating Jira Recipient
- Navigate to Recipients β Create New Recipient
- Fill in details:
- Name:
Production Incidents - Type: Jira
- Jira Configuration: Enter details
- Instance URL:
https://yourcompany.atlassian.net - Project Key:
OPS - Issue Type:
Incident - API Token: Your Jira API token
- Instance URL:
- Name:
- Click Test Connection
- Click Save
Jira Issue Format
Issues created include:
- Summary: Query name and timestamp
- Description: Query results formatted as table
- Labels:
semantico,automated, query name - Priority: Configurable based on result thresholds
Notification History
Viewing History
- Click Notifications in left navigation
- View all notification deliveries with:
- Execution timestamp
- Query executed
- Recipients notified
- Delivery status (Success, Failed)
- Query results
Filtering History
Filter by:
- Subscription: Show only specific subscription
- Date Range: Last 24 hours, week, month, custom
- Status: Success, Failed, All
- Recipient: Deliveries to specific recipient
Notification Details
Click any notification to see:
- Complete query results
- Execution metrics (time, row count)
- Recipient delivery status per channel
- Error messages (if delivery failed)
- Query execution plan
Result Formatting
Table Size Limits
| Channel | Inline Display | Attachment |
|---|---|---|
| 20 rows (HTML table) | CSV with ALL rows (complete dataset) | |
| Teams | 10 rows, 3 columns (adaptive card) | None |
| Slack | 100 rows, 20 columns (table block) | None |
| Jira | 50 rows (issue description) | CSV in description |
Powerful Reporting: Email notifications include a CSV attachment with the complete query result set, regardless of size. This makes Semantico ideal for scheduled reporting - stakeholders receive full datasets they can analyze in Excel without needing database access.
Example: A query returning 5,000 product sales records will show the first 20 rows in the email body, but the CSV attachment will contain all 5,000 rows ready for Excel pivot tables and analysis.
Column Formatting
Results are automatically formatted:
- Numbers: Comma-separated thousands (1,247)
- Dates: ISO 8601 format (2025-10-22)
- Booleans: true/false
- NULL: Displayed as βNULLβ
Custom Formatting
Use SQL to format results:
Format numbers:
SELECT
TO_CHAR(revenue, 'FM$999,999,999.00') as formatted_revenue
FROM sales
Format dates:
SELECT
TO_CHAR(created_at, 'YYYY-MM-DD HH24:MI:SS') as formatted_date
FROM events
Delivery Status
Success
Notification delivered successfully:
- Email: Accepted by email provider (may still bounce)
- Teams: 200 OK response from webhook
- Slack: 200 OK response from webhook
- Jira: Issue created successfully
Failed
Delivery failed with error:
- Email: Invalid recipient, email provider API error
- Teams: Invalid webhook, channel deleted
- Slack: Invalid webhook, channel deleted, webhook revoked
- Jira: Authentication failed, project not found
Common failure reasons:
- Recipient configuration invalid
- External service unavailable
- Authentication expired
- Rate limits exceeded
Retry Behavior
Semantico does NOT automatically retry failed deliveries:
- Check error message in history
- Fix recipient configuration
- Re-execute subscription manually
Design Decision: No retries prevent notification storms and duplicate alerts. Manual re-execution gives control.
Examples
Example 1: Critical Alert to Teams
Use Case: Notify team immediately of production errors
Subscription:
- Name:
Critical Error Alert - Query:
SELECT * FROM errors WHERE severity = 'CRITICAL' AND created_at > NOW() - INTERVAL '5 minutes' - Cron:
*/5 * * * *(every 5 minutes) - Recipients: On-Call Channel (Teams)
Notification:
- Delivered to Teams within seconds
- Team sees alert card with error details
- Can discuss and assign immediately
Example 2: Daily Report via Email with Full Results
Use Case: Send overnight sales report to management with complete data for Excel analysis
Subscription:
- Name:
Daily Sales Report - Query:
SELECT product_name, category, SUM(quantity) as units_sold, SUM(revenue) as total_revenue, AVG(price) as avg_price FROM orders WHERE DATE(created_at) = CURRENT_DATE - 1 GROUP BY product_name, category ORDER BY total_revenue DESC - Cron:
0 7 * * *(every day at 7 AM) - Recipients: Management Team (Email)
Notification:
- HTML table in email body (first 20 rows preview)
- CSV attachment with ALL rows (complete dataset for Excel)
- Recipients can open CSV directly for pivot tables, charts, and analysis
- Professional formatting
Reporting Power: Unlike other alerting tools that only show summaries, Semantico delivers the complete dataset as a CSV attachment. Perfect for stakeholders who need to analyze data in Excel without database access.
Example 3: Incident Creation in Jira
Use Case: Automatically create incidents for database issues
Subscription:
- Name:
Database Health Monitor - Query:
SELECT tablename, pg_size_pretty(size) FROM table_sizes WHERE size > 10GB - Cron:
0 */6 * * *(every 6 hours) - Recipients: DBA Team (Jira)
Notification:
- Creates Jira issue in OPS project
- Issue includes table size details
- Assigned to DBA team queue
- Tracked through resolution
Example 4: Multi-Channel Notification
Use Case: Critical alerts to multiple channels for redundancy
Subscription:
- Name:
System Down Alert - Query:
SELECT COUNT(*) as failures FROM health_checks WHERE status = 'DOWN' - Cron:
*/1 * * * *(every minute) - Recipients:
- On-Call Engineer (Teams)
- DevOps Team (Email)
- Incident Project (Jira)
Purpose: Ensure critical alerts reach team through multiple channels.
Troubleshooting
Emails Not Arriving
Check:
- IEmailAdapter is implemented and registered
- Email adapter configuration is correct (SMTP host, credentials, etc.)
- Recipient email address is correct
- Check spam/junk folder
- Review application logs for email adapter errors
Debug your email adapter:
- Add logging to your
SendEmailAsyncimplementation - Test email sending outside of Semantico
- Verify SMTP credentials and server settings
- Check firewall rules for SMTP ports (usually 587 or 465)
Teams Webhook Not Working
Check:
- Webhook URL is complete and correct
- Teams channel still exists
- Webhook connector not removed
- URL hasnβt expired
Test webhook manually:
curl -X POST 'YOUR_WEBHOOK_URL' \
-H 'Content-Type: application/json' \
-d '{"text": "Test"}'
If this fails, recreate the webhook in Teams.
Jira Issues Not Creating
Check:
- Jira credentials are valid
- Project key exists
- Issue type is valid for project
- API token has necessary permissions
Verify Jira connection:
- Check Jira API token hasnβt expired
- Ensure user has βCreate Issueβ permission
- Verify project key is uppercase
Delivery Shows Success But Not Received
Email:
- Check spam folder
- Verify recipient email address
- Check SendGrid activity for bounces
Teams:
- Verify youβre in the correct Teams channel
- Check Teams notification settings
- Refresh Teams client
Jira:
- Check correct Jira project
- Verify issue type filter
- Refresh Jira board
Related Documentation
- Recipients - Configure notification targets
- Subscriptions - Schedule notifications
- Configuration - SendGrid and webhook setup
- Troubleshooting - Notification delivery issues