SharePoint · Microsoft Graph · n8n · recursive crawl · Slack delivery
Overview
This project helps an internal user search SharePoint documents through an assistant workflow. The request can include a document query, a folder hint, a file type, and an instruction to deliver the best match back to Slack.
The workflow searches Microsoft Graph, ranks possible folders, falls back to a bounded recursive crawl when needed, and can deliver a selected file after safety checks.
The private workflow keeps the real SharePoint structure, drive IDs, Slack channel IDs, credentials, and document names inside n8n. The public repo documents only the architecture and reusable helper patterns.
The challenge
Internal document lookup can be slow when files are stored across SharePoint folders, nested structures, and mixed file types. A user might know the topic, a partial folder name, or only the type of file they need.
The challenge was to make search useful from a simple assistant request without exposing the SharePoint structure and without letting fallback logic crawl too much data.
My role
I built the n8n workflow structure for SharePoint search, folder ranking, recursive crawl fallback, file-type filtering, and Slack delivery.
I also prepared the sanitized public documentation and helper snippets so the architecture can be reviewed without publishing workflow exports or internal identifiers.
Workflow structure
Core modules
Main search workflow
The main workflow receives a query, optional file type, optional folder hint, and a delivery flag. It chooses full-drive search, folder-scoped search, or fallback crawl depending on the request and result quality.
Folder hint ranking
When the user gives a folder hint, the workflow searches for candidate folders and ranks them by matching the folder name and parent path against the cleaned query terms.
Recursive crawl fallback
If normal Graph search does not return useful scoped results, a second workflow walks child folders with a queue and a fixed iteration limit. This keeps the assistant useful without crawling SharePoint without bounds.
File delivery guard
When delivery is requested, the selected file is downloaded through Microsoft Graph, checked for binary content and size, then uploaded to Slack only when it is safe to do so.
Technical decisions
Search first, crawl only when needed
Direct Graph search is fast and usually enough. Recursive traversal is kept as a fallback so everyday searches remain responsive.
Folder hints are treated as hints
The assistant does not assume the user knows the exact folder path. It sanitizes the hint, searches candidates, and chooses the best match by score.
File types stay human-readable
Users can ask for PDF, image, email, Excel, Word, or text. The workflow maps those words to extensions before filtering results.
Public repo contains patterns only
The public material documents the architecture and helper logic. Raw workflow exports, drive IDs, credential IDs, Slack IDs, SharePoint paths, and document names stay private.
Tech stack
Proof / Evidence
This case study is based on a private SharePoint search assistant. The public proof focuses on architecture, design decisions, and sanitized snippets. Original workflow exports, drive IDs, folder paths, Slack IDs, credential IDs, document names, and tenant details are not published.
Public proof shown on this page
A sanitized architecture diagram showing the SharePoint document search assistant with Graph search, folder-scoped search, recursive crawl fallback, result formatting, and Slack file delivery.
Live system
Public code & documentation
Sanitized architecture notes and JavaScript helper snippets from an internal SharePoint document search assistant built with n8n, Microsoft Graph, recursive crawl fallback, and Slack file delivery.
Code excerpt: file type filtering
The assistant accepts human file-type words and maps them to file extensions before formatting the SharePoint results.
const TYPE_MAP = {
image: ["jpg", "jpeg", "png", "gif", "webp"],
pdf: ["pdf"],
email: ["msg", "eml"],
excel: ["xlsx", "xls", "csv"],
word: ["docx", "doc"],
};
function filterFilesByType(items, fileType) {
const filesOnly = items.filter((item) => item.file);
const allowed = TYPE_MAP[String(fileType || "").toLowerCase()];
if (!allowed) return filesOnly;
return filesOnly.filter((item) => {
const ext = String(item.name || "").split(".").pop().toLowerCase();
return allowed.includes(ext);
});
}Full sanitized example in snippets/file-result-formatter.js. The repository also documents query cleanup, folder ranking, recursive crawl queue handling, and Slack delivery guardrails.
Publication note
The public repository is a documentation and snippet reference. It does not include original workflow JSON, credentials, SharePoint drive IDs, Slack identifiers, tenant configuration, internal folder paths, or document content.