AutomationFlowsAI & RAG › Mensallizap - Aniversário Automático

Mensallizap - Aniversário Automático

MensalliZap - Aniversário Automático. Uses httpRequest. Scheduled trigger; 9 nodes.

Cron / scheduled trigger★★★★☆ complexity9 nodesHTTP Request
AI & RAG Trigger: Cron / scheduled Nodes: 9 Complexity: ★★★★☆ Added:

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
{
  "name": "MensalliZap - Anivers\u00e1rio Autom\u00e1tico",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * *"
            }
          ]
        }
      },
      "id": "schedule-trigger",
      "name": "Disparo Di\u00e1rio (8h)",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.2,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "https://zvlnkkmcytjtridiojxx.supabase.co/rest/v1/vw_aniversariantes_do_dia",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            }
          ]
        },
        "options": {}
      },
      "id": "buscar-aniversariantes",
      "name": "Buscar Aniversariantes",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        500,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "// Criar mensagem de anivers\u00e1rio para cada aluno\nconst FALLBACK_ANIVERSARIO = 'Parab\u00e9ns, {{nomeCliente}}! \ud83c\udf82\ud83c\udf89\\n\\nHoje \u00e9 um dia muito especial! A equipe {{nomeEmpresa}} deseja a voc\u00ea um feliz anivers\u00e1rio cheio de sa\u00fade, alegria e conquistas!\\n\\nObrigado por fazer parte da nossa fam\u00edlia! \ud83d\udc9b\\n\\n_{{nomeEmpresa}}_';\n\nconst items = $input.all();\nconst results = [];\n\nfor (const item of items) {\n  const data = item.json;\n\n  let mensagem = data.template_mensagem;\n  if (!mensagem || mensagem.trim() === '') {\n    console.log(`${data.nome_cliente}: sem template birthday, usando fallback`);\n    mensagem = FALLBACK_ANIVERSARIO;\n  }\n\n  const variaveis = {\n    '{{nomeCliente}}': data.nome_cliente || 'Aluno',\n    '{{nomeEmpresa}}': data.nome_empresa || 'Equipe'\n  };\n\n  Object.entries(variaveis).forEach(([chave, valor]) => {\n    mensagem = mensagem.replace(new RegExp(chave, 'g'), valor);\n  });\n\n  let telefone = String(data.telefone || '').replace(/\\D/g, '');\n  if (!telefone.startsWith('55')) telefone = '55' + telefone;\n\n  results.push({\n    json: {\n      ...data,\n      mensagem,\n      telefone,\n      evolution_url: `${data.evolution_api_url}/message/sendText/${data.evolution_instance_name}`,\n      tipo_lembrete: 'aniversario'\n    }\n  });\n}\n\nreturn results;"
      },
      "id": "criar-msg-aniversario",
      "name": "Criar Mensagem",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        750,
        300
      ]
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all();\nconst results = [];\n\nfor (let i = 0; i < items.length; i++) {\n  const data = items[i].json;\n  if (i > 0) await new Promise(r => setTimeout(r, 1000));\n\n  try {\n    const resp = await this.helpers.httpRequest({\n      method: 'POST',\n      url: data.evolution_url,\n      headers: { 'Content-Type': 'application/json', 'apikey': data.evolution_api_key },\n      body: { number: data.telefone, text: data.mensagem },\n      returnFullResponse: true,\n      ignoreHttpStatusErrors: true,\n      json: true\n    });\n\n    const body = resp.body;\n    const statusCode = resp.statusCode;\n\n    if (statusCode >= 200 && statusCode < 300 && body?.key?.id) {\n      results.push({ json: { ...data, envio_sucesso: true, response_id: body.key.id, http_status: statusCode, response_api: body } });\n    } else {\n      let erroCodigo = `http_${statusCode}`;\n      let erroMsg = body?.response?.message || body?.message || `HTTP ${statusCode}`;\n      if (statusCode === 500) { erroCodigo = 'instance_500'; erroMsg = 'Inst\u00e2ncia retornou 500 (prov\u00e1vel desconex\u00e3o)'; }\n      else if (statusCode === 404) { erroCodigo = 'instance_not_found'; erroMsg = 'Inst\u00e2ncia n\u00e3o encontrada na Evolution'; }\n      else if (statusCode === 401 || statusCode === 403) { erroCodigo = 'auth_failed'; erroMsg = 'Credencial Evolution inv\u00e1lida'; }\n      else if (statusCode === 400) { erroCodigo = 'bad_request'; }\n      results.push({ json: { ...data, envio_sucesso: false, erro_mensagem: typeof erroMsg === 'string' ? erroMsg : JSON.stringify(erroMsg), erro_codigo: erroCodigo, http_status: statusCode, response_api: body } });\n    }\n  } catch (err) {\n    results.push({ json: { ...data, envio_sucesso: false, erro_mensagem: err.message || 'Erro de conex\u00e3o', erro_codigo: err.code ? `network_${String(err.code).toLowerCase()}` : 'exception', http_status: null, response_api: { name: err.name, message: err.message, code: err.code } } });\n  }\n}\n\nreturn results;"
      },
      "id": "enviar-aniversario",
      "name": "Enviar Anivers\u00e1rio",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1000,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{ $json.envio_sucesso }}",
              "value2": true
            }
          ]
        }
      },
      "id": "if-sucesso",
      "name": "Envio OK?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1500,
        300
      ]
    },
    {
      "parameters": {
        "method": "PATCH",
        "url": "=https://zvlnkkmcytjtridiojxx.supabase.co/rest/v1/devedores?id=eq.{{ $('Envio OK?').item.json.devedor_id }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=minimal"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"enviado_aniversario_em\": \"{{ new Date().toISOString().split('T')[0] }}\"\n}",
        "options": {}
      },
      "id": "marcar-aniversario",
      "name": "Marcar Enviado",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1750,
        200
      ]
    },
    {
      "parameters": {
        "method": "PATCH",
        "url": "=https://zvlnkkmcytjtridiojxx.supabase.co/rest/v1/controle_planos?user_id=eq.{{ $('Envio OK?').item.json.user_id }}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=minimal"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"usage_count\": {{ ($('Envio OK?').item.json.usage_count || 0) + 1 }},\n  \"updated_at\": \"{{ new Date().toISOString() }}\"\n}",
        "options": {}
      },
      "id": "incrementar-usage",
      "name": "Incrementar Usage",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2000,
        200
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://zvlnkkmcytjtridiojxx.supabase.co/rest/v1/logs_mensagens",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=minimal"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"user_id\": \"{{ $('Envio OK?').item.json.user_id }}\",\n  \"devedor_id\": \"{{ $('Envio OK?').item.json.devedor_id }}\",\n  \"telefone\": \"{{ $('Envio OK?').item.json.telefone }}\",\n  \"mensagem\": {{ JSON.stringify($('Envio OK?').item.json.mensagem) }},\n  \"tipo\": \"birthday\",\n  \"status\": \"enviado\",\n  \"http_status\": {{ JSON.stringify($('Envio OK?').item.json.http_status ?? null) }},\n  \"response_api\": {{ JSON.stringify($('Envio OK?').item.json.response_api ?? null) }}\n}",
        "options": {}
      },
      "id": "log-aniversario",
      "name": "Log Anivers\u00e1rio",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        2250,
        200
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://zvlnkkmcytjtridiojxx.supabase.co/rest/v1/logs_mensagens",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "apikey",
              "value": "<redacted-credential>"
            },
            {
              "name": "Authorization",
              "value": "<redacted-credential>"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Prefer",
              "value": "return=minimal"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"user_id\": \"{{ $('Envio OK?').item.json.user_id }}\",\n  \"devedor_id\": \"{{ $('Envio OK?').item.json.devedor_id }}\",\n  \"telefone\": \"{{ $('Envio OK?').item.json.telefone }}\",\n  \"mensagem\": {{ JSON.stringify($('Envio OK?').item.json.mensagem) }},\n  \"tipo\": \"birthday\",\n  \"status\": \"falha\",\n  \"erro\": {{ JSON.stringify($('Envio OK?').item.json.erro_mensagem || 'Erro desconhecido') }},\n  \"erro_codigo\": {{ JSON.stringify($('Envio OK?').item.json.erro_codigo || null) }},\n  \"http_status\": {{ JSON.stringify($('Envio OK?').item.json.http_status ?? null) }},\n  \"response_api\": {{ JSON.stringify($('Envio OK?').item.json.response_api ?? null) }}\n}",
        "options": {}
      },
      "id": "log-falha",
      "name": "Log Falha",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        1750,
        450
      ]
    }
  ],
  "connections": {
    "Disparo Di\u00e1rio (8h)": {
      "main": [
        [
          {
            "node": "Buscar Aniversariantes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Buscar Aniversariantes": {
      "main": [
        [
          {
            "node": "Criar Mensagem",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Criar Mensagem": {
      "main": [
        [
          {
            "node": "Enviar Anivers\u00e1rio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Enviar Anivers\u00e1rio": {
      "main": [
        [
          {
            "node": "Envio OK?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Envio OK?": {
      "main": [
        [
          {
            "node": "Marcar Enviado",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Falha",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Marcar Enviado": {
      "main": [
        [
          {
            "node": "Incrementar Usage",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Incrementar Usage": {
      "main": [
        [
          {
            "node": "Log Anivers\u00e1rio",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}
Pro

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

About this workflow

MensalliZap - Aniversário Automático. Uses httpRequest. Scheduled trigger; 9 nodes.

Source: https://github.com/Caiolcn/sistema-cobranca/blob/46ea6a3aee3efb5f1043713ca8238bf882ef3bc6/n8n-workflows/agente-aniversario.json — 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

Template 14310. Uses httpRequest, stopAndError, slack, gmail. Scheduled trigger; 53 nodes.

HTTP Request, Stop And Error, Slack +1
AI & RAG

🧑🏾 Chief of Staff — System Intelligence & Operations. Uses httpRequest, microsoftOutlook. Scheduled trigger; 52 nodes.

HTTP Request, Microsoft Outlook
AI & RAG

Master Agent - Orchestrator. Uses httpRequest, telegram, telegramTrigger. Scheduled trigger; 46 nodes.

HTTP Request, Telegram, Telegram Trigger
AI & RAG

Reputation Engine — Content Research Agent. Uses httpRequest. Scheduled trigger; 45 nodes.

HTTP Request
AI & RAG

Master Agent - Orchestrator. Uses httpRequest, telegram, telegramTrigger. Scheduled trigger; 44 nodes.

HTTP Request, Telegram, Telegram Trigger