DocGen & eSign

DocGen & eSign Reminder Email System — Technical Architecture & Reference

What this layer does

A signer is awaiting signature on a workflow. Either manually (quick action on workflow item) or automatically (nightly batch), the system sends a reminder email to prompt the signer to sign. The reminder fetches the signing link and optional custom email template from the workflow configuration, substitutes signer name and URL tokens, renders dynamic content (merge fields), and sends via org-wide email address. Every reminder sent is logged for audit trails. Two paths exist: manual (quick action) and automated (batch scheduler).

Three records (plus configuration) hold the state:

Object

Holds

docgen_esign__Document_Workflow_Item__c

Signer queue item (Envelope Link created) — contains Signer_Email__c, Signer_Name__c, Signer_URL_New__c, Signer_Sequence__c, linked to workflow

docgen_esign__Document_Workflow__c

Workflow header — contains Reminder_Email_Template__c (EmailTemplate ID), Sender_s_Email_Address__c (OrgWideEmailAddress), Email_Body__c, Email_Subject__c, Current_Signing_Count__c (which signer is up)

EmailTemplate (Salesforce native)

Email template — subject and HTML body for reminder message. Contains {url} and {signer} tokens for substitution


Architecture

┌─────────────────────────────────────────────────────┐
│              Two Reminder Paths                     │
└──────────────┬──────────────────────────────────────┘
               │
    ┌──────────┴──────────┐
    │                     │
    ▼                     ▼
MANUAL REMINDER      AUTOMATED REMINDER
(Quick Action)       (Scheduled Batch)
    │                     │
    └──────────┬──────────┘
               │
    reminderEmailPopup (LWC)  OR  BatchSendReminderEmail (Batch)
               │                     │
               └──────────┬──────────┘
                          │
    ┌───────────────────┬─┴──────────────────┐
    │                   │                    │
    ▼                   ▼                    ▼
InvocableSendReminder   │              DocumentSigningUtility
Email (Invocable)       │              .sendEmail()
    │                   │                    │
    └─────────────┬─────┴────────────────────┘
                  │
        Query EmailTemplate
        Query OrgWideEmailAddress
        Substitute {url}, {signer}, merge fields
                  │
        Messaging.sendEmail()
                  │
        Log result via UtilityClass.createReminderLog()

Key mechanism — two-path invocation + deferred scheduling.

Manual path: User clicks "Send Reminder" quick action on a workflow item (documentWorkFlowIndividual LWC). reminderEmailPopup LWC opens confirmation dialog. On confirm, calls GenerationScreenController.sendReminderEmail() → queries workflow item + workflow + email template → calls InvocableSendReminderEmail.sendReminder() → sends email immediately → logs result.

Automated path: BatchSendReminderEmail runs on schedule (via finish() reschedule or external org-wide schedule). Queries workflows in Awaiting Signature status (created in last N days per config). For each workflow, finds current signer (matching Current_Signing_Count__c). Fetches email template + org-wide address. Constructs and sends bulk emails. Logs each result. On finish(), reschedules itself for next run time (read from DocGen_eSign_Configuration__c).


LWC — reminderEmailPopup

Quick action quick-open component. Triggered by documentWorkFlowIndividual "Send Reminder" badge or flow button.

Tracked state

Property

Purpose

@api recordId

Injected: Document_Workflow_Item__c ID

isLoading

Toggles spinner during send

Key functions

Function

Behavior

connectedCallback()

None (component stateless)

sendReminder()

Calls GenerationScreenController.sendReminderEmail({ recordId }). Sets isLoading = true. On success: shows toast, closes modal. On error: shows error toast, closes modal.

closeModal()

Dispatches CloseActionScreenEvent.

showToast(title, variant, message)

Displays ShowToastEvent.

HTML Template

Info banner: "Are you sure you want to send a reminder email to notify the signer of the pending document?" Cancel/Send buttons in footer.


Apex — GenerationScreenController.sendReminderEmail()

@AuraEnabled method. Receives Document_Workflow_Item__c ID. Queries workflow item + linked workflow. Calls InvocableSendReminderEmail.sendReminder() passing item ID.

Method

Returns

What it does

sendReminderEmail(String recordId) @AuraEnabled

void

Queries Document_Workflow_Item__c by recordId. Calls InvocableSendReminderEmail.sendReminder({ itemId }). Used by reminderEmailPopup LWC and documentWorkFlowIndividual LWC.


Apex — InvocableSendReminderEmail

global with sharing. Invocable method (callable from Flow, Apex, or direct method calls).

Method

Invocation

What it does

sendReminder(List<Id> workflowItemId) @InvocableMethod

Flow, Apex, quick action → GenerationScreenController

