AutomationFlowsAI & RAG › Triage Pubmed Clinical Literature with Gemini and Google Sheets and Docs

Triage Pubmed Clinical Literature with Gemini and Google Sheets and Docs

ByHiroyuki Yamasaki @hxshanqi on n8n.io

Automatically retrieve recent PubMed articles, identify the three papers most worth reading first using AI, and generate structured clinical literature triage reports in Google Sheets and Google Docs. Reads the first pending literature request from the Google Sheets "Search…

Cron / scheduled trigger★★★★☆ complexityAI-powered22 nodesXMLGoogle SheetsHTTP RequestGoogle DocsChain LlmGoogle Gemini Chat
AI & RAG Trigger: Cron / scheduled Nodes: 22 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #16805 — we link there as the canonical source.

This workflow follows the Chainllm → Google Sheets recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "spxBgUi30QKDKN0q",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI-Powered PubMed Literature Triage",
  "tags": [],
  "nodes": [
    {
      "id": "131c381a-620a-4c6d-9c05-93c744b629d0",
      "name": "Parse PubMed XML",
      "type": "n8n-nodes-base.xml",
      "position": [
        -480,
        -304
      ],
      "parameters": {
        "options": {},
        "dataPropertyName": "=data"
      },
      "typeVersion": 1
    },
    {
      "id": "038fa360-1fe3-4583-910b-e5bbe4a9ea58",
      "name": "Append row in sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1104,
        144
      ],
      "parameters": {
        "columns": {
          "value": {
            "Rank": "={{ $json.rank }}",
            "Title": "={{ $json.title }}",
            "Journal": "={{ $json.journal }}",
            "Keyword": "={{ $json.keyword }}",
            "Pub Date": "={{ $json.pub_date }}",
            "Disclaimer": "={{ $json.disclaimer }}",
            "Pubmed URL": "={{ $json.pubmed_url }}",
            "Read Priority": "={{ $json.read_priority }}",
            "Summary 30sec": "={{ $json.summary_30sec }}",
            "Why Read First": "={{ $json.why_read_first }}",
            "Practice Impact": "={{ $json.practice_impact }}",
            "Priority Reason": "={{ $json.priority_reason }}",
            "Clinical Takeaway": "={{ $json.clinical_takeaway }}",
            "Evidence Snapshot": "={{ $json.evidence_snapshot }}",
            "Abstract Confidence": "={{ $json.abstract_confidence }}",
            "Full Text Checkpoints": "={{ $json.full_text_checkpoints.join(\"\\n\")  }}",
            "Clinical Question Match": "={{ $json.clinical_question_match }}"
          },
          "schema": [
            {
              "id": "Keyword",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Keyword",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Rank",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Rank",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Title",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Title",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Journal",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Journal",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pub Date",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Pub Date",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Pubmed URL",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Pubmed URL",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Summary 30sec",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Summary 30sec",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Clinical Takeaway",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Clinical Takeaway",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Evidence Snapshot",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Evidence Snapshot",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Read Priority",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Read Priority",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Priority Reason",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Priority Reason",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Why Read First",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Why Read First",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Practice Impact",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Practice Impact",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Clinical Question Match",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Clinical Question Match",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Full Text Checkpoints",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Full Text Checkpoints",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Abstract Confidence",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Abstract Confidence",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Disclaimer",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Disclaimer",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1721492144,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM/edit#gid=1721492144",
          "cachedResultName": "Triage Results"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM/edit?usp=drivesdk",
          "cachedResultName": "AI-Powered PubMed Literature Triage"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "cbf47341-f8b1-47cf-bb98-f86c91421b1a",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1648,
        -304
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours"
            }
          ]
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "07c1b48a-f510-4582-962e-0e930d8eddd1",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1744,
        -544
      ],
      "parameters": {
        "color": 4,
        "width": 816,
        "height": 432,
        "content": "\n\n## Step 1 - Request Intake\n\n\u2022 Poll Google Sheets\n\u2022 Prepare search parameters\n\u2022 Mark request as Processing"
      },
      "typeVersion": 1
    },
    {
      "id": "7e41537d-d4b8-44b8-84b8-af855c0c5c58",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -896,
        -544
      ],
      "parameters": {
        "color": 5,
        "width": 960,
        "height": 432,
        "content": "\n\n## Step 2 - PubMed Retrieval\n\n\u2022 Search PubMed                                                                                                  \n\u2022 Download article metadata\n\u2022 Normalize article information\n\u2022 Aggregate candidate papers"
      },
      "typeVersion": 1
    },
    {
      "id": "629dd04e-7575-486f-b7ae-6ef393c547af",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1744,
        -64
      ],
      "parameters": {
        "color": 6,
        "width": 544,
        "height": 544,
        "content": "\n\n## Step 3 - AI Clinical Triage\n\n\u2022 Compare candidate articles\n\u2022 Select Top 3\n\u2022 Generate structured clinical evaluation\n\n\n\n\n\n\n\n\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000\u3000"
      },
      "typeVersion": 1
    },
    {
      "id": "682f9fd0-0b75-4f8d-9c56-7c6adb653d27",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1168,
        -64
      ],
      "parameters": {
        "color": 2,
        "width": 1024,
        "height": 544,
        "content": "\n\n## Step 4 - Reporting\n\n\u2022 Save structured results\n\u2022 Generate Google Docs report\n\u2022 Mark request as Completed"
      },
      "typeVersion": 1
    },
    {
      "id": "8ae6e9ae-a446-4c85-850c-ae90b3453088",
      "name": "Load Request",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1472,
        -304
      ],
      "parameters": {
        "options": {
          "returnFirstMatch": true
        },
        "filtersUI": {
          "values": [
            {
              "lookupValue": "pending",
              "lookupColumn": "Status"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM/edit#gid=0",
          "cachedResultName": "Search Requests"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM/edit?usp=drivesdk",
          "cachedResultName": "AI-Powered PubMed Literature Triage"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "1624cf78-2f45-42be-b712-6a6b9e6d1875",
      "name": "Build Query",
      "type": "n8n-nodes-base.set",
      "position": [
        -1312,
        -304
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "={\n  \"keyword\": \"{{ $json.Keyword }}\",\n  \"clinical_question\": \"{{ $json['Clinical Question'] }}\",\n  \"specialty\": \"{{ $json.Specialty }}\",\n  \"max_results\": {{ $json['Max Results'] }},\n  \"output_language\": \"{{ $json['Output Language'] }}\",\n  \"row_number\": {{ $json.row_number }}\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "a77ddea1-2c30-4c85-9a4c-871af30952a9",
      "name": "Search PubMed",
      "type": "n8n-nodes-base.httpRequest",
      "maxTries": 2,
      "position": [
        -832,
        -304
      ],
      "parameters": {
        "url": "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "db",
              "value": "pubmed"
            },
            {
              "name": "term",
              "value": "={{ $('Load Request').item.json.Keyword }}"
            },
            {
              "name": "sort",
              "value": "pub_date"
            },
            {
              "name": "retmax",
              "value": "={{ $json.max_results }}"
            },
            {
              "name": "retmode",
              "value": "json"
            }
          ]
        }
      },
      "retryOnFail": false,
      "typeVersion": 4.3
    },
    {
      "id": "2f153b23-75fa-4bcb-b466-079c58311783",
      "name": "Fetch Details",
      "type": "n8n-nodes-base.httpRequest",
      "maxTries": 2,
      "position": [
        -656,
        -304
      ],
      "parameters": {
        "url": "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi",
        "options": {},
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "db",
              "value": "pubmed"
            },
            {
              "name": "id",
              "value": "={{ $json.esearchresult.idlist.join(\",\") }}"
            },
            {
              "name": "rettype",
              "value": "abstract"
            },
            {
              "name": "retmode",
              "value": "xml"
            }
          ]
        }
      },
      "retryOnFail": false,
      "typeVersion": 4.3
    },
    {
      "id": "5046b3a3-226d-471f-a8b3-4ebf560234da",
      "name": "Normalize",
      "type": "n8n-nodes-base.code",
      "position": [
        -304,
        -304
      ],
      "parameters": {
        "jsCode": "const articles = $input.first().json.PubmedArticleSet.PubmedArticle;\n\nreturn articles.map(article => {\n  const a = article.MedlineCitation.Article;\n\n  const abstract = a.Abstract?.AbstractText\n    ? (Array.isArray(a.Abstract.AbstractText)\n        ? a.Abstract.AbstractText.map(t => t._ ?? t).join(\"\\n\")\n        : a.Abstract.AbstractText._ ?? a.Abstract.AbstractText)\n    : \"\";\n\nconst articleIdsRaw =\n  article.PubmedData?.ArticleIdList?.ArticleId ?? [];\n\nconst articleIds = Array.isArray(articleIdsRaw)\n  ? articleIdsRaw\n  : [articleIdsRaw];\n\nconst doi =\n  articleIds.find(id => id.IdType === \"doi\")?._ ?? \"\";\n\n  const pmid = article.MedlineCitation.PMID._;\n\n  return {\n    json: {\n      pmid,\n      url: `https://pubmed.ncbi.nlm.nih.gov/${pmid}/`,\n      title: typeof a.ArticleTitle === \"string\"\n        ? a.ArticleTitle\n        : [\n            a.ArticleTitle?._,\n            a.ArticleTitle?.i,\n            a.ArticleTitle?.b\n          ]\n            .flat()\n            .map(x => typeof x === \"string\" ? x : Object.values(x ?? {}).join(\" \"))\n            .filter(Boolean)\n            .join(\" \")\n            .replace(/\\s+/g, \" \")\n            .trim(),\n      abstract,\n      journal: a.Journal?.Title ?? \"\",\n      publication_date:\n        a.Journal?.JournalIssue?.PubDate?.Year ??\n        article.MedlineCitation.DateCompleted?.Year ??\n        \"\",\n      doi\n    }\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "40a9aa67-7753-4ba3-b16a-ff373e663e0c",
      "name": "Aggregate",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        -144,
        -304
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "063a6330-4204-44a1-9241-c1c7e2ea213a",
      "name": "Write Report",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        -544,
        144
      ],
      "parameters": {
        "actionsUi": {
          "actionFields": [
            {
              "text": "={{ $('Build Report').item.json.report }}",
              "action": "insert"
            }
          ]
        },
        "operation": "update",
        "documentURL": "={{ $json.id }}"
      },
      "credentials": {
        "googleDocsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "bbaa28fc-5d0d-4452-8301-5e46a50829c6",
      "name": "Clinical Literature Triage",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "position": [
        -1696,
        144
      ],
      "parameters": {
        "text": "=System Message\n\nYou are an expert clinical literature triage assistant for medical specialists.\n\nYour role is NOT to summarize every paper.\n\nYour role is to compare multiple PubMed articles and identify the three papers with the highest clinical reading value for the specified medical specialty and clinical question.\n\nEvaluate each article from the perspective of an experienced practicing clinician.\n\nPrioritize:\n- Relevance to the specified medical specialty\n- Relevance to the clinical question\n- Human clinical evidence whenever available\n- High-quality evidence\n- Potential to change or improve clinical practice\n- Diagnostic, therapeutic, prognostic, procedural, imaging, prevention, complication management, or patient counseling value\n- Strong translational value when clearly applicable\n\nDeprioritize:\n- Pure basic science with limited clinical applicability\n- Animal-only or in vitro studies unless their translational significance is exceptionally high\n- Broad biological studies with weak specialty relevance\n- Case reports with limited generalizability\n- Editorials, comments, or letters\n- Review articles unless they provide exceptional clinical value\n\nRank articles primarily by their potential impact on day-to-day clinical practice.\nBase your evaluation primarily on the information available in the title and abstract.\n\nDo not assume methods, results, or limitations that are not explicitly stated.\n\nWhen important information is missing from the abstract, state that it should be verified in the full text rather than making assumptions.\n\nReturn ONLY valid JSON.\n\nDo NOT use Markdown.\n\nDo NOT include explanations outside the JSON output.\n\n\nUser Message\n\nOutput Language:\n{{ $('Load Request').item.json['Output Language'] }}\n\nGenerate ALL explanatory fields in the specified language.\n\nDo NOT translate:\n- Article titles\n- Journal names\n- PubMed URLs\n- DOI\n\nSummary 30sec should be concise enough to read in approximately 30 seconds (about 80\u2013120 English words or an equivalent length in the requested language).\nwhy_read_first should be a single concise sentence (approximately 10\u201320 words in English, or an equivalent length in the requested language) explaining why this paper should be read before the others.\nEvidence Snapshot should summarize only objective facts explicitly stated in the title or abstract.\n\nUse the following format:\n\nStudy type:\nPopulation/Model:\nPrimary outcome:\nKey limitation:\n\nDo not infer or invent information that is not explicitly described in the abstract.\n\nIf information is unavailable, write \"Not reported\".\n\nRank the selected papers by considering:\n\n- Relevance to the specialty\n- Relevance to the clinical question\n- Quality of evidence\n- Potential impact on clinical practice\n- Novelty\n- Likelihood of influencing day-to-day clinical decision-making\n\nIf multiple papers have similar scientific quality, prioritize the paper with greater immediate clinical usefulness.\n\nKeyword:\n{{ $('Load Request').item.json.Keyword }}\n\nClinical Question:\n{{ $('Load Request').item.json['Clinical Question'] }}\n\nSpecialty:\n{{ $('Load Request').item.json.Specialty }}\n\nEvaluate the following PubMed articles.\n\nInput Articles:\n\n{{ JSON.stringify($json.data, null, 2) }}\n\nSelect ONLY the best three articles.\n\nReturn the result using EXACTLY the following JSON schema:\n\n{\n  \"selected_papers\": [\n    {\n      \"rank\": 1,\n      \"keyword\": \"\",\n      \"title\": \"\",\n      \"journal\": \"\",\n      \"pub_date\": \"\",\n      \"pubmed_url\": \"\",\n      \"summary_30sec\": \"\",\n      \"clinical_takeaway\": \"\",\n      \"evidence_snapshot\": \"Study type: ...\\nPopulation/Model: ...\\nPrimary outcome: ...\\nKey limitation: ...\",\n      \"read_priority\": \"\",\n      \"why_read_first\": \"\",\n      \"priority_reason\": \"\",\n      \"practice_impact\": \"\",\n      \"clinical_question_match\": \"\",\n      \"full_text_checkpoints\": [\n        \"\",\n        \"\",\n        \"\"\n      ],\n      \"abstract_confidence\": \"\",\n      \"disclaimer\": \"\"\n    }\n  ]\n}\n\nAdditional requirements:\n\n- Return exactly three papers.\n- Do not invent information.\n- If information is unavailable, use \"Not reported\".\n- Keep every field concise and clinically useful.\n- read_priority must be one of:\n  - High\n  - Medium\n  - Low\n- abstract_confidence must be one of:\n  - High\n  - Medium\n  - Low",
        "batching": {},
        "promptType": "define"
      },
      "typeVersion": 1.7
    },
    {
      "id": "f93c67fd-47ed-41d7-9dc2-f33d7cb00b2f",
      "name": "Parse AI Output",
      "type": "n8n-nodes-base.code",
      "position": [
        -1376,
        144
      ],
      "parameters": {
        "jsCode": "const raw = $input.first().json.text;\n\nconst parsed = JSON.parse(raw);\n\nreturn parsed.selected_papers.map(paper => {\n  return {\n    json: paper\n  };\n});"
      },
      "typeVersion": 2
    },
    {
      "id": "cc60b712-3f15-410f-af3c-7342f50c7d3a",
      "name": "Build Report",
      "type": "n8n-nodes-base.code",
      "position": [
        -928,
        144
      ],
      "parameters": {
        "jsCode": "const papers = $input.all().map(item => item.json);\n\nconst keyword = papers[0]?.Keyword ?? \"\";\nconst clinicalQuestion = papers[0]?.[\"Clinical Question\"] ?? \"\";\nconst specialty = papers[0]?.Specialty ?? \"\";\nconst today = new Date().toISOString().slice(0, 10);\n\nfunction stars(level) {\n  switch ((level ?? \"\").toLowerCase()) {\n    case \"high\":\n      return \"\u2605\u2605\u2605\u2605\u2605 High\";\n    case \"medium\":\n      return \"\u2605\u2605\u2605\u2606\u2606 Medium\";\n    case \"low\":\n      return \"\u2605\u2606\u2606\u2606\u2606 Low\";\n    default:\n      return level ?? \"Not reported\";\n  }\n}\n\nlet report = \"\\n\\n\\n\";\n\nreport += \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\";\nreport += \"Clinical Literature Triage Report\\n\";\nreport += \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n\";\n\nreport += `Date\\n${today}\\n\\n`;\nreport += `Keyword\\n${keyword}\\n\\n`;\n\nif (clinicalQuestion) report += `Clinical Question\\n${clinicalQuestion}\\n\\n`;\nif (specialty) report += `Specialty\\n${specialty}\\n\\n`;\n\nreport += \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n\";\n\nfor (const p of papers) {\n  const rankEmoji =\n    p.Rank == 1 ? \"\ud83e\udd47\" :\n    p.Rank == 2 ? \"\ud83e\udd48\" :\n    p.Rank == 3 ? \"\ud83e\udd49\" : \"\u2022\";\n\n  report += `${rankEmoji} Rank ${p.Rank}\\n`;\n  report += \"\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\\n\\n\";\n\n  report += `Title\\n${p.Title}\\n\\n`;\n  report += `Journal\\n${p.Journal} (${p[\"Pub Date\"]})\\n\\n`;\n  report += `Why Read First\\n${p[\"Why Read First\"] ?? \"\"}\\n\\n`;\n  report += `Summary 30 sec\\n${p[\"Summary 30sec\"]}\\n\\n`;\n  report += `Clinical Takeaway\\n${p[\"Clinical Takeaway\"]}\\n\\n`;\n  report += `Evidence Snapshot\\n${p[\"Evidence Snapshot\"]}\\n\\n`;\n  report += `Practice Impact\\n${p[\"Practice Impact\"]}\\n\\n`;\n  report += `Clinical Question Match\\n${p[\"Clinical Question Match\"]}\\n\\n`;\n  report += `Abstract Confidence\\n${stars(p[\"Abstract Confidence\"])}\\n\\n`;\n  report += `Recommended Full-text Checkpoints\\n${p[\"Full Text Checkpoints\"] ?? \"\"}\\n\\n`;\n  report += `PubMed\\n${p[\"Pubmed URL\"]}\\n\\n`;\n\n  report += \"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\\n\\n\";\n}\n\nreport += \"Disclaimer\\n\";\nreport += `${papers[0]?.Disclaimer ?? \"\"}\\n`;\n\nreturn [{\n  json: {\n    title: `Clinical Literature Triage Report - ${keyword} - ${today}`,\n    report\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "68421d9f-fdcc-401e-8c4f-63054ab26111",
      "name": "Create Google Doc",
      "type": "n8n-nodes-base.googleDocs",
      "position": [
        -736,
        144
      ],
      "parameters": {
        "title": "={{ $json.title }}",
        "driveId": "=myDrive",
        "folderId": "1G0CPhAu3TuUBE_o4D5Ml1i-V6QZ6787I"
      },
      "credentials": {
        "googleDocsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2
    },
    {
      "id": "749fdec8-14bf-4f38-a7c3-3c68d653d97f",
      "name": "Complete Request",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -352,
        144
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "completed",
            "row_number": "={{ $('Load Request').first().json.row_number }}"
          },
          "schema": [
            {
              "id": "Keyword",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Keyword",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Clinical Question",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Clinical Question",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Specialty",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Specialty",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Max Results",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Max Results",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Output Language",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Output Language",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM/edit#gid=0",
          "cachedResultName": "Search Requests"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM/edit?usp=drivesdk",
          "cachedResultName": "AI-Powered PubMed Literature Triage"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "6f22e9b7-e7a3-4832-b9cc-10b02a5d17cc",
      "name": "Processing Request",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1136,
        -304
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "processing",
            "row_number": "={{ $('Load Request').item.json.row_number }}"
          },
          "schema": [
            {
              "id": "Keyword",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Keyword",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Clinical Question",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Clinical Question",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Specialty",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Specialty",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Max Results",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Max Results",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Output Language",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Output Language",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "row_number",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": true,
              "required": false,
              "displayName": "row_number",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "row_number"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "update",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM/edit#gid=0",
          "cachedResultName": "Search Requests"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1zaD8am3_O090rV0TGIURg0EzB3oTg-3CFCVihvBuNPM/edit?usp=drivesdk",
          "cachedResultName": "AI-Powered PubMed Literature Triage"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "b40e42a4-d9b0-4d50-9b81-8444fecf2ec2",
      "name": "Gemini 2.5 Flash",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        -1696,
        304
      ],
      "parameters": {
        "options": {}
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "80c38e78-34b9-4df3-81de-4a9a70ca607f",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2416,
        -544
      ],
      "parameters": {
        "width": 624,
        "height": 688,
        "content": "\n\n## AI-Powered PubMed Literature Triage\n\n### How it works\n\nThis workflow reads a literature triage request from Google Sheets, searches PubMed, retrieves article metadata and abstracts, and uses Gemini to identify the three papers most worth reading first.\n\nStructured results are saved to Google Sheets, and a clinician-friendly report is generated in Google Docs.\n\n### Setup\n\n- Connect Google Sheets credentials\n- Connect Google Docs credentials\n- Connect Google Gemini API credential\n- Replace Google Sheets IDs with your own spreadsheet\n- Set the Google Drive folder for generated reports\n- Optionally add an NCBI API key for higher PubMed request limits\n\n### Customization\n\nYou can adjust the PubMed query, result limit, AI triage prompt, output language, ranking criteria, and Google Docs report format."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "timeSavedMode": "fixed",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "81723ffe-7554-4b89-aef6-952890cd13ae",
  "connections": {
    "Aggregate": {
      "main": [
        [
          {
            "node": "Clinical Literature Triage",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Query": {
      "main": [
        [
          {
            "node": "Processing Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build Report": {
      "main": [
        [
          {
            "node": "Create Google Doc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Request": {
      "main": [
        [
          {
            "node": "Build Query",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Write Report": {
      "main": [
        [
          {
            "node": "Complete Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Details": {
      "main": [
        [
          {
            "node": "Parse PubMed XML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Search PubMed": {
      "main": [
        [
          {
            "node": "Fetch Details",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI Output": {
      "main": [
        [
          {
            "node": "Append row in sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gemini 2.5 Flash": {
      "ai_languageModel": [
        [
          {
            "node": "Clinical Literature Triage",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Parse PubMed XML": {
      "main": [
        [
          {
            "node": "Normalize",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Load Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Google Doc": {
      "main": [
        [
          {
            "node": "Write Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Processing Request": {
      "main": [
        [
          {
            "node": "Search PubMed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append row in sheet": {
      "main": [
        [
          {
            "node": "Build Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clinical Literature Triage": {
      "main": [
        [
          {
            "node": "Parse AI Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Automatically retrieve recent PubMed articles, identify the three papers most worth reading first using AI, and generate structured clinical literature triage reports in Google Sheets and Google Docs. Reads the first pending literature request from the Google Sheets "Search…

Source: https://n8n.io/workflows/16805/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Categories Content Creation AI Automation Publishing Social Media

Google Docs, HTTP Request, Slack +7
AI & RAG

Automatically generates structured clinical guideline reports from Google Sheets requests. The workflow analyzes clinical questions with Gemini, searches trusted guideline sources using Brave Search,

Google Sheets, Google Gemini Chat, Chain Llm +3
AI & RAG

Cyber Zap Public. Uses httpRequest, chainLlm, outputParserStructured, telegram. Scheduled trigger; 69 nodes.

HTTP Request, Chain Llm, Output Parser Structured +6
AI & RAG

This workflow is the AI analysis and alerting engine for a complete social media monitoring system. It's designed to work with data scraped from X (formerly Twitter) using a tool like the Apify Tweet

Google Sheets, Google Gemini Chat, Google Sheets Tool +4
AI & RAG

This workflow turns a spreadsheet row into a fully formatted, media-rich WordPress article. It pulls the outline and brand context from Google Sheets/Docs, drafts the article with Anthropic or Gemini,

Agent, Google Sheets, Google Docs +5