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:
@@ -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("")
|
||||
|
||||
Reference in New Issue
Block a user