DocuSign PDFs · SharePoint archive · Microsoft Graph email · Slack alerts
Overview
This project automates the delivery of signed DocuSign documents after they are stored in SharePoint. It collects completed PDFs, prepares a weekly archive, sends the documents by email, and posts status updates to Slack.
I used this pattern as part of the dispatch environment and also for internal delivery of signed consent documents. The public explanation stays generic so the workflow can be discussed without exposing recipients, companies, folder IDs, or original workflow data.
The important part is not only sending an email. The workflow protects the document trail by archiving first, batching large deliveries, and stopping cleanup when the expected archive is missing.
The challenge
Signed documents often need to be delivered after completion, but manual collection from SharePoint is slow and easy to miss when many PDFs arrive during the week.
The workflow needed to create a reliable evidence package, send it to the right destination, and keep the SharePoint folder clean without risking accidental deletion of signed documents.
My role
I built the n8n workflow structure for scheduled collection, SharePoint file handling, archive creation, email delivery through Microsoft Graph, batch handling, Slack reporting, and cleanup safeguards.
I also separated the public case study from the private workflow so only the architecture and sanitized helper patterns are shown.
Workflow structure
Core modules
Signed document collection
The workflow reads the signed document folder and keeps only the completed PDF files that belong to the current delivery scope.
Weekly archive
Before delivery, the files are copied into a dated weekly archive folder. This creates a stable reference point before cleanup runs.
Email delivery preparation
The automation prepares a structured email payload with PDF attachments. When the total attachment size is too large, it splits the delivery into multiple smaller messages.
Safety cleanup
The cleanup branch checks that the weekly archive exists before deleting loose files from the root folder. If the archive is missing, it stops and alerts through Slack.
Operational visibility
Slack messages confirm successful delivery, batch counts, cleanup completion, or safety issues that need manual review.
Technical decisions
Archive first, clean later
The workflow does not delete loose files until it can confirm that the weekly archive exists. This protects signed documents from accidental loss.
Batching protects email delivery
Large attachment sets are split into batches so the delivery can continue without depending on one oversized email.
DocuSign stays visible in the explanation
The project is named broadly, but the documentation makes clear that the workflow handles completed DocuSign PDFs.
Public material is sanitized
The public version explains the architecture and helper logic without exposing original workflow exports, folder IDs, tenant IDs, secrets, recipients, or company-specific text.
Tech stack
Proof / Evidence
This case study is based on a private n8n workflow for signed document delivery. The public proof focuses on architecture, delivery logic, and sanitized snippets. Original workflow JSON, secrets, recipient data, tenant IDs, SharePoint IDs, Slack IDs, and company-specific email text are not published.
Public proof shown on this page
A sanitized architecture diagram showing weekly collection of signed DocuSign PDFs, SharePoint archiving, attachment preparation, email batching, Microsoft Graph delivery, Slack status updates, and safety cleanup.
Live system
Public code & documentation
Sanitized architecture notes and JavaScript helper snippets for signed DocuSign document delivery with SharePoint archiving, Microsoft Graph email batching, cleanup safeguards, and Slack status alerts.
Code excerpt: attachment batching helper
The public snippet shows the attachment batching pattern only. Real recipients, file paths, credentials, and email templates stay private.
function shouldSendAsBatches(files, maxBatchSizeMb = 3.5) {
const batches = [];
let currentBatch = [];
let currentSize = 0;
for (const file of files) {
const sizeMb = Number(file.sizeMb || 0);
if (currentBatch.length && currentSize + sizeMb > maxBatchSizeMb) {
batches.push(currentBatch);
currentBatch = [];
currentSize = 0;
}
currentBatch.push({
name: file.safeName,
contentBytes: file.base64,
});
currentSize += sizeMb;
}
if (currentBatch.length) {
batches.push(currentBatch);
}
return batches.map((attachments, index) => ({
batchNumber: index + 1,
totalBatches: batches.length,
attachments,
}));
}Publication note
The public repository is a documentation and snippet reference only. It must not include original workflow JSON, active credentials, client secrets, tenant IDs, SharePoint drive IDs, Slack workspace identifiers, real recipients, or private email templates.