Pages

Showing posts with label Prompt template. Show all posts
Showing posts with label Prompt template. Show all posts

Sunday, August 16, 2026

Zero-Touch Case Documents: Automating Dynamic PDF Generation and Delivery in Salesforce

 

The Business Problem

Every organization running Salesforce eventually hits the same operational bottleneck: a business process that depends on a human generating a document, filling it with record data, and emailing it out. It's slow, error-prone, and doesn't scale.

In this case, the requirement was precise: the moment a Case is created, a formatted PDF — built against a structure the business team had already defined — needed to be generated and delivered to the customer's inbox automatically. No manual document prep. No copying case details into a form by hand. No separate step to draft and send the email.

The complexity sat in two places. First, the PDF itself had to be dynamic — Case-specific data such as the case number, account, customer name, and address needed to populate directly into predefined blank fields on a business-supplied form. Second, the email carrying that PDF needed its own dynamic template, merging Case data with related Account and Customer details, following a structure the business had already signed off on.

The goal of this proof-of-concept was to solve both problems declaratively wherever possible, keep the architecture maintainable by non-developers, and make failure visible rather than silent. Here's how it came together — the diagram below gives the high-level shape before we walk through each stage.

Solution Overview

At a high level, the architecture has four moving parts, shown end to end in the diagram above:



  1. A Record-Triggered Flow on the Case object, fired on record creation, acting as the orchestrator.
  2. A Prompt Template that accepts the Case ID as input and returns the populated document structure, using the business-provided file as the base format with the blank fields resolved dynamically.
  3. An Apex class that converts this formatted content into an actual PDF, retrieves the additional Account and Customer details required, drafts the email through Salesforce's Messaging classes, attaches the PDF, and sends it to the customer.
  4. Error handling and logging, so failures — a missing or invalid customer email, for instance — are captured for review rather than failing silently.

Step-by-Step Breakdown

1. Trigger: record-triggered flow on Case creation

The entry point is intentionally simple: a Record-Triggered Flow configured to fire on Case creation. Its role is orchestration only — it does not construct the PDF or send the email directly, but coordinates the downstream calls to the Prompt Template and the Apex class. Keeping this layer thin makes the automation easier to hand off and modify without touching code.

2. Formatting the document through a Prompt Template

Rather than hardcoding the PDF layout inside Apex, the design uses a Prompt Template that takes the Case ID as its sole input parameter. The template is grounded in the business-supplied file, which defines the exact structure and blank fields the final document requires — case number, account, customer name, address, and similar fields.

The Prompt Template resolves these fields against live Case data and returns the fully populated document content, which the Flow captures into a variable. This keeps the formatting logic declarative and business-owned: when the form layout changes, the business team can adjust it without a developer touching Apex.

3. PDF conversion and email dispatch through Apex

The Flow hands the populated content to an Apex class, which performs the core execution:

  • Converts the formatted content into an actual PDF using Salesforce's native PDF generation capability (Blob.toPDF()).
  • Queries the Case for its related Account and Contact details — customer name, email address, and any additional fields needed for personalization.
  • Builds the email body from a separate email template, merging in both Case data and Account/Customer data.
  • Uses the Messaging class to construct and send the email, with the generated PDF attached.
  • Delivers the email to the customer's address as retrieved from the record.

Consolidating PDF generation, data retrieval, and email dispatch into one well-tested Apex class made the logic considerably easier to unit test and reason about, compared to distributing the same responsibilities across multiple Flow elements.

4. Error handling and logging

Automation of this kind fails quietly if you're not deliberate about it — a missing customer email, a null Account lookup, or a malformed PDF payload can break the process without anyone noticing. To guard against that, the design includes:

  • Validation checks before attempting to send, such as confirming a valid customer email exists.
  • A dedicated logging mechanism that captures failures with enough context — Case ID, failure reason, timestamp — for a support or error-logging user to investigate.
  • Isolated failure handling, so an issue on one Case does not affect processing for any other.

Lessons learned

A few takeaways stood out from building this proof-of-concept:

  • Separating "what to generate" from "how to send it" — using the Prompt Template purely for content and formatting, and Apex purely for delivery — made the solution significantly easier to maintain and hand off to business stakeholders.
  • Error logging is not optional. Any automation that touches a customer's inbox carries a higher cost for silent failure than a purely internal process, so visibility into failures has to be designed in from the start, not added afterward.
  • Declarative-first, code-second is the right default here. The Flow owns orchestration, the Prompt Template owns dynamic formatting against a business-owned structure, and Apex is reserved for the pieces that genuinely require code: PDF binary conversion and the Messaging API calls.

Closing thoughts

This proof-of-concept demonstrates how a common but operationally expensive requirement — generate a document, populate it with live data, and deliver it automatically — can be solved cleanly with a combination of Flow, Prompt Templates, and Apex, without hardcoding business logic that should stay flexible. The pattern generalizes well beyond Cases, to invoices, confirmations, onboarding packets, and any other scenario where a document needs to be assembled and delivered the moment a record is created.

If you're solving something similar, I'd welcome hearing how your approach differs — particularly around error handling strategy or how much of the template logic you keep declarative versus code-driven.