Pular para o conteúdo principal

Exportação e Importação de Workflows

A exportação e importação de workflows permite mover automações entre ambientes, fazer backup e compartilhar soluções. Esta seção aborda todas as formas de exportar e importar workflows no n8n de forma segura e eficiente.

Visão Geral

A exportação e importação de workflows oferece múltiplas funcionalidades:

  • Migração entre ambientes (desenvolvimento, homologação, produção)
  • Backup e recuperação de workflows
  • Compartilhamento de soluções entre equipes
  • Versionamento e controle de mudanças
  • Templates para reutilização

Formatos de Exportação

Formato JSON (Padrão)

O formato padrão do n8n inclui todos os dados do workflow:

json\n{\n  "name": "Automação de Vendas",\n  "nodes": [\n    {\n      "parameters": {},\n      "id": "webhook-trigger",\n      "name": "Webhook Trigger",\n      "type": "n8n-nodes-base.webhook",\n      "typeVersion": 1,\n      "position": [240, 300]\n    }\n  ],\n  "connections": {\n    "Webhook Trigger": {\n      "main": [\n        [\n          {\n            "node": "HTTP Request",\n            "type": "main",\n            "index": 0\n          }\n        ]\n      ]\n    }\n  },\n  "active": false,\n  "settings": {\n    "executionTimeout": 3600000,\n    "saveExecutionProgress": true\n  },\n  "versionId": "1.0.0",\n  "meta": {\n    "templateCredsSetupCompleted": true,\n    "instanceId": "n8n-brasil"\n  }\n}\n
\n\n### Formato Compacto\n\nVersão simplificada para compartilhamento rápido:\n\n
json\n{\n  "name": "Automação de Vendas",\n  "nodes": [\n    {\n      "parameters": {\n        "httpMethod": "POST",\n        "path": "vendas-webhook"\n      },\n      "id": "webhook-trigger",\n      "name": "Webhook Trigger",\n      "type": "n8n-nodes-base.webhook",\n      "typeVersion": 1,\n      "position": [240, 300]\n    }\n  ],\n  "connections": {\n    "Webhook Trigger": {\n      "main": [\n        [\n          {\n            "node": "HTTP Request",\n            "type": "main",\n            "index": 0\n          }\n        ]\n      ]\n    }\n  },\n  "active": false\n}\n
\n\n### Formato com Credenciais\n\nInclui credenciais criptografadas (use com cuidado):\n\n
json\n{\n  "name": "Automação de Vendas",\n  "nodes": [\n    {\n      "parameters": {\n        "url": "https://api.crm.com.br/v1/leads",\n        "authentication": "genericCredentialType"\n      },\n      "credentials": {\n        "httpBasicAuth": {\n          "id": "crm-credentials",\n          "name": "CRM API"\n        }\n      },\n      "id": "http-request",\n      "name": "HTTP Request",\n      "type": "n8n-nodes-base.httpRequest",\n      "typeVersion": 1,\n      "position": [460, 300]\n    }\n  ],\n  "connections": {},\n  "active": false,\n  "credentials": {\n    "httpBasicAuth": {\n      "id": "crm-credentials",\n      "name": "CRM API",\n      "type": "httpBasicAuth",\n      "data": {\n        "user": "encrypted-user",\n        "password": "encrypted-password"\n      }\n    }\n  }\n}\n
\n\n## Exportação de Workflows\n\n### Via Interface Web\n\nPara exportar um workflow via interface:\n\n1. Abra o workflow no editor\n2. Clique no menu (⋮) no canto superior direito\n3. Selecione "Export" no menu\n4. Escolha o formato de exportação\n5. Clique em "Download" para baixar o arquivo\n\n### Via API\n\nExporte workflows programaticamente:\n\n
javascript\n// Exportar workflow via API\nconst exportarWorkflow = async (workflowId, formato = 'json') => {\n  const response = await fetch(`/api/v1/workflows/${workflowId}/export`, {\n    method: 'GET',\n    headers: {\n      'Authorization': 'Bearer YOUR_API_KEY',\n      'Accept': `application/${formato}`\n    },\n    params: {\n      format: formato,\n      includeCredentials: false,\n      includeSettings: true\n    }\n  });\n  \n  return response.json();\n};\n\n// Exemplo de uso\nconst workflow = await exportarWorkflow('workflow-123', 'json');\nconsole.log(JSON.stringify(workflow, null, 2));\n
\n\n### Exportação em Lote\n\nExporte múltiplos workflows de uma vez:\n\n
javascript\n// Exportar múltiplos workflows\nconst exportarWorkflowsEmLote = async (workflowIds, formato = 'json') => {\n  const workflows = [];\n  \n  for (const id of workflowIds) {\n    try {\n      const workflow = await exportarWorkflow(id, formato);\n      workflows.push(workflow);\n    } catch (error) {\n      console.error(`Erro ao exportar workflow ${id}:`, error);\n    }\n  }\n  \n  return workflows;\n};\n\n// Exemplo: Exportar todos os workflows de vendas\nconst workflowIds = ['vendas-1', 'vendas-2', 'vendas-3'];\nconst workflowsVendas = await exportarWorkflowsEmLote(workflowIds);\n
\n\n### Exportação com Filtros\n\nExporte workflows baseado em critérios:\n\n
javascript\n// Exportar workflows com filtros\nconst exportarWorkflowsComFiltros = async (filtros) => {\n  const response = await fetch('/api/v1/workflows/export/batch', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'Authorization': 'Bearer YOUR_API_KEY'\n    },\n    body: JSON.stringify({\n      filters: {\n        tags: filtros.tags,\n        categories: filtros.categorias,\n        active: filtros.ativo,\n        createdAfter: filtros.criadoApos,\n        createdBefore: filtros.criadoAntes\n      },\n      format: 'json',\n      includeCredentials: false,\n      includeSettings: true\n    })\n  });\n  \n  return response.json();\n};\n\n// Exemplo: Exportar workflows de vendas ativos\nconst filtros = {\n  tags: ['vendas', 'crm'],\n  categorias: ['Vendas'],\n  ativo: true,\n  criadoApos: '2024-01-01'\n};\n\nconst workflowsFiltrados = await exportarWorkflowsComFiltros(filtros);\n
\n\n## Importação de Workflows\n\n### Via Interface Web\n\nPara importar um workflow via interface:\n\n1. Vá para a página de workflows\n2. Clique em "Import from file"\n3. Selecione o arquivo JSON do workflow\n4. Configure as opções de importação\n5. Clique em "Import" para importar\n\n### Via API\n\nImporte workflows programaticamente:\n\n
javascript\n// Importar workflow via API\nconst importarWorkflow = async (workflowData, opcoes = {}) => {\n  const response = await fetch('/api/v1/workflows/import', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'Authorization': 'Bearer YOUR_API_KEY'\n    },\n    body: JSON.stringify({\n      workflow: workflowData,\n      options: {\n        overwrite: opcoes.sobrescrever || false,\n        importCredentials: opcoes.importarCredenciais || false,\n        importSettings: opcoes.importarConfiguracoes || true,\n        updateExisting: opcoes.atualizarExistente || false\n      }\n    })\n  });\n  \n  return response.json();\n};\n\n// Exemplo de uso\nconst workflowData = {\n  name: "Automação de Vendas",\n  nodes: [...],\n  connections: {...}\n};\n\nconst opcoes = {\n  sobrescrever: false,\n  importarCredenciais: true,\n  importarConfiguracoes: true,\n  atualizarExistente: true\n};\n\nconst resultado = await importarWorkflow(workflowData, opcoes);\n
\n\n### Importação com Validação\n\nValide workflows antes da importação:\n\n
javascript\n// Validar workflow antes da importação\nconst validarWorkflow = async (workflowData) => {\n  const response = await fetch('/api/v1/workflows/validate', {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application/json',\n      'Authorization': 'Bearer YOUR_API_KEY'\n    },\n    body: JSON.stringify({\n      workflow: workflowData\n    })\n  });\n  \n  return response.json();\n};\n\n// Importar com validação\nconst importarComValidacao = async (workflowData) => {\n  // Primeiro validar\n  const validacao = await validarWorkflow(workflowData);\n  \n  if (validacao.valid) {\n    // Se válido, importar\n    return await importarWorkflow(workflowData);\n  } else {\n    throw new Error(`Workflow inválido: ${validacao.errors.join(', ')}`);\n  }\n};\n
\n\n### Importação em Lote\n\nImporte múltiplos workflows de uma vez:\n\n
javascript\n// Importar múltiplos workflows\nconst importarWorkflowsEmLote = async (workflows, opcoes = {}) => {\n  const resultados = [];\n  \n  for (const workflow of workflows) {\n    try {\n      const resultado = await importarWorkflow(workflow, opcoes);\n      resultados.push({\n        nome: workflow.name,\n        sucesso: true,\n        id: resultado.id\n      });\n    } catch (error) {\n      resultados.push({\n        nome: workflow.name,\n        sucesso: false,\n        erro: error.message\n      });\n    }\n  }\n  \n  return resultados;\n};\n\n// Exemplo: Importar workflows de backup\nconst workflowsBackup = [\n  { name: "Vendas 1", nodes: [...], connections: {...} },\n  { name: "Vendas 2", nodes: [...], connections: {...} },\n  { name: "Vendas 3", nodes: [...], connections: {...} }\n];\n\nconst resultados = await importarWorkflowsEmLote(workflowsBackup);\n
\n\n## Migração Entre Ambientes\n\n### Desenvolvimento para Homologação\n\n
javascript\n// Migrar workflow de dev para homologação\nconst migrarParaHomologacao = async (workflowId) => {\n  // 1. Exportar de desenvolvimento\n  const workflow = await exportarWorkflow(workflowId);\n  \n  // 2. Ajustar configurações para homologação\n  const workflowHomologacao = {\n    ...workflow,\n    settings: {\n      ...workflow.settings,\n      executionTimeout: 1800000, // 30 minutos\n      saveExecutionProgress: true,\n      notifications: {\n        onError: {\n          enabled: true,\n          channels: ['email'],\n          recipients: ['dev@empresa.com']\n        }\n      }\n    },\n    meta: {\n      ...workflow.meta,\n      environment: 'homologacao',\n      migratedAt: new Date().toISOString()\n    }\n  };\n  \n  // 3. Importar em homologação\n  const homologacaoApiKey = 'HOMOLOGACAO_API_KEY';\n  const resultado = await importarWorkflow(workflowHomologacao, {\n    sobrescrever: true,\n    importarCredenciais: false\n  });\n  \n  return resultado;\n};\n
\n\n### Homologação para Produção\n\n
javascript\n// Migrar workflow de homologação para produção\nconst migrarParaProducao = async (workflowId) => {\n  // 1. Exportar de homologação\n  const workflow = await exportarWorkflow(workflowId);\n  \n  // 2. Ajustar configurações para produção\n  const workflowProducao = {\n    ...workflow,\n    settings: {\n      ...workflow.settings,\n      executionTimeout: 3600000, // 1 hora\n      saveExecutionProgress: true,\n      notifications: {\n        onError: {\n          enabled: true,\n          channels: ['email', 'slack'],\n          recipients: ['admin@empresa.com', 'dev@empresa.com']\n        },\n        onSuccess: {\n          enabled: true,\n          channels: ['slack'],\n          recipients: ['vendas@empresa.com']\n        }\n      }\n    },\n    meta: {\n      ...workflow.meta,\n      environment: 'producao',\n      migratedAt: new Date().toISOString(),\n      version: '1.0.0'\n    }\n  };\n  \n  // 3. Importar em produção\n  const producaoApiKey = 'PRODUCAO_API_KEY';\n  const resultado = await importarWorkflow(workflowProducao, {\n    sobrescrever: false,\n    importarCredenciais: true\n  });\n  \n  return resultado;\n};\n
\n\n## Backup e Recuperação\n\n### Backup Automático\n\nConfigure backup automático de workflows:\n\n
javascript\n// Configurar backup automático\nconst configurarBackupAutomatico = {\n  enabled: true,\n  schedule: '0 2 * * *', // Diário às 2h\n  retention: {\n    days: 30,\n    maxBackups: 100\n  },\n  storage: {\n    type: 's3', // s3, local, gcs\n    bucket: 'n8n-backups',\n    path: 'workflows/'\n  },\n  encryption: {\n    enabled: true,\n    algorithm: 'AES-256-GCM'\n  }\n};\n\n// Executar backup\nconst executarBackup = async () => {\n  // 1. Listar todos os workflows\n  const workflows = await listarWorkflows();\n  \n  // 2. Exportar cada workflow\n  const backups = [];\n  for (const workflow of workflows) {\n    const backup = await exportarWorkflow(workflow.id);\n    backups.push(backup);\n  }\n  \n  // 3. Criar arquivo de backup\n  const backupData = {\n    timestamp: new Date().toISOString(),\n    version: '1.0.0',\n    workflows: backups,\n    metadata: {\n      totalWorkflows: backups.length,\n      environment: 'producao'\n    }\n  };\n  \n  // 4. Salvar backup\n  await salvarBackup(backupData);\n  \n  return backupData;\n};\n
\n\n### Recuperação de Backup\n\n
javascript\n// Recuperar workflow de backup\nconst recuperarBackup = async (backupId, workflowIds = null) => {\n  // 1. Carregar backup\n  const backup = await carregarBackup(backupId);\n  \n  // 2. Filtrar workflows se necessário\n  const workflowsParaRecuperar = workflowIds \n    ? backup.workflows.filter(w => workflowIds.includes(w.id))\n    : backup.workflows;\n  \n  // 3. Recuperar workflows\n  const resultados = [];\n  for (const workflow of workflowsParaRecuperar) {\n    try {\n      const resultado = await importarWorkflow(workflow, {\n        sobrescrever: true,\n        importarCredenciais: true\n      });\n      \n      resultados.push({\n        nome: workflow.name,\n        sucesso: true,\n        id: resultado.id\n      });\n    } catch (error) {\n      resultados.push({\n        nome: workflow.name,\n        sucesso: false,\n        erro: error.message\n      });\n    }\n  }\n  \n  return resultados;\n};\n
\n\n## Versionamento de Workflows\n\n### Controle de Versões\n\n
javascript\n// Sistema de versionamento\nconst sistemaVersionamento = {\n  // Estrutura de versão\n  version: {\n    major: 1, // Mudanças incompatíveis\n    minor: 2, // Novas funcionalidades\n    patch: 0  // Correções\n  },\n  \n  // Histórico de versões\n  history: [\n    {\n      version: '1.2.0',\n      date: '2024-01-15',\n      author: 'joao@empresa.com',\n      changes: [\n        'Adicionado node de validação CPF',\n        'Corrigido bug no webhook trigger'\n      ]\n    }\n  ],\n  \n  // Tags de versão\n  tags: {\n    'v1.0.0': 'Primeira versão estável',\n    'v1.1.0': 'Adicionado suporte a PIX',\n    'v1.2.0': 'Melhorias de performance'\n  }\n};\n\n// Criar nova versão\nconst criarNovaVersao = async (workflowId, tipoMudanca = 'patch') => {\n  const workflow = await exportarWorkflow(workflowId);\n  const versaoAtual = workflow.versionId || '1.0.0';\n  const novaVersao = incrementarVersao(versaoAtual, tipoMudanca);\n  \n  const workflowVersionado = {\n    ...workflow,\n    versionId: novaVersao,\n    meta: {\n      ...workflow.meta,\n      versionHistory: [\n        ...(workflow.meta.versionHistory || []),\n        {\n          version: novaVersao,\n          date: new Date().toISOString(),\n          author: 'usuario@empresa.com',\n          changes: 'Mudanças automáticas'\n        }\n      ]\n    }\n  };\n  \n  return workflowVersionado;\n};\n
\n\n## Templates e Reutilização\n\n### Criar Template\n\n
javascript\n// Criar template reutilizável\nconst criarTemplate = async (workflowId, metadata) => {\n  const workflow = await exportarWorkflow(workflowId);\n  \n  const template = {\n    ...workflow,\n    template: true,\n    metadata: {\n      name: metadata.nome,\n      description: metadata.descricao,\n      category: metadata.categoria,\n      tags: metadata.tags,\n      version: metadata.versao,\n      author: metadata.autor,\n      license: metadata.licenca,\n      variables: metadata.variaveis || [],\n      instructions: metadata.instrucoes || ''\n    }\n  };\n  \n  return template;\n};\n\n// Exemplo: Template de automação de vendas\nconst metadataTemplate = {\n  nome: 'Automação de Vendas - Template',\n  descricao: 'Template para automação de processo de vendas',\n  categoria: 'Vendas',\n  tags: ['vendas', 'crm', 'automação', 'template'],\n  versao: '1.0.0',\n  autor: 'Equipe n8n Brasil',\n  licenca: 'MIT',\n  variaveis: [\n    {\n      name: 'CRM_API_URL',\n      description: 'URL da API do CRM',\n      required: true,\n      default: 'https://api.crm.com.br'\n    },\n    {\n      name: 'EMAIL_NOTIFICACAO',\n      description: 'Email para notificações',\n      required: true,\n      default: 'vendas@empresa.com'\n    }\n  ],\n  instrucoes: [\n    '1. Configure as variáveis obrigatórias',\n    '2. Ajuste as credenciais do CRM',\n    '3. Teste o workflow antes de ativar'\n  ]\n};\n\nconst template = await criarTemplate('workflow-123', metadataTemplate);\n
\n\n### Usar Template\n\n
javascript\n// Usar template com variáveis\nconst usarTemplate = async (template, variaveis) => {\n  // 1. Substituir variáveis no template\n  const workflowPersonalizado = substituirVariaveis(template, variaveis);\n  \n  // 2. Importar workflow personalizado\n  const resultado = await importarWorkflow(workflowPersonalizado, {\n    sobrescrever: false,\n    importarCredenciais: false\n  });\n  \n  return resultado;\n};\n\n// Função para substituir variáveis\nconst substituirVariaveis = (workflow, variaveis) => {\n  let workflowString = JSON.stringify(workflow);\n  \n  for (const [variavel, valor] of Object.entries(variaveis)) {\n    const regex = new RegExp(`\\{\\{${variavel}\\}\\}`, 'g');\n    workflowString = workflowString.replace(regex, valor);\n  }\n  \n  return JSON.parse(workflowString);\n};\n\n// Exemplo de uso\nconst variaveis = {\n  CRM_API_URL: 'https://api.meucrm.com.br',\n  EMAIL_NOTIFICACAO: 'vendas@minhaempresa.com'\n};\n\nconst resultado = await usarTemplate(template, variaveis);\n
\n\n## Segurança na Exportação/Importação\n\n### Sanitização de Dados\n\n
javascript\n// Sanitizar workflow antes da exportação\nconst sanitizarWorkflow = (workflow) => {\n  const workflowSanitizado = {\n    ...workflow,\n    nodes: workflow.nodes.map(node => {\n      // Remover credenciais sensíveis\n      const nodeSanitizado = { ...node };\n      delete nodeSanitizado.credentials;\n      \n      // Mascarar URLs sensíveis\n      if (nodeSanitizado.parameters && nodeSanitizado.parameters.url) {\n        nodeSanitizado.parameters.url = mascararUrl(nodeSanitizado.parameters.url);\n      }\n      \n      return nodeSanitizado;\n    })\n  };\n  \n  // Remover credenciais globais\n  delete workflowSanitizado.credentials;\n  \n  return workflowSanitizado;\n};\n\n// Mascarar URL sensível\nconst mascararUrl = (url) => {\n  try {\n    const urlObj = new URL(url);\n    return `${urlObj.protocol}//***.***.***/${urlObj.pathname}`;\n  } catch {\n    return '***URL_MASCARADA***';\n  }\n};\n
\n\n### Validação de Segurança\n\n
javascript\n// Validar segurança do workflow\nconst validarSeguranca = (workflow) => {\n  const problemas = [];\n  \n  // Verificar credenciais expostas\n  if (workflow.credentials) {\n    problemas.push('Workflow contém credenciais expostas');\n  }\n  \n  // Verificar URLs sensíveis\n  workflow.nodes.forEach(node => {\n    if (node.parameters && node.parameters.url) {\n      if (isUrlSensivel(node.parameters.url)) {\n        problemas.push(`Node ${node.name} contém URL sensível`);\n      }\n    }\n  });\n  \n  // Verificar dados pessoais\n  if (contemDadosPessoais(workflow)) {\n    problemas.push('Workflow contém dados pessoais');\n  }\n  \n  return {\n    seguro: problemas.length === 0,\n    problemas: problemas\n  };\n};\n\n// Verificar se URL é sensível\nconst isUrlSensivel = (url) => {\n  const urlsSensiveis = [\n    'localhost',\n    '127.0.0.1',\n    '192.168.',\n    '10.',\n    '172.'\n  ];\n  \n  return urlsSensiveis.some(sensivel => url.includes(sensivel));\n};\n
\n\n## Workflows de Exportação/Importação\n\n### Workflow: Backup Automático\n\n
mermaid\ngraph TD\n    A[Schedule Trigger: Diário às 2h] --> B[Code: Listar Workflows]\n    B --> C[Code: Exportar Workflows]\n    C --> D[Code: Criar Arquivo Backup]\n    D --> E[HTTP Request: Upload para S3]\n    E --> F[Code: Limpar Backups Antigos]\n    F --> G[Send Email: Backup Concluído]\n
\n\n### Workflow: Migração Entre Ambientes\n\n
mermaid\ngraph TD\n    A[Manual Trigger: Migrar Workflow] --> B[Code: Exportar de Origem]\n    B --> C[Code: Ajustar Configurações]\n    C --> D[Code: Validar Workflow]\n    D --> E[HTTP Request: Importar no Destino]\n    E --> F[Code: Verificar Importação]\n    F --> G[Send Notification: Migração Concluída]\n

