mirror of
https://github.com/paperless-ngx/paperless-ngx.git
synced 2026-10-28 02:25:43 +00:00
email and webhooks too
This commit is contained in:
3 files changed
+89
-1
No files matched your search
+1
-1
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user