Start with a contract, then a caller
These examples use only their input and return JSON-compatible dictionaries. Run them through the matching extension point in a test environment after saving and publishing. Creating a script does not connect it to a caller.Normalize a Caseflow reference
Choose Caseflow Autofill (caseflow_autofill). The caller supplies trigger_value; the result maps target attribute names to string values.
Bind the published script to the intended Caseflow autofill target, and include
CustomerReference among its allowed target attributes. Verify it in the consuming form. Decide separately whether an empty reference is acceptable; normalization does not enforce a required field.
Return a workflow decision
Choose Workflow Action (workflow_action). Configure a Script.Run action to supply the input key amount and capture its output into an instance variable.
9999 and 10000: the results are false and true respectively. Test a missing value, a string, a boolean, and a negative amount as rejected inputs. If your source keyword is text, convert it deliberately before passing it as a number.
Use the returned decision in a subsequent workflow condition. The script does not create a task or update a document by returning this value; those are separate configured actions. Script.Run resolves the published script by slug, so publishing a workflow does not freeze the script version.
Acknowledge a document event
Choose Event Hook (event_hook). This minimal example verifies the event contract without writing to another system:
event_type equal to document.created and entity_id equal to 1042, the message is Received document.created for entity 1042.
Publish it, then create a binding for one test document type and the Document Created event. Create a representative document and inspect the script’s execution log. An acknowledgement is not an upload, callback, or business-state change.
Work with PDF documents
Scripts can read, split, merge and check PDF documents themselves with two libraries:pypdf (pages, text, split, merge) and pyhanko (signatures and signer certificates). Read a document’s bytes with context["api"].get_document_content(), wrap them in BytesIO, and store a new PDF with initialize_upload(), upload_chunk() and create_document().
This Workflow Action splits a scanned file into one document per person. A page that contains an identifier such as 010190-1234 starts a new part, the following pages join it, and pages before the first identifier are left out. The text comes from the PDF’s text layer, so scan with OCR: a page that is only an image has no text to match.
pyhanko and accept it only when it is trusted and covers the whole file:
- Trusted means the signer’s certificate chains to the issuer’s CA certificate, which you pass in as a trust root. Keep that CA certificate (PEM) in a script secret named
Issuer_CA_Certificate. An e-mail address in the certificate proves nothing on its own, because anyone can create a certificate that claims it. - Whole file means nothing was appended after the signature. A signed PDF can carry unsigned changes added later.
status.bottom_line combines integrity, the signature’s validity, trust and the document’s modification policy.
Keep certificate revocation checks switched off in
pyhanko (its allow_fetching option). Those checks would call out to the internet directly, bypassing context["http"] and the environment’s allowed destinations.Maintain an autofill keyword set
A script can read and change the entries of an autofill keyword set throughcontext["api"]: find the set with get_autofill_keyword_sets(), search its entries with search_autofill_entries(), and change them with create_autofill_entry(), update_autofill_entry() and delete_autofill_entry(). Entry values are keyed by keyword type ID.
This Workflow Action (workflow_action) moves the entries filed under one primary value to another, for example after a person’s identifier changed. The primary keyword cannot be edited in place, so each entry is created again under the new value before the original is deleted (a failed create then leaves the original in place):
0101901234 and new_value equal to 0202901234, it returns {"moved": 1} and the entry’s other keywords are kept.
Creating, updating and deleting entries needs the Keyword Sets privilege for the identity the script calls with. For a workflow script, that is the Workflow Engine’s service account. Grant it to a group of that account under Admin settings → Documents → Access rights → Group privileges → General privileges; see general privileges. A set whose values come from an external source is read-only. value matches exactly; use search_term to find entries where any keyword contains a text.
Return a summary for a workflow message
A Workflow Action (workflow_action) can return text for the workflow to show the person who started it with Workflow.SetMessage. This one withdraws a batch of generated letters: it reads the batch number from the batch document, finds the batch’s letters with search_documents(), deletes the unsigned ones with delete_document(), and returns a summary and a level. It belongs to the worked example Confirm, run a background script, show the result, which runs it in the background from Script.Run with this input:
singleInstanceGroups or multiInstanceGroups instead of standalone. A letter counts as signed when its SignedDate keyword has any value, which the IsNotNull operator finds; IsNull finds the letters without one. Each search row carries the document’s ID under documentInfo.
A recipient can sign after the search and before the script reaches their letter. So the script reads each letter’s SignedDate again just before deleting it, and keeps the letter if it has been signed in the meantime. Nobly Insight has no delete that checks a keyword in the same step, so a signature in the very moment between that read and the delete can still be lost. If that matters, stop signing for the batch before you withdraw it, for example with a keyword on the batch that whatever handles signing checks first.
A background script calls Insight as the Script Engine’s service account. Its user needs View and View keywords on the batch document type, and View, View keywords, and Delete on the letter document type; see document access rights. Deleted letters move to the archive trashcan, and Nobly Insight cannot restore them from there, so try the test run first. One search returns at most 10,000 letters; run the action again for a larger batch.
Before adding an external integration
Replace the example behavior only after the caller, input, published version, and logs are working. Usecontext["api"] or context["http"] for the supported managed clients, context["variables"] for configured settings such as base URLs, and context["secrets"] for configured credentials. For an API that needs an OAuth client-credentials token, use context["http"].client_credentials_token instead of requesting the token yourself; see Call an API that uses OAuth client credentials.
Define what happens after a timeout or duplicate event before adding a write operation. Keep an external operation idempotent where possible, and distinguish “request accepted” from “business operation completed.” Script-authoring access is trusted access because executed scripts can read the secrets supplied to their scope.
Where to read next
Bindings and event hooks
Attach published scripts to external autofill sets, Caseflow forms, workflows, and document events.
