Flow automation#
Welisa DocGen ships Flow invocable actions for generation and signing, plus helpers for custom signing UIs. This page says which to pick and gives a worked recipe for each.
Picking the right action#
| You want to… | Use this action | Class |
|---|---|---|
| Generate a single document for one record (most common) | Generate Document | DocGenFlowAction |
| Auto-detect whether the dataset is big enough to need the background path | Generate Document (Auto Giant Query) | DocGenGiantQueryFlowAction |
| Run a template against many records in one batch | Generate Bulk Documents | DocGenBulkFlowAction |
| Send a document for guided signing (built-in signing) | Welisa: Create Signature Request | DocGenSignatureFlowAction |
| Send through the configured signature provider (built-in or DocuSign) | Welisa: Send for Signature | SignatureFlowAction — see Signature providers |
| Re-run signer form-field writeback for a completed request | Welisa: Write Back Signer Form Fields | DocGenFieldWritebackService |
| Send an existing document for signature on the PDF viewer page | Welisa: Send Existing Document for Signature — deprecated, use Create Signature Request | DocGenSignaturePdfFlowAction |
Three further helpers — Validate Signature Token, Submit Signed Signature, Finalize Signature Image — exist for custom signing screens against legacy single-signer requests (below). Templates can be addressed by API Name instead of Id in every action, so a Flow survives sandbox-to-production deployment with nothing to remap. In Flow Builder, search "Welisa" or "Generate Document" in the Action element.
Recipe — when an Opportunity closes won, generate a PDF and attach it#
Trigger: Record-Triggered Flow on Opportunity, updated records, entry condition IsClosed = TRUE AND IsWon = TRUE.
Action: Generate Document.
| Input | Value |
|---|---|
| Template API Name | Opp_Close_Summary (set the API Name on the template; identical in every environment). Or pass Template ID. |
| Record ID | {!$Record.Id} |
| Save to Record | {!$GlobalConstant.True} |
| Output Format | leave blank for the template's default |
| Document Title | {!$Record.Name} — Close Summary |
Outputs: contentDocumentId and contentVersionId (the new file), success, errorMessage. Every closed-won Opportunity gets a PDF in its Files related list.
Recipe — e-mail a generated PDF without keeping a copy#
- Generate Document with Save to Record = True; capture
contentVersionId. - Send Email with
contentVersionIdwired into the attachment input. - Optionally Delete Records on the ContentDocument afterwards.
For a truly storage-less path use Apex: welisa.DocGenService.generatePdfBlob(templateId, recordId) returns the PDF without persisting anything (Apex API).
Recipe — mass-generate quarterly statements#
Trigger: Scheduled Flow, first day of the quarter.
Action: Generate Bulk Documents.
| Input | Value |
|---|---|
| Template ID / Template API Name | the statement template |
| WHERE Condition | Active__c = TRUE AND Status__c = 'Current' |
| Job Label | Q{!$Flow.CurrentQuarter} {!$Flow.CurrentYear} Statements |
| Combined PDF Only | {!$GlobalConstant.False} |
| Also Keep Individual Files | {!$GlobalConstant.True} |
| Sort Order | Account.Name ASC |
| Duplex Padding | only meaningful with a Combined PDF |
| Batch Size | 25 |
Output: jobId — track it on the Command Hub's Job History tab. The job runs asynchronously; the Flow continues immediately; failed records are logged on the job with their error.
Recipe — generate when dataset size is unpredictable#
Most invoices have 5–20 line items, a few customers have 5,000 — or a normal count with very large rich-text descriptions. Generate Document (Auto Giant Query) estimates peak memory (measuring one real child row when it is borderline) and routes small datasets synchronously and large ones to the background.
| Input | Value |
|---|---|
| Template ID | the invoice template |
| Record ID | {!$Record.Id} |
| Save to Record | {!$GlobalConstant.True} |
Outputs: contentDocumentId + contentVersionId when synchronous, jobId when routed to the background, and isGiantQuery so the Flow can branch — show the file immediately, or send the user to a "your document is being prepared" screen with a polling component. Auto-routing needs a V3 query configuration and a Word template; other cases are pointed to the runner with a message.
Recipe — send a contract for signature on Opportunity approval#
Trigger: Record-Triggered Flow on Opportunity, entry Approval_Status__c → 'Approved'.
Step 1 — Get Records: the primary Contact.
Step 2 — Build the signers collection. Create a Flow Variable with Data Type = Apex-Defined, Apex Class = DocGenSigner (one record), and a second collection variable of the same type. Populate the signer with an Assignment:
name = {!PrimaryContact.Name} // full legal name, one field
email = {!PrimaryContact.Email}
role = "Buyer" // matches {@Signature_Buyer:1:Full} in the template; blank → "Signer"
contactId = {!PrimaryContact.Id} // optional — links the audit trail to the ContactOnly name and email are required. Add the record to the collection with a second Assignment (signers Add {!signer}).
Step 3 — Welisa: Create Signature Request.
| Input | Value |
|---|---|
| Template API Name | MSA_Agreement (or Template ID) |
| Related Record ID | {!$Record.Id} |
| Signers | {!signers} (the signerRecords input — never the deprecated signers inner type) |
| Signing Order | Sequential, Parallel or Single |
| Send Branded Emails | blank or True lets Welisa DocGen e-mail the signers; False suppresses the initial invitations so you can send your own from signerUrls |
| Require Email Verification / Pre-fill Signer Email | optional overrides of the template and org defaults |
| Link Expiration (Days) | optional, 1–365; blank = the org default |
| Email Subject / Email Message | optional per-send overrides of the e-mail template |
Outputs: success (branch on it), signatureRequestId, signerUrls (per-signer links in signer order), signerNames, signerEmails, signerRoles, emailStatus (delivery result when Welisa DocGen sends), errorMessage.
The signer receives a branded invitation, clicks, verifies the PIN, signs and submits; the signed PDF with its Certificate of Completion lands on the Opportunity's Files. For multi-signer flows add one signer per person and pick Parallel or Sequential.
Sequential + Send Branded Emails = False. That input suppresses only the initial invitations; on a Sequential request the next signer is still e-mailed automatically as each one completes — that is how the chain advances. If your Flow also sends invitations, signers 2…N get two e-mails. Either let Welisa DocGen send everything, or use Parallel with Send Branded Emails = False and send every invitation yourself. PIN e-mails always need an Org-Wide Email Address, even when you send your own invitations.
Sign in-session — inside your own portal or screen Flow#
To have someone sign immediately, inside an Experience Cloud screen Flow for example, while the remaining parties sign later by e-mail:
- Tag the template with one role per party:
{@Signature_Primary:1:Full},{@Signature_Member:2:Full}. - At the end of the Flow call Welisa: Create Signature Request with the in-session signer first in the collection, Signing Order =
Sequential, Require Email Verification =False(the signer is about to sign; a PIN would force them to fetch an e-mail mid-flow), and Send Branded Emails left blank. - Navigate the user to their link: it is the first element of
signerUrls. Flow cannot index a collection directly, so loop oversignerUrlswith an Assignment that only writes while your text variable is still blank, then pass it to the Navigate action (or show it as a Display Text link). - Stop there. Do not add a Generate Document action afterwards — the request produces the signed document itself when the last signer completes; a second action would leave an unsigned, certificate-less duplicate next to the real one.
The signature is a real audited signature: timestamp, IP, consent hash, and an entry on the Certificate of Completion.
Recipe — pass prebuilt JSON data instead of querying#
Generate Document accepts a JSON Data input. When present, the engine skips its own query and merges the supplied JSON — an external API response you already fetched, cross-object data the query cannot express, computed values. Wire it to a Text variable populated upstream (typically by an Apex action):
{ "Name": "Acme Corp", "Amount": 50000,
"Items": { "records": [ { "Product": "Widget", "Qty": 2, "Price": 100 }, { "Product": "Gadget", "Qty": 1, "Price": 250 } ] } }Templates that only ever receive data this way can be created as JSON Data (from Flow) templates — see Query configuration.
Signer form fields — collect input during signing#
On the guided PDF signing path you can ask each signer for information before they sign and have the answers flow into the document, the certificate and the record. In the template builder add Form Fields, each with a Key (referenced as {?key} in the document), a Label, a Type (text, number, date, checkbox, picklist), Required, an optional Writeback field on the related record and List on certificate. On completion the values render at each {?key}, listed fields appear on the Certificate of Completion, and for a single-signer request mapped answers write back to the related record in one update. Multi-signer requests capture and list the answers but do not write them back yet; Welisa: Write Back Signer Form Fields re-runs the writeback for a completed request if you need a retry.
Custom signing UI (advanced)#
Three helper actions exist for orgs that build their own signing experience — for example a signature pad embedded in a customer portal: Validate Signature Token (returns signer name, document title and a preview URL), Submit Signed Signature (token + base64 signature) and Finalize Signature Image (stamps a captured PNG, renders the PDF, writes the audit record).
These work only against legacy single-signer requests, whose token lives on the request record. They cannot submit a signature into a request created by Create Signature Request or Send Existing Document for Signature — the current multi-signer path. Passing a signer token from signerUrls to Submit or Finalize is a silent no-op; passing the request's own token lands in the legacy path and produces an error and no document. Validate Signature Token accepts both shapes, which is exactly why a Flow can validate cleanly and then do nothing. To capture a signature inside your own portal, use sign in-session — the only route that produces an audit trail and a certificate.
There is also no action that records a signature image you captured yourself as a v3 signer's signature. If you only need a captured image to appear in a document, store it as a file, keep its Id in a text field and merge it with {%Your_Field__c} — it is a picture, with no audit record and no certificate entry. Do not use that where the signature must be legally defensible.
Polling an async job from a screen Flow#
Bulk and large-dataset actions return a jobId. Screen Flows have no Wait element, so poll with a user-driven loop: Get Records on welisa__DocGen_Job__c where Id = {!jobId} → Decision on Status__c (Completed → show the file; Failed → show the error; anything else → a Screen with a Refresh button whose next path returns to the Get Records). Autolaunched and record-triggered Flows can use a real Pause element.
Error handling#
Every action returns success (Boolean) and errorMessage (String). Always add a Decision on success. Common failures: a wrong Template Id (prefer Template API Name), a null Record Id (add an entry condition), a locked output format conflicting with an override, a heap limit on a synchronous action (switch to Auto Giant Query).
Two kinds of error arrive by different routes, so signature Flows need both:
| What went wrong | How you find out | What to wire |
|---|---|---|
| Runtime failure — template deleted, DML rejected, limit hit | success = false with errorMessage | A Decision after the action |
| Invalid input — no Template Id, no Related Record Id, an empty Signers collection, a signer without e-mail | The action throws and the interview faults | A fault connector on the action |
The signature actions validate their inputs strictly and stop the interview rather than returning success = false. That is deliberate: a missing Template Id is an authoring mistake and failing loudly beats a Flow that quietly continues having created nothing — but it means success is never reached on those paths. Drag the fault connector.
Bulk batches. Flow can hand an action up to 200 requests; Validate Signature Token queries per token and past roughly fifty runs out of the transaction's SOQL allowance. It validates as many as it can and returns the rest with Is Valid = false and an "not attempted" message — check per row and validate in smaller batches.