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.
Birthday Automation - Production (Fixed). Uses stopAndError, httpRequest, emailSend, bannerbear. Scheduled trigger; 86 nodes.
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