Boas Práticas

Exportação

  • Sempre valide workflows antes da exportação
  • Sanitize dados sensíveis quando necessário
  • Use versionamento para controle de mudanças
  • Documente dependências e pré-requisitos

Importação

  • Valide workflows antes da importação
  • Teste em ambiente isolado primeiro
  • Configure credenciais adequadamente
  • Verifique compatibilidade de versões

Segurança

  • Nunca exporte credenciais em ambientes públicos
  • Use criptografia para backups
  • Valide origem dos workflows importados
  • Implemente auditoria de importações

Troubleshooting

Problemas Comuns

Erro na importação:

  • Verificar formato do arquivo JSON
  • Verificar compatibilidade de versão
  • Verificar permissões de usuário
  • Verificar configurações de rede

Credenciais não importadas:

  • Verificar se credenciais estão incluídas
  • Verificar permissões de credenciais
  • Verificar configurações de criptografia
  • Verificar mapeamento de credenciais

Workflow não funciona após importação:

  • Verificar configurações de ambiente
  • Verificar URLs e endpoints
  • Verificar credenciais e tokens
  • Verificar dependências externas

Recursos Adicionais

Documentação Oficial

Ferramentas Relacionadas

  • n8n CLI: Exportação/importação via linha de comando
  • Git: Versionamento de workflows
  • Docker: Containers para migração

Próximo: Tags e Organização - Organize seus workflows com tags