Takes Document_Workflow_Item__c ID(s). Queries item + workflow (including Reminder_Email_Template__c, Sender_s_Email_Address__c, Email_Body__c, Email_Subject__c). Queries same signer's Envelop Link Created event to fetch Signer_URL_New__c. Validates: URL, org-wide address, email, signer name present. Queries EmailTemplate by ID. If template exists: uses Subject + HTMLValue. Else: uses Email_Subject__c + Email_Body__c from workflow. Substitutes {url} → Signer_URL_New__c, {signer} → Signer_Name__c. Calls UtilityClass.renderDynamicContent() to replace merge fields (e.g., {Account.Name}). Calls DocumentSigningUtility.sendEmail() to construct email. Sends via Messaging.sendEmail(). On success: calls UtilityClass.createReminderLog('Reminder Email Delivered', workflowId, 'Success', null, 'Manual Reminder Email Sent'). On fail: logs error message.

Validation gate: If Test.isRunningTest() = false, requires: sSignerURL not blank, orgWideEmailAddress not null, sSignerEmail not null, reminderTemplateId not null OR emailContent not blank.


Apex — BatchSendReminderEmail

global with sharing, implements Database.Batchable<sObject>, Schedulable, Database.Stateful. Queries workflows in Awaiting Signature state (created in last N days). For each workflow, identifies current signer (matching Current_Signing_Count__c to Signer_Sequence__c). Sends bulk reminder emails. Reschedules itself on finish().

Method

Context

What it does

start(Database.BatchableContext BC)

Batch init

Queries DocGen_eSign_Configuration__c for 'Reminder_Batch_WhereClause'. If not set: defaults to WHERE Status = 'Awaiting Signature'. Appends CreatedDate = LAST_N_DAYS:{iLastDays} (read from 'Reminder_Batch_LastNDays' config, default N). Returns QueryLocator.

execute(Database.BatchableContext BC, List<docgen_esign__Document_Workflow__c> lstWorkflow)

Batch row processing

Takes workflow batch. Extracts workflow IDs and current signer counts into map. Queries Workflow_Items WHERE Event_Type = 'Envelop Link Created' AND Workflow ID IN set (all signers' envelope links). Filters items: only process if Current_Signing_Count matches Signer_Sequence AND all required fields present (email, URL, body/template, org-wide, parent ID). Builds set of email template IDs + org-wide addresses. Queries EmailTemplates and OrgWideEmailAddresses. Builds map of address→ID and templateId→EmailTemplate. For each item to process: constructs EmailWrapper using DocumentSigningUtility. Uses template.Subject/HTMLValue if available, else workflow Email_Subject__c/Email_Body__c. Substitutes {url}, {signer}. Calls renderDynamicContent(). Adds to batch email list. Sends all emails via Messaging.sendEmail(lstMails, false). For each result, logs success/failure via UtilityClass.createReminderLog().

execute(SchedulableContext sc)

Scheduler invocation

Creates new BatchSendReminderEmail() and calls database.executebatch(oBatch, iBatchSize). Decouples scheduler from batch.

finish(Database.BatchableContext BC)

Batch completion

Queries 'Reminder_Email_Next_Run_Time' config (hours from now). If set: calculates next scheduled time. Generates CRON expression. Generates unique job name. Calls System.schedule() to reschedule next batch run. This creates a self-rescheduling batch job.

Configuration reads: Reminder_Batch_LastNDays (default N), Reminder_Batch_WhereClause (default "Status = 'Awaiting Signature'"), Reminder_Email_Next_Run_Time (hours to next run), Reminder_Batch_Batch_Size (batch size for execute).


Utility — DocumentSigningUtility.sendEmail()

Helper method. Constructs Messaging.SingleEmailMessage from EmailWrapper.

Wrapper Property

Apex Property

toAddress

setToAddresses(new List<String>{ toAddress })

fromAddress

setOrgWideEmailAddressId(fromAddress) [OrgWideEmailAddress ID]

emailSubject

setSubject(emailSubject)

emailBody

setHtmlBody(emailBody)

Returns fully-built Messaging.SingleEmailMessage ready for sendEmail().


Utility — UtilityClass.createReminderLog()

Audit log. Creates platform event or log record. Takes event name, workflow ID, status, error message, description. Logs all manual and automated reminder attempts (success and failure).


Email template tokens

Standard substitutions (literal, no field lookup):

Token

Replaced with

{url}

Document_Workflow_Item__c.Signer_URL_New__c (signing link)

{signer}

Document_Workflow_Item__c.Signer_Name__c (signer name)

{Account.Name}, {Contact.Email}, etc.

Merge field lookup via UtilityClass.renderDynamicContent() — depends on parent record type