email and webhooks too

This commit is contained in:
shamoon committed 2026-10-26 21:07:00 -07:00
1 parent 7f7c7cc3c7
commit 2c329255a9
3 files changed
+89 -1

No files matched your search

+1 -1
View File
@@ -726,7 +726,7 @@ applied. You can use the following placeholders in the template with any trigger
- `{{added_time}}`: added time in HH:MM format
- `{{original_filename}}`: original file name without extension
- `{{filename}}`: current file name without extension (for "added" workflows this may not be final yet, you can use `{{original_filename}}`)
- `{{custom_fields}}` (title assignments only): Custom field names mapped to their type and value, as in [file name templates](advanced_usage.md#additional-variables). For example, `{{ custom_fields.Invoice.value }}` or `{{ custom_fields | get_cf_value("Invoice", "") }}` for a fallback when the field is missing. In title assignments, fields assigned by the same action are available.
- `{{custom_fields}}`: Custom field names mapped to their type and value, as in [file name templates](advanced_usage.md#additional-variables). For example, `{{ custom_fields.Invoice.value }}` or `{{ custom_fields | get_cf_value("Invoice", "") }}` for a fallback when the field is missing. In title assignments, fields assigned by the same action are available.
- `{{doc_title}}`: current document title (cannot be used in title assignment)
The following placeholders are only available for "added" or "updated" triggers
+66
View File
@@ -5164,6 +5164,72 @@ class TestWorkflows(
self.assertEqual(Document.objects.count(), 0)
@pytest.mark.django_db
@pytest.mark.parametrize("use_overrides", [False, True])
def test_custom_fields_in_email_and_webhook_templates(
use_overrides,
settings,
tmp_path,
):
from documents.workflows.actions import build_workflow_action_context
from documents.workflows.actions import execute_email_action
from documents.workflows.actions import execute_webhook_action
settings.EMAIL_ENABLED = True
field = CustomField.objects.create(
name="Invoice",
data_type=CustomField.FieldDataType.STRING,
)
if use_overrides:
invoice = tmp_path / "invoice.pdf"
invoice.write_bytes(b"%PDF-1.7")
document = ConsumableDocument(
source=DocumentSource.ConsumeFolder,
original_file=invoice,
)
overrides = DocumentMetadataOverrides(custom_fields={field.pk: "INV-123"})
else:
document = Document.objects.create(title="Invoice")
CustomFieldInstance.objects.create(
document=document,
field=field,
value_text="INV-123",
)
overrides = None
context = build_workflow_action_context(document, overrides)
template = '{{ custom_fields.Invoice.value }} {{ custom_fields | get_cf_value("Missing", "fallback") }}'
action = WorkflowAction(
email=WorkflowActionEmail(
subject=template,
body=template,
to="test@example.com",
),
webhook=WorkflowActionWebhook(
url="https://example.com",
body=template,
),
)
with mock.patch("documents.workflows.actions.send_email") as send_email:
execute_email_action(
action,
document,
context,
None,
Path("invoice.pdf"),
WorkflowTrigger.WorkflowTriggerType.DOCUMENT_ADDED,
)
assert send_email.call_args.kwargs["subject"] == "INV-123 fallback"
assert send_email.call_args.kwargs["body"] == "INV-123 fallback"
with mock.patch("documents.workflows.actions.send_webhook.apply_async") as send:
for use_params in (False, True):
action.webhook.use_params = use_params
action.webhook.params = {"invoice": template}
execute_webhook_action(action, document, context, None, Path("invoice.pdf"))
assert send.call_args.kwargs["kwargs"]["data"] == (
{"invoice": "INV-123 fallback"} if use_params else "INV-123 fallback"
)
class TestWebhookSend:
def test_send_webhook_data_or_json(
self,
+22
View File
@@ -11,6 +11,8 @@ from documents.data_models import DocumentMetadataOverrides
from documents.mail import EmailAttachment
from documents.mail import send_email
from documents.models import Correspondent
from documents.models import CustomField
from documents.models import CustomFieldInstance
from documents.models import Document
from documents.models import DocumentType
from documents.models import WorkflowAction
@@ -48,6 +50,9 @@ def build_workflow_action_context(
"added": timezone.localtime(document.added),
"created": document.created,
"id": document.pk,
"custom_fields": CustomFieldInstance.global_objects.filter(
document=document,
).select_related("field"),
}
correspondent_obj = (
@@ -80,6 +85,19 @@ def build_workflow_action_context(
"added": timezone.localtime(timezone.now()),
"created": overrides.created if overrides else None,
"id": "",
"custom_fields": [
CustomFieldInstance(
field=field,
**{
CustomFieldInstance.get_value_field_name(
field.data_type,
): overrides.custom_fields[field.pk],
},
)
for field in CustomField.objects.filter(
pk__in=overrides.custom_fields or {},
)
],
}
@@ -116,6 +134,7 @@ def execute_email_action(
context["title"],
context["doc_url"],
context["id"],
custom_fields=context["custom_fields"],
)
if action.email.subject
else ""
@@ -133,6 +152,7 @@ def execute_email_action(
context["title"],
context["doc_url"],
context["id"],
custom_fields=context["custom_fields"],
)
if action.email.body
else ""
@@ -211,6 +231,7 @@ def execute_webhook_action(
context["title"],
context["doc_url"],
context["id"],
custom_fields=context["custom_fields"],
)
except Exception as e:
logger.error(
@@ -230,6 +251,7 @@ def execute_webhook_action(
context["title"],
context["doc_url"],
context["id"],
custom_fields=context["custom_fields"],
)
headers = {}
if action.webhook.headers: