Skip to main content

Notifications & Messages

NeoMind's message system routes device alerts, rule triggers, AI Agent analysis results, and system events to the channels you configure. Every message lands in the in-app notification center first, then fans out to your enabled external channels. It supports 7 external message channels (Webhook, Email, Telegram, WeCom, DingTalk, Slack, Feishu) with simultaneous multi-channel fan-out and per-channel message filtering.

The message system lives under Messages (bell icon) in the left nav. Two tabs: Messages (notification center, browse alert history) and Channels (channel configuration).

Supported Channels

ChannelTypeUse CaseAuthDisable
WebhookGeneric HTTPForward to any HTTP endpoint (custom systems, IFTTT, n8n, AlertManager); the UI can configure auth headers for the endpointURL + 5 auth types (configured in UI, converted to headers)Yes
EmailSMTPStandard email notificationsSMTP username / passwordYes
TelegramBot APIReal-time alerts for global teamsBot TokenYes
WeComGroup BotChina enterprise collaborationGroup Bot Webhook KeyYes
DingTalkCustom BotChina enterprise collaborationAccess Token + signingYes
SlackIncoming WebhookInternational team collaborationWebhook URLYes
FeishuCustom BotChina enterprise collaborationHook ID + signingYes
note

NeoMind does not support SMS. For SMS alerts, use a Webhook channel to bridge to a third-party SMS gateway (e.g. Twilio, Alibaba Cloud SMS).

Interface Overview

Messages Tab (Notification Center)

Open the Messages page — the default view is the notification center:

Messages list — severity, status, category, source, actions

Each message contains:

FieldDescription
Severityinfo / warning / critical / emergency (color coded light → dark)
TitleMessage title
BodyMessage content (click row to expand full content)
Categoryalert / system / business / notification + backend-extensible arbitrary categories
SourceTriggering source: device / rule / telemetry / schedule / llm / system
Statusactive / acknowledged / resolved / archived
TimeCreated and last-updated timestamps
ActionsAcknowledge / Resolve / Archive / Delete

Filtering: Click Filter in the toolbar to open the filter Popover. Filter by severity (multi-select), status (multi-select), and category (multi-select). Active filters appear as chips in the toolbar.

Channels Tab (Channel Management)

Switch to the Channels tab to see all channels:

Channels list — name, type, status, stats, actions

The top shows summary cards (Total channels / Enabled / Channel type count). Below is the channel list. Each channel card shows:

  • Name + type icon: Channel identity
  • Enable switch: Toggle channel on/off in one click
  • Test button: Inline test result (success / failure + reason)
  • Action menu: View / Edit / Configure Filter / Manage Recipients (Email only) / Enable | Disable / Delete

Configuring a Channel

Click Create to open the full-screen channel editor:

Channel editor — left sidebar type picker, right config form (Webhook selected by default)

The editor uses a split-pane layout:

  • Left sidebar: Lists the 7 channel types; click to switch
  • Right form: Shows config fields for the selected type

Channels only handle external forwarding. Regardless of channels, every message is kept in the in-app notification center (Messages tab), viewable via the top-right bell icon in the Web UI.

Common Fields

All external channels need:

FieldDescription
NameUnique identifier used by rules and Agents. Use lowercase-hyphenated names (e.g. ops-feishu)
EnabledWhether the channel is active. Disabled channels receive no messages

Webhook Channel

The most flexible channel — bridges to any HTTP endpoint.

Webhook channel config — URL, method, auth type, timeout
FieldDescriptionExample
URLHTTP(S) endpoint receiving messages; NeoMind pushes via POSThttps://api.example.com/alerts
AuthenticationAuth type: none / bearer / basic / apikey / customSee table below
HeadersCustom request headers (used with custom auth){"X-Tenant": "factory1"}
Timeout (secs)HTTP timeout, default 30, max 30030

Auth types in detail (UI-level settings, converted to HTTP headers on save):

TypeExtra FieldsUse Case
noneNonePublic endpoints, intranet without auth
bearerBearer TokenOAuth 2.0, JWT
basicUsername + PasswordHTTP Basic Auth
apikeyAPI Key + Header Name (default X-API-Key)Third-party API gateways
customCustom Headers key-value tableCustom signatures, multi-header combos

