{
  "id": "FKbKIlRnRWzCMkUZ",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Generate Research Ideas from PDF Documents based on Content Gaps",
  "tags": [
    {
      "id": "66wgFoDi9Xjl74M3",
      "name": "Support",
      "createdAt": "2025-05-21T17:06:32.355Z",
      "updatedAt": "2025-05-21T17:06:32.355Z"
    },
    {
      "id": "kRM0hQV2zw7VxrON",
      "name": "Research",
      "createdAt": "2025-05-21T19:44:19.136Z",
      "updatedAt": "2025-05-21T19:44:19.136Z"
    },
    {
      "id": "sJk9cUvmMU8FkJXv",
      "name": "AI",
      "createdAt": "2025-05-20T13:16:15.636Z",
      "updatedAt": "2025-05-20T13:16:15.636Z"
    }
  ],
  "nodes": [
    {
      "id": "f05941ad-6b05-4f7e-8d63-467a4f289978",
      "name": "Convert File to PDF",
      "type": "n8n-nodes-base.httpRequest",
      "disabled": true,
      "position": [
        2260,
        180
      ],
      "parameters": {
        "url": "https://v2.convertapi.com/convert/pdf/to/txt",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "responseFormat": "text"
            }
          }
        },
        "sendBody": true,
        "contentType": "multipart-form-data",
        "sendHeaders": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "file",
              "parameterType": "formBinaryData",
              "inputDataFieldName": "data"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/octet-stream"
            }
          ]
        }
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.2
    },
    {
      "id": "46fdd8ba-70b2-4943-8df7-958f549b65c9",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2220,
        -400
      ],
      "parameters": {
        "color": 2,
        "width": 360,
        "height": 820,
        "content": "## Optional: Better PDF Conversion\n\n### Standard Map PDF to Text node will split your PDF files into very short chunks, which deteriorates retrieval. \n\nUse can use [ConvertAPI](https://convertapi.com?ref=4l54n) which is a high-quality convertor that will respect the layout of the original document and not cut the paragraphs into short chunks. \n\nHere is an HTTP node that makes a request to their API to convert the PDF into text. If you have a ConvertAPI account, you can replace the \"Extract Text from PDF\" node in Step 3 with this node. \n\nNote that you will need to map the text output from this node correctly in the Step 4 after.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "70af249f-8908-48d5-907c-0c84de4e5074",
      "name": "On form submission",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        -380,
        -60
      ],
      "parameters": {
        "options": {
          "appendAttribution": false
        },
        "formTitle": "Find Content Gaps in Your PDF Files",
        "formFields": {
          "values": [
            {
              "fieldType": "file",
              "fieldLabel": "Add Your Files",
              "acceptFileTypes": ".pdf"
            }
          ]
        },
        "formDescription": "Upload the files you'd like to analyze and we will extract content gaps and interesting questions based on them."
      },
      "typeVersion": 2.2
    },
    {
      "id": "6290cac1-3bc5-46e0-b8eb-5196a15e7ce7",
      "name": "Convert binary files to PDF",
      "type": "n8n-nodes-base.code",
      "position": [
        -60,
        -60
      ],
      "parameters": {
        "jsCode": "let results = [];\n\nfor (let item of items) {\n    if (item.binary) {\n        // If there's binary data in the item, process each binary file\n        for (let key in item.binary) {\n            // Use the key as the file name\n            let binaryKey = key.replace(/\\s/g, '_'); // Replace spaces with underscores for the key\n            results.push({\n                json: {\n                    fileName: binaryKey\n                },\n                binary: {\n                    [binaryKey]: item.binary[key] // Use the modified key for the binary data\n                }\n            });\n        }\n    }\n}\n\nreturn results;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "2c90baa0-2576-4166-819e-738f5f0c11cd",
      "name": "Extract text from PDF files",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        280,
        -60
      ],
      "parameters": {
        "options": {},
        "operation": "pdf",
        "binaryPropertyName": "={{ $json.fileName }}"
      },
      "typeVersion": 1
    },
    {
      "id": "dbd08770-dbcd-4142-a54f-3da8beab15b5",
      "name": "Prepare for InfraNodus",
      "type": "n8n-nodes-base.code",
      "position": [
        580,
        -60
      ],
      "parameters": {
        "jsCode": "\nlet plainText = '' // we send plain text from all the PDFs to InfraNodus for analysis\n\nconst randomNum = Math.floor(Math.random() * 3); // replace this with a 0 if you'd like to address the biggest gap in the knowledge graph\n\nfor (let item of items) {\n   plainText += item.json.text + '\\n\\n'  \n}\n\n\nreturn {text: plainText, randomNum};"
      },
      "typeVersion": 2
    },
    {
      "id": "facd169e-b993-4762-a603-f167e1d0aad5",
      "name": "Display on the Form to the User",
      "type": "n8n-nodes-base.form",
      "position": [
        1840,
        -40
      ],
      "parameters": {
        "operation": "completion",
        "respondWith": "showText",
        "responseText": "=<br>\n<h2>Question:</h2>\n<h3>{{ $('InfraNodus GraphRAG Question Generator').item.json.aiAdvice[0].text }}</h3>\n<br>\n<h2>Response:</h2>\n<h3>{{ $json.aiAdvice[0].text }}</h3>\n<br>\n"
      },
      "typeVersion": 1
    },
    {
      "id": "cd16a781-fd46-4c3d-962b-1207b950f7ba",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -420,
        -400
      ],
      "parameters": {
        "height": 520,
        "content": "## Step 1: User uploads the PDF files for analysis\n\n### You can expose this endpoint and make it publicly available via a URL to your organization."
      },
      "typeVersion": 1
    },
    {
      "id": "300eb3e7-0c37-460f-a0c1-926eb07a68c7",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -120,
        -400
      ],
      "parameters": {
        "width": 280,
        "height": 520,
        "content": "## Step 2: Convert uploaded binaries into PDF files\n\n### We need to convert the binaries uploaded to the PDF files so we can extract text from them."
      },
      "typeVersion": 1
    },
    {
      "id": "bde9366e-452a-43a7-8f78-a563bb3c23b3",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        220,
        -400
      ],
      "parameters": {
        "width": 220,
        "height": 520,
        "content": "## Step 3: Extract plain text from PDF files\n\n### For better quality text extraction, you can use the optional [ConvertAPI](https://convertapi.com?ref=4l54n) node to the right, which respects the files' original formatting."
      },
      "typeVersion": 1
    },
    {
      "id": "9e4d5981-49bf-4062-a4e2-874e43f945f8",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        520,
        -400
      ],
      "parameters": {
        "width": 220,
        "height": 520,
        "content": "## Step 4: Combine extracted text into a text string\n\n### Prepare data for InfraNodus: combine all the extracted text into a text string and also tell InfraNodus the gap depth it should use when generating advice"
      },
      "typeVersion": 1
    },
    {
      "id": "5352de5f-5d0f-4e66-8a14-a326290fbc57",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        820,
        -400
      ],
      "parameters": {
        "width": 380,
        "height": 820,
        "content": "## Step 5: Use InfraNodus GraphRAG to build a knowledge graph, find the gap, and generate a research question based on it.\n\n### [InfraNodus](https://infranodus.com) builds a knowledge graph from all the texts, identifies the topical clusters that are least connected, and generates a research question that has a potential to bridge them in a new way.\n\n\ud83d\udea8 PROVIDE YOUR INFRANODUS API KEY HERE"
      },
      "typeVersion": 1
    },
    {
      "id": "34aa69a0-2a4d-4c2c-b20a-29aa209276b6",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1700,
        -400
      ],
      "parameters": {
        "width": 380,
        "height": 820,
        "content": "## Step 7: Show question / prompt to the user\n\n### Optionally, you can feed the response to your other n8n workflow or expose it via a webhook and show it in your own app using an iframe."
      },
      "typeVersion": 1
    },
    {
      "id": "bfad357a-e426-4bda-aa72-5df44b54be73",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -420,
        180
      ],
      "parameters": {
        "color": 5,
        "width": 1160,
        "height": 1000,
        "content": "# How does InfraNodus GraphRAG generate research questions?\n\n## [InfraNodus](https://infranodus.com) GraphRAG helps avoid generic responses and LLM bias through analyzing your text's structure. Here's how it works:\n\n### 1. It represents your text as a network of concepts and relations building a knowledge graph.\n\n### 2. It then identifies the clusters of cocnepts that are furthest apart from each other \u2014 they appear in the same context (your texts) but are not well connected.\n\n### 3. InfraNodus will then use the AI to generate a question / prompt that bridges this gap \u2014 touching upon relevant topics but connecting them in a new way.\n\n![structural gap infranodus](https://infranodus.com/images/front/infranodus-structural-gaps-ideas.jpg)"
      },
      "typeVersion": 1
    },
    {
      "id": "d716e200-6706-4eeb-8714-34bc8a0f1229",
      "name": "InfraNodus GraphRAG Question Generator",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        960,
        0
      ],
      "parameters": {
        "url": "=https://infranodus.com/api/v1/graphAndAdvice?doNotSave=true&optimize=develop&includeGraph=false&includeGraphSummary=true&gapDepth={{ $json.randomNum }}",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "aiTopics",
              "value": "true"
            },
            {
              "name": "requestMode",
              "value": "question"
            },
            {
              "name": "text",
              "value": "={{ $json.text }}"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "b07a00e9-9926-46e8-bc33-e1958d708f21",
      "name": "InfraNodus GraphRAG Response Generator",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1380,
        0
      ],
      "parameters": {
        "url": "=https://infranodus.com/api/v1/graphAndAdvice?doNotSave=true&optimize=imagine&includeGraph=false&includeGraphSummary=true",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "aiTopics",
              "value": "true"
            },
            {
              "name": "requestMode",
              "value": "response"
            },
            {
              "name": "text",
              "value": "={{ $('Prepare for InfraNodus').item.json.text }}"
            },
            {
              "name": "prompt",
              "value": "={{ $json.aiAdvice[0].text }}"
            }
          ]
        },
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "eea5f81c-5bd8-49f3-854f-9f94992bf268",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1240,
        -400
      ],
      "parameters": {
        "width": 380,
        "height": 600,
        "content": "## Step 6: Generate a Response using InfraNodus GraphRAG API\n\n### Use the gap question generated by [InfraNodus](https://infranodus.com) in the previous step to generate an idea based on your PDF documents\n\n\ud83d\udea8 PROVIDE YOUR INFRANODUS API KEY HERE"
      },
      "typeVersion": 1
    },
    {
      "id": "70996dc5-232d-4a3d-82e3-f36575e305bf",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1240,
        280
      ],
      "parameters": {
        "color": 2,
        "width": 380,
        "height": 900,
        "content": "## Optional: Get the answers from a different collection of papers\n\n### You can use a different collection of PDFs to generate an answer, which can be especially good for cross-disciplinary research.\n\nSimply use a different set of PDFs here and add their text output to the `text` field of the InfraNodus HTTP node.\n\nYou can also use an existing InfraNodus \"expert\" graph that you save in the system to derive answers for your queries."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "c12cc761-44a5-40b0-9a17-6349f2e082d8",
  "connections": {
    "On form submission": {
      "main": [
        [
          {
            "node": "Convert binary files to PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare for InfraNodus": {
      "main": [
        [
          {
            "node": "InfraNodus GraphRAG Question Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Convert binary files to PDF": {
      "main": [
        [
          {
            "node": "Extract text from PDF files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract text from PDF files": {
      "main": [
        [
          {
            "node": "Prepare for InfraNodus",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "InfraNodus GraphRAG Question Generator": {
      "main": [
        [
          {
            "node": "InfraNodus GraphRAG Response Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "InfraNodus GraphRAG Response Generator": {
      "main": [
        [
          {
            "node": "Display on the Form to the User",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}