This workflow follows the Emailsend → HTTP Request 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 →
{
"name": "n8n_email_daily_tasks_fixed",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "hours"
}
]
}
},
"id": "21b45205-19ba-4ae1-87ac-dfa02520b38f",
"name": "Agendamento Di\u00e1rio (7:30)",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
20,
-120
]
},
{
"parameters": {
"authentication": "headerAuth",
"url": "http://backend:8000/api/v1/admin/users",
"options": {}
},
"id": "a4b3441f-38ff-4676-adfb-fe32f7d6078c",
"name": "Obter Lista de Usu\u00e1rios",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
240,
-120
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Filtra apenas usu\u00e1rios com email v\u00e1lido\nconst response = $input.all();\nconsole.log('Resposta da API:', JSON.stringify(response).substring(0, 200));\n\n// Extrair os usu\u00e1rios da resposta\nlet usuarios = [];\nif (response && response.length > 0 && response[0].json) {\n // Verificar se os dados est\u00e3o dentro de um campo 'data'\n if (response[0].json.data && Array.isArray(response[0].json.data)) {\n usuarios = response[0].json.data;\n } \n // Verificar se o json j\u00e1 \u00e9 um array\n else if (Array.isArray(response[0].json)) {\n usuarios = response[0].json;\n }\n}\n\nconsole.log('Total de usu\u00e1rios extra\u00eddos:', usuarios.length);\n\n// Filtra apenas os que t\u00eam email\nconst usuariosComEmail = usuarios.filter(u => u && u.email && u.email.includes('@'));\nconsole.log('Usu\u00e1rios com email:', usuariosComEmail.length);\n\n// Debug - mostra os primeiros 3 usu\u00e1rios\nif (usuariosComEmail.length > 0) {\n console.log('Primeiro usu\u00e1rio com email:', JSON.stringify(usuariosComEmail[0]));\n}\n\n// Retorna usu\u00e1rios j\u00e1 formatados como items para o n8n\nreturn usuariosComEmail.map(user => ({ json: user }));"
},
"id": "dbc0fca1-e365-4ab0-84f7-b2917bde76cb",
"name": "Usu\u00e1rios com Email",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
460,
-120
]
},
{
"parameters": {
"batchSize": 1,
"options": {}
},
"id": "0c57217b-d6d5-4ca6-ad36-1a636279f146",
"name": "Processar por Usu\u00e1rio",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 2,
"position": [
680,
-120
]
},
{
"parameters": {
"functionCode": "// Obter o ID do usu\u00e1rio para debug\nconst item = $input.item;\nconst usuarioAtual = item.json;\n\n// Imprimir detalhes para debug\nconsole.log('Processando usu\u00e1rio:', JSON.stringify(usuarioAtual));\nconsole.log('ID do usu\u00e1rio:', usuarioAtual.id);\n\n// Garantir que temos um ID v\u00e1lido antes de prosseguir\nif (!usuarioAtual || !usuarioAtual.id) {\n console.error('ID de usu\u00e1rio n\u00e3o encontrado ou inv\u00e1lido:', JSON.stringify(item));\n throw new Error('ID de usu\u00e1rio n\u00e3o encontrado');\n}\n\nreturn $input.item;"
},
"id": "c7b781a1-e365-4ab0-94f7-b2917bce76cb",
"name": "Debug ID Usu\u00e1rio",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
800,
-120
]
},
{
"parameters": {
"authentication": "headerAuth",
"method": "GET",
"url": "=http://backend:8000/api/v1/admin/tasks/user/{{$json.id}}",
"options": {
"allowUnauthorizedCerts": true,
"redirect": {
"redirect": {
"follow": true
}
}
}
},
"id": "672057cd-eb14-42a9-9d57-7e384e488654",
"name": "Obter Tarefas do Usu\u00e1rio",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
900,
-120
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "// Processar os dados do usu\u00e1rio e suas tarefas\nconst usuario = $node[\"Debug ID Usu\u00e1rio\"].json;\nconst tarefas = $json;\n\n// Log para debug\nconsole.log(`Usu\u00e1rio: ${usuario.name}, ID: ${usuario.id}, Email: ${usuario.email}`);\nconsole.log(`Tarefas recebidas: ${tarefas.length}`);\nif (tarefas.length > 0) {\n console.log('Exemplo de tarefa:', JSON.stringify(tarefas[0]));\n}\n\n// Data atual\nconst hoje = new Date();\nconst amanha = new Date(hoje);\namanha.setDate(hoje.getDate() + 1);\n\n// Formatar data\nconst dataFormatada = hoje.toLocaleDateString('pt-BR');\n\n// Filtrar tarefas\nconst tarefasHoje = tarefas.filter(t => {\n if (!t.due_date) return false;\n const data = new Date(t.due_date);\n return data.toDateString() === hoje.toDateString();\n});\n\nconst tarefasAmanha = tarefas.filter(t => {\n if (!t.due_date) return false;\n const data = new Date(t.due_date);\n return data.toDateString() === amanha.toDateString();\n});\n\nconst tarefasAtrasadas = tarefas.filter(t => {\n if (!t.due_date || t.status === 'done') return false;\n const data = new Date(t.due_date);\n return data < hoje && data.toDateString() !== hoje.toDateString();\n});\n\n// Log para debug de categoriza\u00e7\u00e3o\nconsole.log(`Tarefas para hoje: ${tarefasHoje.length}`);\nconsole.log(`Tarefas para amanh\u00e3: ${tarefasAmanha.length}`);\nconsole.log(`Tarefas atrasadas: ${tarefasAtrasadas.length}`);\n\n// Estat\u00edsticas\nconst totalTarefas = tarefas.length;\nconst tarefasConcluidas = tarefas.filter(t => t.status === 'done').length;\n\n// Retornar dados formatados com melhor tratamento para nome e email\nreturn {\n json: {\n id: usuario.id,\n nome: usuario.name || (usuario.email ? usuario.email.split('@')[0] : 'Usu\u00e1rio'),\n email: usuario.email || '',\n dataFormatada,\n tarefasHoje,\n tarefasAmanha,\n tarefasAtrasadas,\n totalTarefas,\n tarefasConcluidas\n }\n};"
},
"id": "0c1e6b5c-8e85-4c4c-916d-1cec8062ef3a",
"name": "Processar Dados do Usu\u00e1rio",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
1120,
-120
]
},
{
"parameters": {
"functionCode": "// Criar um prompt para a IA baseado nos dados do usu\u00e1rio\nconst dados = $json;\n\n// Verificar se temos dados de tarefa\nconsole.log('Dados para gerar prompt:', JSON.stringify(dados));\n\n// Formatar tarefas para o prompt\nconst formatarTarefas = (tarefas) => {\n if (!tarefas || !tarefas.length) return '(Nenhuma tarefa)';\n return tarefas.map(t => `- ${t.title} (${t.priority})`).join('\\n');\n};\n\nconst tarefasHoje = formatarTarefas(dados.tarefasHoje);\nconst tarefasAmanha = formatarTarefas(dados.tarefasAmanha);\nconst tarefasAtrasadas = formatarTarefas(dados.tarefasAtrasadas);\n\nconst prompt = `Crie um email de resumo de tarefas para um usu\u00e1rio de um sistema de produtividade chamado Orga.AI. O email deve ser motivacional, breve e destacar as principais tarefas e prioridades. Inclua dicas r\u00e1pidas e pr\u00e1ticas para melhorar a produtividade. Use as informa\u00e7\u00f5es abaixo para personalizar o email:\\n\\nData: ${dados.dataFormatada}\\nNome do usu\u00e1rio: ${dados.nome}\\nTotal de tarefas: ${dados.totalTarefas}\\nTarefas conclu\u00eddas: ${dados.tarefasConcluidas}\\n\\nTarefas para hoje:\\n${tarefasHoje}\\n\\nTarefas para amanh\u00e3:\\n${tarefasAmanha}\\n\\nTarefas atrasadas:\\n${tarefasAtrasadas}\\n\\nO email deve ter um t\u00edtulo, uma sauda\u00e7\u00e3o personalizada, uma vis\u00e3o geral das tarefas, e ser no formato HTML com cores e formata\u00e7\u00e3o que destaquem as diferentes se\u00e7\u00f5es. Use o tom de um coach produtivo que est\u00e1 ajudando o usu\u00e1rio a organizar seu dia.`;\n\n// Log para debug\nconsole.log('Prompt gerado com tamanho:', prompt.length);\n\nreturn [{\n json: {\n ...dados,\n prompt: prompt\n }\n}];"
},
"id": "79f99e04-46ac-4c3f-982b-8ce4e64c67ff",
"name": "Gerar Prompt para IA",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
1340,
-120
]
},
{
"parameters": {
"url": "http://ollama:11434/api/chat",
"method": "POST",
"responseFormat": "json",
"jsonParameters": true,
"options": {
"allowUnauthorizedCerts": true,
"timeout": 120000
},
"bodyParametersJson": "={\n \"model\": \"gemma3:1b\",\n \"messages\": [\n {\n \"role\": \"system\",\n \"content\": \"Voc\u00ea \u00e9 um assistente especializado em produtividade e gest\u00e3o de tempo que ajuda pessoas a organizarem suas tarefas. Seu tom \u00e9 motivacional, pr\u00e1tico e direto.\"\n },\n {\n \"role\": \"user\",\n \"content\": {{$json[\"prompt\"]}}\n }\n ],\n \"stream\": false\n}"
},
"id": "df1d34dd-2c2c-4f00-a5cd-a25df0838d26",
"name": "Gerar Conte\u00fado do Email com IA",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
1560,
-120
]
},
{
"parameters": {
"functionCode": "// Formatar o conte\u00fado do email a partir da resposta da IA\nconst dados = $json;\n\n// Log para debug\nconsole.log('Resposta da IA recebida:', JSON.stringify(dados).substring(0, 300) + '...');\n\n// Extrair o conte\u00fado da mensagem da resposta da API chat\nlet conteudoHTML = 'N\u00e3o foi poss\u00edvel gerar o conte\u00fado do email.';\n\nif (dados.message && dados.message.content) {\n conteudoHTML = dados.message.content;\n} else if (dados.response) {\n conteudoHTML = dados.response;\n} else if (dados.choices && dados.choices.length > 0 && dados.choices[0].message) {\n conteudoHTML = dados.choices[0].message.content;\n}\n\n// Retornar os dados com o HTML formado\nreturn [{\n json: {\n ...dados,\n emailHTML: conteudoHTML\n }\n}];"
},
"id": "0edd1bc0-ea34-4e14-ab95-63fae62fbd0c",
"name": "Formatar Conte\u00fado do Email",
"type": "n8n-nodes-base.function",
"typeVersion": 1,
"position": [
1780,
-120
]
},
{
"parameters": {
"fromEmail": "angelo.sagnori@gmail.com",
"toEmail": "={{$json[\"email\"]}}",
"subject": "=Orga.AI - Seu resumo di\u00e1rio de tarefas ({{$json[\"dataFormatada\"]}})",
"html": "={{$json[\"emailHTML\"]}}",
"options": {}
},
"id": "1c91b921-0951-4f6e-868b-571fccd29d61",
"name": "Enviar Email",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 1,
"position": [
2000,
-120
],
"credentials": {
"smtp": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"httpMethod": "POST",
"path": "logar-erro",
"options": {}
},
"id": "60572774-d4d7-45d8-8e85-ecb2af78a97f",
"name": "Webhook para Logs",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
2220,
-20
]
},
{
"parameters": {
"authentication": "headerAuth",
"url": "http://backend:8000/api/v1/admin/logs",
"method": "PUT",
"allowUnauthorizedCerts": true,
"jsonParameters": true,
"options": {},
"bodyParametersJson": "= { \n \"level\": \"info\", \n \"source\": \"n8n_workflow\", \n \"message\": `Email enviado para ${$json[\"nome\"]} <${$json[\"email\"]}>`,\n \"details\": { \n \"workflow\": \"n8n_email_daily_tasks_fixed\", \n \"user_id\": $json[\"id\"], \n \"task_count\": $json[\"totalTarefas\"],\n \"timestamp\": new Date().toISOString()\n }\n}"
},
"id": "a0572774-d4d7-45d8-8e85-ecb2af78a97f",
"name": "Registrar Log de Email",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 1,
"position": [
2220,
-120
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Agendamento Di\u00e1rio (7:30)": {
"main": [
[
{
"node": "Obter Lista de Usu\u00e1rios",
"type": "main",
"index": 0
}
]
]
},
"Obter Lista de Usu\u00e1rios": {
"main": [
[
{
"node": "Usu\u00e1rios com Email",
"type": "main",
"index": 0
}
]
]
},
"Usu\u00e1rios com Email": {
"main": [
[
{
"node": "Processar por Usu\u00e1rio",
"type": "main",
"index": 0
}
]
]
},
"Processar por Usu\u00e1rio": {
"main": [
[
{
"node": "Debug ID Usu\u00e1rio",
"type": "main",
"index": 0
}
]
]
},
"Debug ID Usu\u00e1rio": {
"main": [
[
{
"node": "Obter Tarefas do Usu\u00e1rio",
"type": "main",
"index": 0
}
]
]
},
"Obter Tarefas do Usu\u00e1rio": {
"main": [
[
{
"node": "Processar Dados do Usu\u00e1rio",
"type": "main",
"index": 0
}
]
]
},
"Processar Dados do Usu\u00e1rio": {
"main": [
[
{
"node": "Gerar Prompt para IA",
"type": "main",
"index": 0
}
]
]
},
"Gerar Prompt para IA": {
"main": [
[
{
"node": "Gerar Conte\u00fado do Email com IA",
"type": "main",
"index": 0
}
]
]
},
"Gerar Conte\u00fado do Email com IA": {
"main": [
[
{
"node": "Formatar Conte\u00fado do Email",
"type": "main",
"index": 0
}
]
]
},
"Formatar Conte\u00fado do Email": {
"main": [
[
{
"node": "Enviar Email",
"type": "main",
"index": 0
}
]
]
},
"Enviar Email": {
"main": [
[
{
"node": "Registrar Log de Email",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "fixed-2025-05-11",
"meta": {
"templateCredsSetupCompleted": true
},
"id": "fixed_workflow_with_debug",
"tags": [
"corrigido",
"debug"
]
}
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.
httpHeaderAuthsmtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
n8n_email_daily_tasks_fixed. Uses httpRequest, emailSend. Scheduled trigger; 13 nodes.
Source: https://github.com/asagnori/Orga-AI/blob/f21833e668c05ab292af681640381cdd147afbcc/cookbooks/n8n-flows/backup/20250511/n8n_email_daily_tasks.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.
This workflow is an improvement of this workflow by Greg Brzezinka.
N8N-Self-Updater. Uses ssh, emailSend, httpRequest. Scheduled trigger; 27 nodes.
> An automated n8n workflow originally built for DigitalOcean-based n8n deployments, but fully compatible with any VPS or cloud hosting (e.g., AWS, Google Cloud, Hetzner, Linode, etc.) where n8n ru
What if you could spot a major sales problem—or a winning campaign—the very next morning, instead of weeks later? Imagine receiving a beautiful, data-rich alert directly in your inbox the moment your
Track Changes Of Product Prices. Uses htmlExtract, functionItem, httpRequest, writeBinaryFile. Scheduled trigger; 25 nodes.