Email Channel

Email channel config — SMTP server, port, from address, auth
FieldDescriptionExample
SMTP ServerSMTP server hostsmtp.gmail.com
SMTP PortPort (default 587, STARTTLS)465 (SSL) / 587 (STARTTLS)
UsernameSMTP login usernamealert@example.com
PasswordSMTP password or app-specific password••••••••
From AddressSender address (usually same as Username)alert@example.com
Recipients are managed separately

After saving the Email channel, use Manage Recipients in the channel action menu to add/remove recipient addresses — no need to reopen the channel editor.

Telegram Channel

Telegram channel config — Bot Token, Chat ID
FieldDescriptionHow to Get
Bot TokenTelegram Bot access tokenCreate a Bot via @BotFather, format 123456:ABC-DEF...
Chat IDConversation ID receiving messages (group or DM)Add the Bot to a group, then visit https://api.telegram.org/bot<TOKEN>/getUpdates to read it

DM Chat IDs are pure numbers (your user ID). Group Chat IDs typically start with - (e.g. -1001234567890).

WeCom Channel

FieldDescriptionHow to Get
KeyThe key portion of the group bot Webhook URL (not the full URL)Group Settings → Add Group Bot → copy Webhook URL, take the value after key=

NeoMind internally reconstructs https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=<KEY>, so fill in only the Key.

DingTalk Channel

FieldDescriptionHow to Get
Access TokenThe access_token portion of the group bot Webhook URLGroup Settings → Smart Group Assistant → Add Custom Bot → copy Webhook URL, take the value after access_token=
Secret (optional)Signing secretBot security settings → choose "Sign" → copy the Secret. Strongly recommended — otherwise the bot can be invoked maliciously
note

When signing is enabled, NeoMind computes an HMAC-SHA256 signature and appends timestamp and sign to the URL per DingTalk protocol.

Slack Channel

FieldDescriptionHow to Get
Webhook URLFull Slack Incoming Webhook URLhttps://api.slack.com/apps → Create New App → Incoming Webhooks → enable → copy URL

URL format: https://hooks.slack.com/services/T000/B000/XXXX.

Feishu Channel

FieldDescriptionHow to Get
Hook IDThe hook_id portion of the bot Webhook URL (not the full URL)Group Settings → Group Bots → Add Custom Bot → copy Webhook URL, take the UUID after open.feishu.cn/open-apis/bot/v2/hook/
Secret (optional)Signing secretBot security settings → choose "Signature Verification" → copy the Secret
note

When signing is enabled, NeoMind computes timestamp and sign fields per Feishu protocol and includes them in the request body.

Testing a Channel

After saving, click Test in the channel list. NeoMind sends a test message and shows the result inline:

  • ✅ Success: HTTP status code or channel response
  • ❌ Failure: Error reason (connection timeout, auth failed, Chat ID not found, etc.)

Always Test before enabling in production to avoid silent alert failures.

Channel Filters

Each channel can have its own message filter deciding which messages get forwarded. Click Configure Filter in the channel action menu to open the filter dialog:

Channel filter config — source types, categories, minimum severity

Filters have three groups:

1. Source Types

Multi-select, deciding which triggering sources get forwarded:

SourceDescription
deviceDevice events (online / offline / data anomaly)
ruleRule engine triggers
telemetryTelemetry threshold alerts
scheduleScheduled task triggers
llmAI Agent / Chat triggers
systemSystem events (extension crashes, storage alerts)

Empty = receive all sources (default).

2. Categories

Multi-select message categories:

  • alert — Alerts (device anomaly, threshold breach)
  • system — System (service status, extension events)
  • business — Business (orders, workflows)
  • notification — General notifications

Empty = receive all categories (default). The backend can extend with custom categories which will also appear here.

3. Minimum Severity

Single-select dropdown, filtering out messages below the chosen level:

ValueSeverities Received
(empty)All (info / warning / critical / emergency)
infoAll
warningwarning / critical / emergency
criticalcritical / emergency
emergencyemergency only

Typical usage:

  • Email channel: min warning (filter out info noise)
  • Feishu / DingTalk group: min critical (only important alerts)
  • Webhook → monitoring dashboard: All (preserve full data)
