Bulk Export Results Processor & SharePoint Archiver
Salesforce action: GetJobResults. After a bulk query job completes, retrieves the result CSV data, saves it to a date-stamped folder in a SharePoint document library, and emails the requesting team a link to the exported file.
Provided as-is, without warranty of any kind. Review and test each pattern in a non-production environment before deploying it to live automations. See our Terms.
Overview
This flow demonstrates the end-to-end pattern for retrieving a completed Salesforce Bulk API 2.0 job's results and archiving them to SharePoint. On button press, it pulls the job's result CSV via the Salesforce connector's GetJobRecordResults action, writes the CSV into a date-stamped subfolder of a SharePoint document library, and emails the requesting team a styled HTML notification with the job context, archive path, and SharePoint site link.
It is a reference implementation of three complementary patterns: (1) invoking a Salesforce Bulk API result endpoint through the native connector rather than HTTP, (2) using env var-driven SharePoint site/library/folder paths with a runtime-generated date subfolder, and (3) a recipient-fallback expression that prefers a per-invocation requester email but falls back to a solution-level notification env var when none is supplied.
Use Case
Data operations teams routinely run Salesforce Bulk API jobs to ingest or reconcile large record sets (tens of thousands to millions of rows). Once a job completes, the result CSV — which lists every successful, failed, or unprocessed record — needs to be archived to durable storage, distributed to the requesting business owner, and retained for audit purposes. This flow removes the manual "download CSV from Salesforce, upload to SharePoint, email the team" loop: an on-demand button-triggered flow that accepts a job ID and result type, then does the archive-and-notify cycle in one shot.
Typical operators: IT Admins, Developers, and Operations teams who manage Salesforce bulk operations. The flow also serves as a starting point for automating scheduled cleanup of completed jobs, chaining into an error-analysis workflow, or integrating with a broader data-ops orchestration suite.
The flow is ideal for teams that:
- IT Admins managing Salesforce bulk operations
- Developers building data-ops orchestration suites
- Operations teams archiving Salesforce job results to SharePoint
- Teams that need automated audit trails for bulk data jobs
- Organizations standardizing CSV archival from Salesforce to SharePoint
Flow Architecture
Manually trigger a flow (Button)
Manual triggerButton trigger with three text inputs: JobId (required) — the Salesforce Bulk API 2.0 job ID whose results will be retrieved; ResultType (required, default `successfulResults`) — one of `successfulResults`, `failedResults`, or `unprocessedRecords`; RequesterEmail (optional) — email to notify; falls back to flowlibs_NotificationEmailAddress when blank.
Initialize variables (4x parallel)
Initialize variableFour InitializeVariable actions run in parallel and bind the flow's solution env vars to named variables: varSharePointSite, varArchiveLibrary, varArchiveFolder, varNotificationEmail. This isolates connector calls from the env var layer so tenants only have to rewire env var values (not flow logic) to retarget a new SharePoint site.
Compose DateFolder
ComposeEmits today's date as `yyyy-MM-dd` via `utcNow('yyyy-MM-dd')`. This becomes the leaf folder name so that multiple jobs archived on the same day group together under the library.
Compose FullFolderPath
ComposeConcatenates varArchiveLibrary, varArchiveFolder, and the dated folder into a single server-relative path (e.g., `/Shared Documents/Salesforce Bulk Exports/2026-04-16`) for SharePoint CreateFile.
Compose FileName
ComposeGenerates a unique CSV file name: `BulkJobResults_{JobId}_{yyyyMMddHHmmss}.csv`. Embedding the job ID plus a second-granular timestamp guarantees uniqueness within the date-stamped folder and makes the filename self-documenting when operators browse the archive.
Compose EffectiveRecipient
ComposeEvaluates `if(empty(coalesce(triggerBody()?['RequesterEmail'], '')), varNotificationEmail, triggerBody()?['RequesterEmail'])` — uses the requester email if the caller supplied one, otherwise the flow-level notification fallback.
Environment Variables
| Schema name | Type | Default | Description |
|---|---|---|---|
| flowlibs_SharePointSiteURL | String | https://your-tenant.sharepoint.com | Target SharePoint site for the archive library. Set to your tenant's SharePoint root or specific site URL. |
| flowlibs_BulkExportArchiveLibrary | String | /Shared Documents | Server-relative path of the document library that hosts the archive. |
| flowlibs_BulkExportArchiveFolder | String | Salesforce Bulk Exports | Subfolder name inside the archive library. A `yyyy-MM-dd` leaf is appended at runtime. |
| flowlibs_NotificationEmailAddress | String | <configure> | Fallback recipient when the trigger's RequesterEmail input is empty. Set to your team's distribution list or notification alias. |
Connectors & Connections
| Connector | API name | Actions used |
|---|---|---|
| Salesforce | shared_salesforce | GetJobRecordResults |
| SharePoint | shared_sharepointonline | CreateFile |
| Office 365 Outlook | shared_office365 | SendEmailV2 |
Note — All connections are referenced as solution connection references; the flow is portable between environments as long as a connection is mapped at import time.
Customization Guide
Almost every realistic variant of this flow can be implemented by changing environment variable values. A few cases require small edits inside the flow definition — those are called out explicitly below.
- Retarget to a different SharePoint site/library
- Update flowlibs_SharePointSiteURL, flowlibs_BulkExportArchiveLibrary, and flowlibs_BulkExportArchiveFolder env var values in the destination environment. No flow edits are required. Note that flowlibs_BulkExportArchiveLibrary expects the server-relative path, so /Shared Documents for the default library or /sites/{site}/{library} style for nested libraries.
- Change the date-folder granularity
- Edit Compose_DateFolder to use utcNow('yyyy-MM') for monthly grouping or utcNow('yyyy-MM-dd-HH') for hourly rotation. The downstream Compose_FullFolderPath automatically picks up the change.
- Adjust result type behavior
- The flow accepts successfulResults, failedResults, and unprocessedRecords per Salesforce Bulk API 2.0 conventions. To force one result type and hide the input from callers, delete the ResultType property from the trigger schema and hardcode "resultType": "successfulResults" in Get_Job_Results.
- Convert to automated scheduling
- Replace the manual trigger with a Recurrence trigger + Salesforce GetAllJobs (filtered to State eq 'JobComplete') + Apply to Each. The archive/notify pipeline (steps 6–9) stays unchanged; the per-job loop wraps steps 6–9 with items('For_Each_Job')?['Id'] substituted for triggerBody()?['JobId'].
- Switch notification channel to Teams
- Swap Send_Notification_Email with Teams PostMessageToConversation — keep the Compose_Email_Body action (the HTML renders cleanly as a Teams card body). Replace emailMessage/To/Subject/Body with body/recipient/groupId,
Key Expressions
The flow is intentionally light on Power Fx / WDL gymnastics — the heaviest expressions are the branch-name concatenation and the approval outcome check. They are listed below in the order they appear in the flow.
EXPR.01Date folder name
Used in Compose_DateFolder to generate today's date as the leaf folder name (yyyy-MM-dd).
EXPR.02Full folder path
Builds the server-relative SharePoint folder path from the library, subfolder, and date.
EXPR.03Unique CSV file name
Embeds the job ID and a second-granular timestamp for uniqueness and self-documentation.
EXPR.04Recipient fallback
Uses the trigger's RequesterEmail when supplied, otherwise the flow-level notification email. The coalesce() normalizes missing keys (null) to an empty string so empty() works consistently across both "not supplied" and "supplied as empty string" cases.
EXPR.05Dynamic email subject
Subject line for the SendEmailV2 notification, including the job ID for quick scanning.
Comments
Sign in to join the conversation.
Sign inNo comments yet. Be the first to share your experience with this flow.