{ "nodes": [ { "id": "f1142274-898d-43da-a7ff-2b2e03f2dc73", "name": "Execute Workflow Trigger", "type": "n8n-nodes-base.executeWorkflowTrigger", "position": [ 1220, 840 ], "parameters": {}, "typeVersion": 1 }, { "id": "1f407421-2dd6-4e0c-bc74-cfb291e475ed", "name": "Query Confluence", "type": "n8n-nodes-base.httpRequest", "position": [ 1640, 840 ], "parameters": { "url": "https://YOUR_SITE.atlassian.net/wiki/rest/api/search", "options": { "timeout": 30000, "redirect": { "redirect": { "followRedirects": false } }, "response": { "response": { "responseFormat": "json" } } }, "sendQuery": true, "sendHeaders": true, "authentication": "genericCredentialType", "genericAuthType": "httpBasicAuth", "queryParameters": { "parameters": [ { "name": "cql", "value": "={{ $json.cql }}" }, { "name": "limit", "value": "25" } ] }, "headerParameters": { "parameters": [ { "name": "accept", "value": "application/json" } ] }, "method": "GET" }, "typeVersion": 4.2 }, { "id": "f1ab7e79-6bd8-4b87-b6dc-96f9d46cdd16", "name": "Return Knowledge Result", "type": "n8n-nodes-base.code", "position": [ 2040, 840 ], "parameters": { "mode": "runOnceForAllItems", "jsCode": "function sourceSearchReply({ results, wikiBaseUrl }) {\n if (!Array.isArray(results)) throw new Error('Confluence must return a search results array.');\n if (!results.length) return { found: false, response: 'No matching knowledge base article was found.' };\n const first = results[0];\n const title = first?.content?.title;\n const path = first?.content?._links?.webui;\n if (typeof title !== 'string' || !title.trim()) throw new Error('The first search result has no content title.');\n if (typeof path !== 'string' || !path.startsWith('/') || path.startsWith('//') || /[\\s\\u0000-\\u001f\\u007f\\\\]/u.test(path)) throw new Error('The first search result has no valid relative Confluence web link.');\n if (typeof wikiBaseUrl !== 'string' || !/^https:\\/\\/[^/?#@\\s\\\\]+\\/wiki\\/?$/i.test(wikiBaseUrl)) throw new Error('Confluence must supply a valid HTTPS wiki base URL.');\n const base = wikiBaseUrl.replace(/\\/$/, '');\n const link = /^\\/wiki(?:[/?#]|$)/.test(path) ? base.slice(0, -5) + path : base + path;\n const excerpt = first.excerpt ?? '';\n if (typeof excerpt !== 'string') throw new Error('The Confluence excerpt must be text.');\n return { found: true, response: '\"Title\": ' + JSON.stringify(title) + '\\n\"Link\": ' + JSON.stringify(link) + '\\n\"Content\": ' + excerpt + '\\nWhen users request the password, make sure to send them the link above to reset it in markdown. ' };\n}\n\nfunction formatConfluenceSearch({ results, wikiBaseUrl }) {\n if (!Array.isArray(results)) throw new Error('Confluence must return a search results array.');\n return sourceSearchReply({ results: results.map(result => result.raw), wikiBaseUrl });\n}\n\nreturn $input.all().map((item,index)=>({json:sourceSearchReply({results:item.json.results,wikiBaseUrl:item.json._links?.base}),pairedItem:{item:index}}));\n" }, "typeVersion": 2 }, { "id": "manual-knowledge-search", "name": "Run Search", "type": "n8n-nodes-base.manualTrigger", "typeVersion": 1, "position": [ -360, 100 ], "parameters": {} }, { "id": "manual-knowledge-query", "name": "Search Query", "type": "n8n-nodes-base.set", "typeVersion": 3.4, "position": [ -160, 100 ], "parameters": { "assignments": { "assignments": [ { "id": "knowledge-query", "name": "query", "type": "string", "value": "password reset" } ] }, "options": {} } }, { "id": "prepare-knowledge-search", "name": "Prepare Search Query", "type": "n8n-nodes-base.code", "typeVersion": 2, "position": [ 60, 300 ], "parameters": { "mode": "runOnceForAllItems", "jsCode": "function makeCqlQuery({ query }) {\n if (typeof query !== 'string' || !query.trim()) throw new Error('Supply a nonempty Confluence search query.');\n if (/[\\u0000-\\u001f\\u007f]/u.test(query)) throw new Error('Use a single-line search query without control characters.');\n const text = query.trim();\n return { cql: 'text ~ ' + JSON.stringify(text) };\n}\n\nfunction wikiRoot(value) {\n if (typeof value !== 'string' || !/^https:\\/\\/[^/?#@\\s\\\\]+\\/wiki\\/?$/i.test(value)) throw new Error('Use your Confluence HTTPS wiki base URL ending in /wiki.');\n if (/YOUR_SITE/i.test(value)) throw new Error('Configure your Confluence wiki base URL before searching.');\n return value.replace(/\\/$/, '');\n}\n\nfunction prepareConfluenceSearch({ query, wikiBaseUrl }) {\n return { ...makeCqlQuery({ query }), wikiBaseUrl: wikiRoot(wikiBaseUrl) };\n}\n\nreturn $input.all().map((item,index)=>({json:makeCqlQuery({query:item.json.query}),pairedItem:{item:index}}));\n" } } ], "pinData": {}, "connections": { "Run Search": { "main": [ [ { "node": "Search Query", "type": "main", "index": 0 } ] ] }, "Search Query": { "main": [ [ { "node": "Prepare Search Query", "type": "main", "index": 0 } ] ] }, "Execute Workflow Trigger": { "main": [ [ { "node": "Prepare Search Query", "type": "main", "index": 0 } ] ] }, "Prepare Search Query": { "main": [ [ { "node": "Query Confluence", "type": "main", "index": 0 } ] ] }, "Query Confluence": { "main": [ [ { "node": "Return Knowledge Result", "type": "main", "index": 0 } ] ] } }, "name": "Confluence Knowledge Search", "active": false }