No filter configured = receive all messages

Newly created rule notifications enter all enabled channels by default; use filters for tiered routing.

Triggering Notifications

Messages don't appear in isolation — they are triggered by other modules:

1. Rule Engine (Most Common)

Configure a notify action in an Automation Rule:

{ "type": "notify", "message": "sensor-01 temperature {value}°C exceeded threshold 30°C", "severity": "critical" }

For the complete rule structure, see Automation Rules.

A notify action generates a message that enters all enabled channels — each channel's filter then decides whether to forward. So after creating a rule, make sure to configure filters on the channels that should carry it.

2. AI Agent

Let an AI Agent decide whether to notify after analysis:

  • Free-mode Agent: Write in the prompt "notify the ops group via email when an anomaly is detected" — the Agent calls the message tool
  • Focused-mode Agent: Automatically decides whether data is anomalous and triggers alerts

3. AI Chat (Manual)

Just say in Chat: "Send a Feishu message to the group telling them device 3 is offline" — the LLM invokes the message tool.

4. System Events

Some system events (device offline, extension crash-loop stop, low storage) automatically enter the notification center and are forwarded per each channel's filter.

Message Lifecycle

Messages have 4 statuses forming a complete handling workflow:

active → acknowledged → resolved → archived
StatusDescriptionAction
ActiveNew message, pending handlingAutomatic
AcknowledgedOps staff have seen it and are working on itClick Acknowledge
ResolvedIssue fixedClick Resolve
ArchivedArchived, no longer activeClick Archive

Actions:

  • Single message: click the corresponding button on the message row
  • Bulk: filter a batch via the filter Popover, then bulk-act
  • Delete: Delete removes from the database (irreversible — prefer Archive)

CLI Management

The NeoMind CLI provides message subcommands for managing messages and channels:

# List the last 20 messages (filter with --severity / --status)
neomind message list --limit 20

# View message details
neomind message get <message_id>

# Send a system message (for testing the delivery pipeline)
neomind message send --title "Test Alert" --body "Manually created test message" --severity warning

# Acknowledge (mark as read) / delete messages
neomind message read <message_id>
neomind message delete <message_id>

# List all channels
neomind message channel-list

# View channel types and each type's config fields
neomind message channel-types
neomind message channel-type-schema feishu

# Create a channel (--config takes the full JSON, or use repeatable --param k=v)
neomind message channel-create --name ops-feishu --type feishu \
--config '{"hook_id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","secret":"secxxxxxxxx"}'

# Update a channel (modify config / enable-disable, etc.)
neomind message channel-update --name ops-feishu --config '{"enabled":false}'

# Test a channel (send a test message)
neomind message channel-test ops-feishu

# Delete a channel
neomind message channel-delete ops-feishu

Message templates support {value} and {source_id} interpolation; channel filters (by source / category / minimum severity) are configured in the channel edit panel of the Web UI.

REST API

All features are accessible via HTTP API (default port 9375):

Full REST API example
# List messages
curl http://localhost:9375/api/messages?limit=20 \
-H "X-API-Key: $NEOMIND_API_KEY"

# Create a message
curl -X POST http://localhost:9375/api/messages \
-H "X-API-Key: $NEOMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "High Temperature Alert",
"message": "sensor-01 temperature 35°C exceeds threshold",
"severity": "critical",
"category": "alert",
"source_type": "rule"
}'

# List channels
curl http://localhost:9375/api/messages/channels \
-H "X-API-Key: $NEOMIND_API_KEY"

# Create a channel (name + channel_type + config fields, all flat in one object)
curl -X POST http://localhost:9375/api/messages/channels \
-H "X-API-Key: $NEOMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "ops-webhook",
"channel_type": "webhook",
"url": "https://api.example.com/alerts",
"headers": {"Authorization": "Bearer xxx"},
"timeout_secs": 30,
"enabled": true
}'

# Update a channel
curl -X PUT http://localhost:9375/api/messages/channels/ops-webhook \
-H "X-API-Key: $NEOMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"config": {"url": "https://api.example.com/alerts", "enabled": false}}'

# Test a channel
curl -X POST http://localhost:9375/api/messages/channels/ops-webhook/test \
-H "X-API-Key: $NEOMIND_API_KEY"

