feat: Discord/Slack/ntfy/Matrix targets, command templates, delete protection, email/matrix bots

- Discord, Slack, ntfy, Matrix notification target types with clients and dispatch
- MatrixBot model + API + frontend in Bots tab
- Command template system fully wired into all handler commands
- Default command templates seeded (EN/RU, 14 slots each)
- Command template editor with variables reference including child fields
- Delete protection on all 10 entity types (409 with consumer details)
- Provider type selector on template config forms
- Target type selector as dropdown with all 7 types
- Response template selector on command config form
- CLAUDE.md: mandatory server restart rule, child properties rule
This commit is contained in:
2026-03-21 20:36:12 +03:00
parent 846d480d38
commit 3e3a6f0777
64 changed files with 1861 additions and 180 deletions
@@ -31,13 +31,17 @@ class ReceiverUpdate(BaseModel):
def _receiver_key(target_type: str, config: dict[str, Any]) -> str:
"""Derive a unique key for deduplication from receiver config."""
if target_type == "telegram":
return str(config.get("chat_id", ""))
elif target_type == "webhook":
return config.get("url", "")
elif target_type == "email":
return config.get("email", "")
return ""
key_fields = {
"telegram": "chat_id",
"webhook": "url",
"email": "email",
"discord": "webhook_url",
"slack": "webhook_url",
"ntfy": "topic",
"matrix": "room_id",
}
field = key_fields.get(target_type, "")
return str(config.get(field, "")) if field else ""
@router.get("")