Files
multi-seal-mail/server/app/mailer/schema/campaign.schema.json

916 lines
21 KiB
JSON

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://multimailer.local/schema/campaign.schema.json",
"title": "MultiMailer Campaign",
"type": "object",
"required": [
"version",
"campaign",
"template",
"entries"
],
"properties": {
"version": {
"type": "string",
"const": "1.0"
},
"campaign": {
"type": "object",
"required": [
"id",
"name"
],
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"mode": {
"type": "string",
"enum": [
"draft",
"test",
"send"
],
"default": "draft"
}
},
"additionalProperties": false
},
"fields": {
"type": "array",
"items": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"string",
"integer",
"double",
"date",
"password"
],
"default": "string"
},
"label": {
"type": "string"
},
"required": {
"type": "boolean",
"default": false
},
"can_override": {
"type": "boolean",
"default": true,
"description": "Whether recipient/entry field values may override the global value for this field."
}
},
"additionalProperties": false
},
"default": []
},
"global_values": {
"type": "object",
"additionalProperties": true,
"default": {}
},
"server": {
"type": "object",
"properties": {
"smtp": {
"type": "object",
"properties": {
"host": {
"type": "string"
},
"port": {
"type": "integer",
"minimum": 1,
"maximum": 65535
},
"username": {
"type": "string"
},
"password": {
"type": "string"
},
"security": {
"type": "string",
"enum": [
"plain",
"tls",
"starttls"
],
"default": "starttls"
},
"timeout_seconds": {
"type": "integer",
"minimum": 1,
"default": 30
}
},
"additionalProperties": false
},
"imap": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"default": false
},
"host": {
"type": "string"
},
"port": {
"type": "integer",
"minimum": 1,
"maximum": 65535
},
"username": {
"type": "string"
},
"password": {
"type": "string"
},
"security": {
"type": "string",
"enum": [
"plain",
"tls",
"starttls"
],
"default": "tls"
},
"sent_folder": {
"type": "string",
"default": "auto"
},
"timeout_seconds": {
"type": "integer",
"minimum": 1,
"default": 30
}
},
"additionalProperties": false
}
},
"additionalProperties": false
},
"recipients": {
"type": "object",
"properties": {
"from": {
"oneOf": [
{
"$ref": "#/$defs/recipient"
},
{
"type": "object",
"maxProperties": 0
},
{
"type": "null"
}
]
},
"allow_individual_from": {
"type": "boolean",
"default": false
},
"to": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"allow_individual_to": {
"type": "boolean",
"default": false
},
"cc": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"allow_individual_cc": {
"type": "boolean",
"default": false
},
"bcc": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"allow_individual_bcc": {
"type": "boolean",
"default": false
},
"reply_to": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"allow_individual_reply_to": {
"type": "boolean",
"default": false
},
"bounce_to": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"allow_individual_bounce_to": {
"type": "boolean",
"default": false
},
"disposition_notification_to": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"allow_individual_disposition_notification_to": {
"type": "boolean",
"default": false
}
},
"additionalProperties": false,
"default": {}
},
"template": {
"oneOf": [
{
"type": "object",
"required": [
"subject"
],
"properties": {
"subject": {
"type": "string"
},
"text": {
"type": [
"string",
"null"
]
},
"html": {
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"source"
],
"properties": {
"source": {
"type": "object",
"required": [
"type"
],
"properties": {
"type": {
"type": "string",
"const": "files"
},
"subject_path": {
"type": "string"
},
"text_path": {
"type": "string"
},
"html_path": {
"type": "string"
},
"encoding": {
"type": "string",
"default": "utf-8"
}
},
"additionalProperties": false
}
},
"additionalProperties": false
}
]
},
"attachments": {
"type": "object",
"properties": {
"base_path": {
"type": "string",
"default": ".",
"description": "Legacy single campaign-level attachment base path. Used when attachments.base_paths is absent."
},
"base_paths": {
"type": "array",
"items": {
"$ref": "#/$defs/attachment_base_path"
},
"default": [],
"description": "Named selectable attachment base paths. New WebUI campaigns use these instead of the legacy single base_path."
},
"allow_individual": {
"type": "boolean",
"default": false
},
"send_without_attachments": {
"type": "boolean",
"default": true,
"description": "Legacy compatibility flag. Prefer validation_policy and per-config missing_behavior for new campaigns."
},
"global": {
"type": "array",
"items": {
"$ref": "#/$defs/attachment_config"
},
"default": []
},
"missing_behavior": {
"type": "string",
"enum": [
"block",
"ask",
"drop",
"continue",
"warn"
],
"default": "ask"
},
"ambiguous_behavior": {
"type": "string",
"enum": [
"block",
"ask",
"drop",
"continue",
"warn"
],
"default": "ask"
}
},
"additionalProperties": false,
"default": {
"base_path": ".",
"base_paths": [],
"global": []
}
},
"entries": {
"oneOf": [
{
"type": "object",
"required": [
"inline"
],
"properties": {
"inline": {
"type": "array",
"items": {
"$ref": "#/$defs/entry"
}
},
"defaults": {
"$ref": "#/$defs/entry"
}
},
"additionalProperties": false
},
{
"type": "object",
"required": [
"source",
"mapping"
],
"properties": {
"source": {
"$ref": "#/$defs/source"
},
"mapping": {
"type": "object",
"description": "Internal campaign path -> source column/key. Examples: to.0.email, fields.number, attachments.0.file_filter.",
"additionalProperties": {
"type": "string"
}
},
"defaults": {
"$ref": "#/$defs/entry"
}
},
"additionalProperties": false
}
]
},
"validation_policy": {
"type": "object",
"properties": {
"missing_required_attachment": {
"type": "string",
"enum": [
"block",
"ask",
"drop",
"continue",
"warn"
],
"default": "ask"
},
"missing_optional_attachment": {
"type": "string",
"enum": [
"block",
"ask",
"drop",
"continue",
"warn"
],
"default": "warn"
},
"ambiguous_attachment_match": {
"type": "string",
"enum": [
"block",
"ask",
"drop",
"continue",
"warn"
],
"default": "ask"
},
"ignore_empty_fields": {
"type": "boolean",
"default": false,
"description": "Render unresolved/empty template placeholders as an empty string instead of keeping them and raising a template error."
},
"missing_email": {
"type": "string",
"enum": [
"block",
"drop"
],
"default": "block"
},
"template_error": {
"type": "string",
"enum": [
"block",
"drop"
],
"default": "block"
},
"inactive_entry": {
"type": "string",
"enum": [
"drop",
"block",
"warn"
],
"default": "drop"
}
},
"additionalProperties": false,
"default": {
"ignore_empty_fields": false
}
},
"delivery": {
"type": "object",
"properties": {
"rate_limit": {
"type": "object",
"properties": {
"messages_per_minute": {
"type": "integer",
"minimum": 1,
"default": 5
},
"concurrency": {
"type": "integer",
"minimum": 1,
"default": 1
}
},
"additionalProperties": false
},
"imap_append_sent": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"default": false
},
"folder": {
"type": "string",
"default": "auto"
}
},
"additionalProperties": false
},
"retry": {
"type": "object",
"properties": {
"max_attempts": {
"type": "integer",
"minimum": 1,
"default": 3
},
"backoff_seconds": {
"type": "array",
"items": {
"type": "integer",
"minimum": 1
},
"default": [
60,
300,
900
]
}
},
"additionalProperties": false
}
},
"additionalProperties": false,
"default": {}
},
"status_tracking": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"default": true
},
"initial_build_status": {
"type": "string",
"enum": [
"built",
"build_failed"
],
"default": "built"
},
"initial_send_status": {
"type": "string",
"enum": [
"draft",
"queued"
],
"default": "draft"
}
},
"additionalProperties": false,
"default": {
"enabled": true
}
}
},
"additionalProperties": false,
"$defs": {
"recipient": {
"type": "object",
"required": [
"email"
],
"properties": {
"email": {
"type": "string",
"format": "email"
},
"name": {
"type": "string"
},
"type": {
"type": "string",
"enum": [
"to",
"cc",
"bcc",
"reply_to",
"bounce_to",
"disposition_notification_to"
],
"default": "to"
}
},
"additionalProperties": false
},
"attachment_config": {
"type": "object",
"required": [
"base_dir",
"file_filter"
],
"properties": {
"id": {
"type": "string",
"description": "Optional stable ID for UI/status references."
},
"label": {
"type": "string"
},
"base_dir": {
"type": "string",
"description": "Selected attachment base path for current WebUI campaigns, or a directory relative to attachments.base_path for legacy campaigns."
},
"file_filter": {
"type": "string",
"description": "Glob/filter expression, rendered with global/local fields before matching."
},
"include_subdirs": {
"type": "boolean",
"default": false
},
"required": {
"type": "boolean",
"default": true
},
"allow_multiple": {
"type": "boolean",
"default": false,
"description": "Legacy compatibility flag. Current UI treats wildcard file_filter patterns as multi-match-capable automatically."
},
"missing_behavior": {
"type": [
"string",
"null"
],
"enum": [
"block",
"ask",
"drop",
"continue",
"warn",
null
],
"default": null,
"description": "Optional per-rule override. Null or omitted inherits from validation_policy."
},
"ambiguous_behavior": {
"type": [
"string",
"null"
],
"enum": [
"block",
"ask",
"drop",
"continue",
"warn",
null
],
"default": null,
"description": "Optional per-rule override. Null or omitted inherits from validation_policy."
},
"zip": {
"type": "object",
"properties": {
"enabled": {
"type": "boolean",
"default": false
},
"filename_template": {
"type": "string"
},
"password_template": {
"type": "string"
},
"method": {
"type": "string",
"enum": [
"zip_standard",
"aes"
],
"default": "aes"
}
},
"additionalProperties": false,
"default": {
"enabled": false
}
}
},
"additionalProperties": false
},
"entry": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"active": {
"type": "boolean",
"default": true
},
"from": {
"oneOf": [
{
"$ref": "#/$defs/recipient"
},
{
"type": "object",
"maxProperties": 0
},
{
"type": "null"
}
]
},
"to": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"combine_to": {
"type": "boolean",
"default": true
},
"cc": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"combine_cc": {
"type": "boolean",
"default": true
},
"bcc": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"combine_bcc": {
"type": "boolean",
"default": true
},
"reply_to": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"combine_reply_to": {
"type": "boolean",
"default": true
},
"bounce_to": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"combine_bounce_to": {
"type": "boolean",
"default": true
},
"disposition_notification_to": {
"type": "array",
"items": {
"$ref": "#/$defs/recipient"
},
"default": []
},
"combine_disposition_notification_to": {
"type": "boolean",
"default": true
},
"attachments": {
"type": "array",
"items": {
"$ref": "#/$defs/attachment_config"
},
"default": []
},
"combine_attachments": {
"type": "boolean",
"default": true
},
"fields": {
"type": "object",
"additionalProperties": true,
"default": {}
},
"last_sent": {
"type": "string",
"format": "date-time"
},
"name": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
],
"format": "email"
}
},
"additionalProperties": false
},
"source": {
"type": "object",
"required": [
"type",
"path"
],
"properties": {
"type": {
"type": "string",
"enum": [
"csv",
"json"
]
},
"path": {
"type": "string"
},
"delimiter": {
"type": "string",
"default": ";"
},
"encoding": {
"type": "string",
"default": "utf-8"
},
"has_header": {
"type": "boolean",
"default": true
}
},
"additionalProperties": false
},
"attachment_base_path": {
"type": "object",
"required": [
"name",
"path"
],
"properties": {
"id": {
"type": "string",
"description": "Optional stable ID for UI/status references."
},
"name": {
"type": "string",
"description": "Display name for this selectable attachment base path."
},
"path": {
"type": "string",
"default": ".",
"description": "Base path relative to the campaign file unless absolute."
},
"allow_individual": {
"type": "boolean",
"default": false,
"description": "Whether recipient-level attachments may use this base path."
},
"source": {
"type": [
"string",
"null"
],
"description": "Legacy UI compatibility value. Ignored by the backend."
}
},
"additionalProperties": false
}
}
}