# Enable / disable
curl -X PUT http://localhost:9375/api/messages/channels/ops-webhook/enabled \
-H "X-API-Key: $NEOMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"enabled": false}'

# Configure filter
curl -X PUT http://localhost:9375/api/messages/channels/ops-webhook/filter \
-H "X-API-Key: $NEOMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"source_types": ["rule"],
"categories": ["alert"],
"min_severity": "warning"
}'

# View filter
curl http://localhost:9375/api/messages/channels/ops-webhook/filter \
-H "X-API-Key: $NEOMIND_API_KEY"

# Email recipients management (one recipient per call)
curl -X POST http://localhost:9375/api/messages/channels/ops-email/recipients \
-H "X-API-Key: $NEOMIND_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email": "ops@example.com"}'

curl http://localhost:9375/api/messages/channels/ops-email/recipients \
-H "X-API-Key: $NEOMIND_API_KEY"

# Remove a recipient
curl -X DELETE http://localhost:9375/api/messages/channels/ops-email/recipients/ops@example.com \
-H "X-API-Key: $NEOMIND_API_KEY"

# Change message status
curl -X POST http://localhost:9375/api/messages/<message_id>/acknowledge \
-H "X-API-Key: $NEOMIND_API_KEY"

# Delete a channel
curl -X DELETE http://localhost:9375/api/messages/channels/ops-webhook \
-H "X-API-Key: $NEOMIND_API_KEY"

Sending & Dedup

Once created, a message is permanently stored in the notification center; it is then sent once to each enabled channel (after passing that channel's filter):

  • No automatic retry: A channel send failure (timeout, auth failure, target error) is only logged and not retried automatically. Use Test on the channel to verify connectivity. For data forwarding with retry semantics, use Data Push (exponential-backoff retries and delivery history).
  • Dedup window: Messages with the same (title, source, severity) are sent to channels at most once per 60-second window, preventing notification storms from high-frequency rule triggers; the message itself still appears in the notification center.
  • Semantic error detection: Channel tests inspect the response body (e.g. Feishu/DingTalk code != 0, Telegram ok: false) — HTTP 200 with a semantic failure counts as a failure.

Typical Scenarios

Scenario 1: Multi-Channel Redundancy for Critical Alerts

  • Email channel: filter min_severity = critical, recipients oncall@example.com
  • Feishu channel: filter min_severity = critical, signing enabled
  • Webhook channel: forward to AlertManager for secondary routing

When a critical alert fires, all three channels receive it — no missed alerts on single-point failure.

Scenario 2: Tiered Notifications

ChannelFilterUse Case
Emailmin_severity = warningOps mailing list
Feishumin_severity = critical24/7 ops group
Slacksource_types = ["llm"]Agent analysis channel
Webhookcategories = ["alert"]Forward to monitoring dashboard

Scenario 3: In-App Only (Silent)

  • Create no external channels; all messages default to the in-app notification center
  • Check history via the top-right bell icon in the Web UI
  • Suitable for dev / test environments

Best Practices

  • Test before enabling: After creating a channel, always test to catch config errors before they silently swallow alerts
  • Multi-channel redundancy for critical alerts: Configure both email + Feishu / DingTalk to avoid single-point failure
  • Tiered filtering: Use channel filters for severity-based routing — Info goes only to in-app, Critical fans out to email / group notifications
  • Enable signing: DingTalk and Feishu bots should always enable signing to prevent malicious calls if the URL leaks
  • Sensible dedup: Set cooldown in rules to prevent sensor jitter storms; the message system's built-in 60-second dedup window provides a safety net
  • Manage recipients separately: Use Manage Recipients for Email channel add/remove — no need to reopen the channel editor
  • Bridge via Webhook for unified alerting: Point a Webhook channel at AlertManager, Home Assistant, n8n, etc., and let the platform handle secondary routing and silencing rules

Integration with Other Modules

ModuleDescription
Automation Rulesnotify action triggers a message routed by channel filters
AI AgentAgent invokes the message tool after analysis
Device ManagementDevice online / offline / data anomalies trigger messages automatically
ExtensionsExtension crashes and other system events enter the notification center
Data PushData Push handles data streams; the message system handles alert streams

Last updated: 2026-09-08