Business Problem
Campaign engagement data is often fragmented across messaging events and CRM records.
Marketing teams need fast answers about unique recipients, opens, clicks, and
non-engagers without manually joining data or producing separate exports.
Solution
Extended Salesforce's standard Campaign Creation Agent with a CampaignReporting
subagent and two invocable Apex actions. Reporting resolves campaign-linked ListEmail
records, queries Data 360 (formerly Data Cloud) email engagement data, classifies
unique recipient outcomes, and returns results to the marketer in plain language.
Architecture
Marketing Cloud Next Campaign
ListEmail (matched on CampaignId)
Data 360 ssot__EmailEngagement__dlm (joined on BulkEmailMessageId)
Apex aggregation & recipient classification
CampaignReporting subagent response
Private CSV in Salesforce Files
What Was Built
Capabilities
- Conversational summaries of sent, opened, clicked, replied, unsubscribed, and non-engager counts, with explicit bounce-data caveats.
- Grounded recipient lists filtered to non-engagers, openers, or clickers, with a 25-recipient preview and up to 100 on request.
- Category-specific CSV exports of up to 2,500 recipients, saved as a Salesforce File visible only to the requesting user. Asking for the download link again returns the same file instead of exporting again.
- Reusable deployment playbook, permission set, and modular Apex services; no scheduled jobs, Calculated Insights, or custom Salesforce objects required.
Data path
- Campaign →
ListEmail.CampaignId → ssot__EmailEngagement__dlm, joined on BulkEmailMessageId.
- One aggregate Data 360 query per reporting or export request; test sends are excluded.
- Engagement events used:
SEND_STATUS / SENT, OPEN, CLICK, REPLY, UNSUBSCRIBE.
Apex components
JB_Get_Campaign_Engagement: invocable reporting action.
JB_Export_Campaign_Engagement: invocable CSV export action.
JB_Campaign_Engagement_Service: shared resolve → query → classify pipeline.
JB_Campaign_Engagement_Calculator: Data 360 SQL, grouping, and classification.
JB_Campaign_Engagement_Recipient: recipient data type returned to the agent.
JB_Campaign_Engagement_Csv: RFC 4180 CSV writer.
JB_Campaign_List_Email_Lookup: narrow system-mode ListEmail lookup.
JB_Data360_Query_Service: the only class that calls the Data 360 query API (ConnectApi.CdpQuery).
JB_Campaign_Reporting_User permission set: access to the two actions and read access to Campaign, Lead, and Contact.
Agentforce
- A CampaignReporting subagent added to Salesforce's standard Campaign Creation Agent template, with GetCampaignEngagement and ExportCampaignEngagement actions.
- Version 2 of the extended agent is published and active in the development org; version 1 is kept for rollback.
Validation
A real Campaign-scoped Marketing Cloud Next send reached two opted-in test recipients.
Data 360 recorded two sends, one open, one click, and one non-engager. The Agentforce
summaries and recipient categories matched the observed events, and category-specific
CSV files contained the expected recipient data. All 93 reporting Apex tests passed
(93/93: 16 CSV, 18 export, and 59 reporting tests).
Status & Limitations
The reporting extension was exercised with live data and a published, active Campaign
Creation Agent version in a development org. Before customer rollout, additional
checks remain for non-admin permissions, campaign-refinement behavior, client-specific
agent bundle compatibility, Data 360 access, and trusted URLs. Bounce details were not
yet verified with a real bounce. This case study reflects a validated development
implementation, not a production deployment.
- Recipients blocked at send time (not sent) are not reported yet.
- Only the default Data 360 data space is supported.
- Security scanners may inflate open counts.
- Running the actions as a non-admin user still needs validation.
- The Brief-name refinement lookup has not been exercised live.