This workflow follows the Gmail → 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 →
{
"id": "t5hsHZLvrxN168ug",
"meta": {
"site": "https://github.com/zengfr/n8n-workflow-all-templates",
"name": "Extract Web Page Data from Gmail Links and Save to Google Sheets",
"wechat": "youandme10086",
"id": 10006,
"update_time": "2025-11-10"
},
"name": "Extraindo_Dados_Gmail",
"tags": [],
"nodes": [
{
"id": "996ac1ec-c471-4734-a82c-c44c16ce74ad",
"name": "When clicking \u2018Test workflow\u2019",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-1728,
-400
],
"parameters": {},
"typeVersion": 1
},
{
"id": "8473c056-35d1-4e47-96dd-e0cb30e14ad1",
"name": "Search Emails",
"type": "n8n-nodes-base.gmail",
"position": [
-1504,
-400
],
"parameters": {
"simple": false,
"filters": {
"sender": "exemplo.email@gmail.com",
"receivedAfter": "2025-09-30T00:00:00",
"receivedBefore": "2025-09-22T00:00:00"
},
"options": {},
"operation": "getAll",
"returnAll": true
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "2c6c6140-160d-4198-a0cc-3fa17530859e",
"name": "search for an element in the email body",
"type": "n8n-nodes-base.html",
"position": [
-1280,
-400
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"dataPropertyName": "html",
"extractionValues": {
"values": [
{
"key": "dados",
"attribute": "href",
"cssSelector": "=a[style*=\"color: #ffffff\"]",
"returnValue": "attribute"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "7e6693f3-0607-49a3-9725-d844a8b45319",
"name": "open the link",
"type": "n8n-nodes-base.httpRequest",
"onError": "continueErrorOutput",
"position": [
-1072,
-400
],
"parameters": {
"url": "={{ $json.dados }}",
"options": {}
},
"retryOnFail": false,
"typeVersion": 4.2,
"alwaysOutputData": false
},
{
"id": "4a04204c-e8dc-4865-963a-000378aa1024",
"name": "capture data",
"type": "n8n-nodes-base.html",
"position": [
-832,
-416
],
"parameters": {
"options": {},
"operation": "extractHtmlContent",
"extractionValues": {
"values": [
{
"key": "dtnasc",
"cssSelector": "#lblMemberDateOfBirth"
},
{
"key": "id",
"cssSelector": "#txtCase"
},
{
"key": "data_solicitacao",
"cssSelector": "#lblCaseOpenOn"
},
{
"key": "Local_pt01",
"cssSelector": "#lblMemberFullAddress"
},
{
"key": "Local_pt02",
"cssSelector": "#lblLocationHotelName"
},
{
"key": "Nome",
"cssSelector": "#lblMemberFirstName"
},
{
"key": "sobrenome",
"cssSelector": "#lblMemberLastName"
},
{
"key": "Queixa",
"cssSelector": "#lblCaseReportedIssue"
},
{
"key": "Link",
"cssSelector": "=",
"returnValue": "value"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "a3d87c4d-1c96-461c-bc45-42e4a3c7469c",
"name": "processes information",
"type": "n8n-nodes-base.code",
"position": [
-608,
-416
],
"parameters": {
"jsCode": "// Fun\u00e7\u00e3o para converter string \"DD/MM/YYYY HH:MM\" para objeto Date\nfunction parseDateOnly(dateTimeStr) {\n if (!dateTimeStr) return null;\n const parts = dateTimeStr.split(' ')[0].split('/'); // pega apenas DD/MM/YYYY\n if (parts.length !== 3) return null;\n const day = parseInt(parts[0], 10);\n const month = parseInt(parts[1], 10) - 1; // meses em JS v\u00e3o de 0 a 11\n const year = parseInt(parts[2], 10);\n return new Date(year, month, day);\n}\n\n// Fun\u00e7\u00e3o para extrair apenas o n\u00famero do ID, removendo prefixos como \"Caso ID :\" ou \"Case ID :\"\nfunction extractCaseId(idStr) {\n if (!idStr) return null;\n return idStr.replace(/(Caso|Case)\\s*ID\\s*:\\s*/i, '').trim();\n}\n\n// Recupera todos os e-mails e links correspondentes\nconst emailItems = $('Search Emails').all();\nconst linkItems = $('search for an element in the email body').all();\n\n// Percorre todos os itens de entrada\nconst results = [];\nconst inputItems = $input.all();\n\nfor (let i = 0; i < inputItems.length; i++) {\n const item = inputItems[i];\n const birthDateStr = item.json.dtnasc;\n const requestDateTimeStr = item.json.data_solicitacao;\n const rawId = item.json.id;\n\n // Tratamento do ID\n const caseId = extractCaseId(rawId);\n\n // Captura o subject e o link correspondentes (mesmo \u00edndice)\n const emailSubject = emailItems[i]?.json?.headers?.subject || null;\n const emailLink = linkItems[i]?.json?.dados || null;\n\n // Determina o tipo de atendimento com base no subject\n let attendanceType = \"PRESENCIAL\";\n if (emailSubject && emailSubject.toLowerCase().includes(\"tele-medicine\")) {\n attendanceType = \"TELEMEDICINA\";\n }\n\n // Se faltar algum dado essencial, apenas devolve o item como est\u00e1\n if (!birthDateStr || !requestDateTimeStr) {\n results.push({\n json: {\n ...item.json,\n caseId: caseId || null,\n emailSubject: emailSubject,\n attendanceType: attendanceType,\n link: emailLink\n }\n });\n continue;\n }\n\n const birthDate = parseDateOnly(birthDateStr);\n\n // Separar data e hor\u00e1rio\n const [datePart, timePart] = requestDateTimeStr.split(' '); // \"DD/MM/YYYY\" e \"HH:MM\"\n const requestDate = parseDateOnly(datePart);\n\n if (!birthDate || !requestDate) {\n results.push({\n json: {\n ...item.json,\n caseId: caseId || null,\n emailSubject: emailSubject,\n attendanceType: attendanceType,\n link: emailLink\n }\n });\n continue;\n }\n\n // Calcula a idade\n let age = requestDate.getFullYear() - birthDate.getFullYear();\n const m = requestDate.getMonth() - birthDate.getMonth();\n if (m < 0 || (m === 0 && requestDate.getDate() < birthDate.getDate())) {\n age--;\n }\n\n // Retorna o item completo com todos os campos tratados\n results.push({\n json: {\n ...item.json,\n age: age,\n requestDate: datePart, // apenas a data\n requestTime: timePart, // apenas o hor\u00e1rio\n caseId: caseId, // n\u00famero do caso limpo\n emailSubject: emailSubject, // texto do subject do e-mail\n attendanceType: attendanceType, // \"TELEMEDICINA\" ou \"PRESENCIAL\"\n link: emailLink // link correspondente ao e-mail\n }\n });\n}\n\nreturn results;\n"
},
"typeVersion": 2
},
{
"id": "ac95be81-23fa-4833-9bbf-46a68d172a2f",
"name": "set variables",
"type": "n8n-nodes-base.set",
"position": [
-384,
-416
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "bcf5bbaa-2930-4c59-93c3-add1b31fdb7c",
"name": "id",
"type": "string",
"value": "={{ $json.caseId }}"
},
{
"id": "c46a4f49-c77f-4239-83f2-1a1334bf31ae",
"name": "Nome_Paciente",
"type": "string",
"value": "={{ $json.Nome }} {{ $json.sobrenome }}"
},
{
"id": "a2b523a0-6d65-442f-a23a-5e2ec3e8f17f",
"name": "Dt_solicitacao",
"type": "string",
"value": "={{ $json.requestDate }}"
},
{
"id": "7b421b6a-99fe-479a-ac7d-c580c02f6ee0",
"name": "Queixa",
"type": "string",
"value": "={{ $json.Queixa }}"
},
{
"id": "11941808-a53b-4d12-aaef-910120a5b512",
"name": "Idade",
"type": "string",
"value": "={{ $json.age }}"
},
{
"id": "9a0ff300-33ec-4dc6-831f-e21ad8148b84",
"name": "Local",
"type": "string",
"value": "={{ $json.Local_pt01 }} {{ $json.Local_pt02 }}"
},
{
"id": "0133b215-4db9-47ea-a2b8-ef80a4f052fa",
"name": "horario",
"type": "string",
"value": "={{ $json.requestTime }}"
},
{
"id": "a42de334-56c3-4180-bc7c-d926ebd4c2b2",
"name": "Link",
"type": "string",
"value": "={{ $json.link }}"
},
{
"id": "85b87a31-662f-4ef4-9b73-9211b0bd9511",
"name": "Tipo atendimento",
"type": "string",
"value": "={{ $json.attendanceType }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "907f9531-8fdd-4bce-9a8a-b03e7edsdsdsd202180",
"name": "Save data in spreadsheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
-144,
-416
],
"parameters": {
"columns": {
"value": {
"DATA": "={{ $json.Dt_solicitacao }}",
"LINK": "={{ $json.Link }}",
"NOME": "={{ $json.Nome_Paciente }}",
" CASO": "={{ $json.id }}",
"IDADE": "={{ $json.Idade }}",
"LOCAL": "={{ $json.Local }}",
"QUEIXA": "={{ $json.Queixa }}",
"HOR\u00c1RIO": "={{ $json.horario }}",
"TIPO CONSULTA ": "={{ $json['Tipo atendimento'] }}"
},
"schema": [
{
"id": "HOR\u00c1RIO",
"type": "string",
"display": true,
"required": false,
"displayName": "HOR\u00c1RIO",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "DATA",
"type": "string",
"display": true,
"required": false,
"displayName": "DATA",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "EMPRESA",
"type": "string",
"display": true,
"required": false,
"displayName": "EMPRESA",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "TIPO CONSULTA ",
"type": "string",
"display": true,
"required": false,
"displayName": "TIPO CONSULTA ",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "LOCAL",
"type": "string",
"display": true,
"required": false,
"displayName": "LOCAL",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "NOME",
"type": "string",
"display": true,
"required": false,
"displayName": "NOME",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": " CASO",
"type": "string",
"display": true,
"required": false,
"displayName": " CASO",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "IDADE",
"type": "string",
"display": true,
"required": false,
"displayName": "IDADE",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "QUEIXA",
"type": "string",
"display": true,
"required": false,
"displayName": "QUEIXA",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "LINK",
"type": "string",
"display": true,
"required": false,
"displayName": "LINK",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "DIAGNOSTICO",
"type": "string",
"display": true,
"required": false,
"displayName": "DIAGNOSTICO",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "MEDICA\u00c7\u00c3O PRESCRITA",
"type": "string",
"display": true,
"required": false,
"displayName": "MEDICA\u00c7\u00c3O PRESCRITA",
"defaultMatch": false,
"canBeUsedToMatch": true
},
{
"id": "INJETAVEIS /PROCEDIMENTOS",
"type": "string",
"display": true,
"required": false,
"displayName": "INJETAVEIS /PROCEDIMENTOS",
"defaultMatch": false,
"canBeUsedToMatch": true
}
],
"mappingMode": "defineBelow",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {},
"operation": "append",
"sheetName": {
"__rl": true,
"mode": "list",
"value": 311390915,
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bbcFz1111wO77RBr0t8hYaAEuzEsr24MJrFWuIPzoC-XMjx8/edit#gid=311390915",
"cachedResultName": "Outubro-2025"
},
"documentId": {
"__rl": true,
"mode": "list",
"value": "1bbcFzO77RBr0t8hYaAEuzEsr24MJrFWuIPzoC-XMjx8",
"cachedResultUrl": "https://docs.google.com/spreadsheets/d/1bbcFz111O77RBr0t8hYaAEuzEsr24MJrFWuIPzoC-XMjx8/edit?usp=drivesdk",
"cachedResultName": "NOREPLY"
}
},
"credentials": {
"googleSheetsOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 4.7
},
{
"id": "9fedd068-0a9b-44a1-bde1-de312dfc6ced",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1568,
-496
],
"parameters": {
"width": 208,
"height": 272,
"content": "**earch for emails** received from a sender within a specific time period."
},
"typeVersion": 1
},
{
"id": "584ddb97-097b-452c-a632-a534537965d0",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1344,
-496
],
"parameters": {
"color": 4,
"width": 208,
"height": 272,
"content": "**Search for a specific css element** in the email code"
},
"typeVersion": 1
},
{
"id": "f1d3e50c-a187-421f-95a1-009f1f5c8f49",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1120,
-496
],
"parameters": {
"color": 3,
"width": 208,
"height": 272,
"content": "**access the link** found in the HTML body of the email"
},
"typeVersion": 1
},
{
"id": "c434b579-5fb5-4813-9944-7af5f54101e6",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
-896,
-496
],
"parameters": {
"color": 4,
"width": 208,
"height": 272,
"content": "**Search for a specific css element** in the email code"
},
"typeVersion": 1
},
{
"id": "69282cbc-b64e-4923-b67d-f279cca4e509",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-672,
-496
],
"parameters": {
"color": 5,
"width": 208,
"height": 272,
"content": "js code to process the extracted data, **customize as you wish**"
},
"typeVersion": 1
},
{
"id": "df2ead67-1e19-4cec-a79c-47259d756545",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-448,
-496
],
"parameters": {
"color": 5,
"width": 208,
"height": 272,
"content": "set the desired variables to save"
},
"typeVersion": 1
},
{
"id": "2d494ae1-6ab6-473e-8252-b3837a7ea469",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
-208,
-496
],
"parameters": {
"width": 208,
"height": 272,
"content": "save the information to the desired Google spreadsheet."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "ac8b921c-39c6-45d0-bb37-cba2366b53bf",
"connections": {
"capture data": {
"main": [
[
{
"node": "processes information",
"type": "main",
"index": 0
}
]
]
},
"Search Emails": {
"main": [
[
{
"node": "search for an element in the email body",
"type": "main",
"index": 0
}
]
]
},
"open the link": {
"main": [
[
{
"node": "capture data",
"type": "main",
"index": 0
}
]
]
},
"set variables": {
"main": [
[
{
"node": "Save data in spreadsheet",
"type": "main",
"index": 0
}
]
]
},
"processes information": {
"main": [
[
{
"node": "set variables",
"type": "main",
"index": 0
}
]
]
},
"When clicking \u2018Test workflow\u2019": {
"main": [
[
{
"node": "Search Emails",
"type": "main",
"index": 0
}
]
]
},
"search for an element in the email body": {
"main": [
[
{
"node": "open the link",
"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.
gmailOAuth2googleSheetsOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Extraindo_Dados_Gmail. Uses gmail, httpRequest, googleSheets. Event-driven trigger; 15 nodes.
Source: https://github.com/zengfr/n8n-workflow-all-templates/blob/6a3e60251e39ea8c87e061d82f52633e5d0debe6/n8n-workflow-all-templates/00/01/00/10006_Extract_Web_Page_Data_from_Gmail_Links_and_Save_to_Google_Sheets.json — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Splitout Code. Uses manualTrigger, httpRequest, stickyNote, splitOut. Event-driven trigger; 46 nodes.
Automate CSV imports into HubSpot without the mess. Powered by n8n. Supercharged by Pollup AI.
AICARE Email Blast System. Uses googleDrive, httpRequest, googleSheets, gmail. Event-driven trigger; 39 nodes.
Automatically processes new orders added to Google Sheets. Small orders are approved instantly; large orders trigger an HTML email with one-click Approve / Reject links — each handled by an independen
Submit any YouTube, Vimeo, or Zoom webinar URL using a simple form and the workflow handles everything from there. It runs a two-phase pipeline: first identifying the top viral moments in your video w