corbee-crm

Nodes do n8n para integração com a API do Corbee CRM

Package Information

Released: 8/9/2025
Downloads: 0 weekly / 0 monthly
Latest Version: 0.1.0
Author: robertogoes

Documentation

🚀 n8n Corbee CRM Nodes

Nodes para integrar o n8n ao Corbee CRM. Inclui operações para listar atendimentos, alterar atendimento, atualizar cliente a partir de atendimento, marcar ganho e marcar perdido.

📋 Índice

🎯 Visão Geral

O que é este projeto?

Este é um template base para desenvolver nodes customizados do n8n. Ele fornece:

  • ✅ Estrutura completa seguindo padrões oficiais n8n
  • ✅ Sistema de autenticação flexível (API Key, Bearer, Basic Auth)
  • ✅ Operações CRUD prontas para usar
  • ✅ Tratamento de erros robusto
  • ✅ Validação de dados
  • ✅ Compatibilidade com LLMs/Agents (usableAsTool: true)
  • ✅ TypeScript com tipos completos
  • ✅ Configuração de linting e formatação

Quando usar este template?

Use este template quando precisar:

  • Integrar uma API REST ao n8n
  • Criar um node customizado para sua empresa
  • Desenvolver conectores para serviços que não existem no n8n
  • Aprender como desenvolver nodes para n8n

🚀 Início Rápido

1. Clone e Configure

# Clone este repositório
git clone <url-do-repo>
cd n8n_base

# Instale as dependências
pnpm install  # ou npm install

# Build inicial para verificar
pnpm run build

2. Checklist de Modificação Rápida

Para adaptar este template para sua API, você precisa modificar:

  • package.json: Nome, descrição, autor ajustados para Corbee
  • credentials/CorbeeCredentialsApi.credentials.ts: Token e URL
  • nodes/Corbee/Corbee.node.ts: Operações Corbee
  • nodes/Corbee/CorbeeHelpers.ts: Lógica de requisições
  • nodes/Corbee/icon.svg: Ícone do node
  • README.md: Documentação específica

📁 Estrutura do Projeto

n8n_base/
├── credentials/                              # Definições de credenciais
│   └── GenericApiCredentialsApi.credentials.ts  # Configuração de autenticação
│
├── nodes/                                   # Implementação dos nodes
│   └── GenericApi/
│       ├── GenericApi.node.ts              # Node principal - define UI e operações
│       ├── GenericApiHelpers.ts            # Funções auxiliares - requests, validação
│       └── icon.svg                        # Ícone do node (60x60 recomendado)
│
├── .editorconfig                            # Configuração do editor
├── .eslintrc.js                             # Regras de linting
├── .gitignore                               # Arquivos ignorados pelo git
├── .npmignore                               # Arquivos ignorados no npm publish
├── .prettierrc                              # Configuração de formatação
│
├── index.ts                                 # Entry point - exporta nodes e credentials
├── package.json                             # Configuração do projeto e dependências
├── tsconfig.json                            # Configuração TypeScript
└── README.md                                # Esta documentação

Descrição dos Arquivos Principais

credentials/CorbeeCredentialsApi.credentials.ts

Campos:

  • apiUrl: URL base (padrão https://api.crm.corbee.com.br)
  • integrationToken: token enviado em corbee-token-integration

nodes/Corbee/Corbee.node.ts

Operações:

  • listAttendances (GET /pipeline/attendances com filtros document, phone, page, limit)
  • updateAttendance (PUT /attendances/{id})
  • updateCustomerFromAttendance (PUT /customer/{id}/from-attendance)
  • markAttendanceGain (PUT /attendances/{id}/gain)
  • markAttendanceLoss (PUT /attendances/{id}/loss com reason_loss_id)

nodes/Corbee/CorbeeHelpers.ts

Faz a requisição HTTP com header corbee-token-integration, aceita headers e query params customizados e normaliza erros.

index.ts

Exporta Generic API (template) e Corbee CRM.

🛠 Guia de Desenvolvimento

Passo 1: Configurar Credenciais

Modifique credentials/GenericApiCredentialsApi.credentials.ts:

export class SuaApiCredentialsApi implements ICredentialType {
	name = 'suaApiCredentialsApi';  // Nome interno (sempre termina com Api)
	displayName = 'Sua API';        // Nome exibido na UI
	documentationUrl = 'https://docs.suaapi.com/auth';
	
	properties: INodeProperties[] = [
		{
			displayName: 'API URL',
			name: 'apiUrl',
			type: 'string',
			default: 'https://api.suaempresa.com',
			required: true,
		},
		// Adicione seus campos de autenticação aqui
	];
}

Passo 2: Usar o Node Corbee

Modifique nodes/GenericApi/GenericApi.node.ts:

export class SuaApi implements INodeType {
	description: INodeTypeDescription = {
		displayName: 'Sua API',
		name: 'suaApi',  // Nome interno (camelCase)
		icon: 'file:icon.svg',
		group: ['transform'],
		version: 1,
		subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
		description: 'Integração com Sua API',
		documentationUrl: 'https://docs.suaapi.com',
		defaults: {
			name: 'Sua API',
		},
		inputs: ['main'],
		outputs: ['main'],
		credentials: [
			{
				name: 'suaApiCredentialsApi',
				required: true,
			},
		],
		properties: [
			// Defina seus campos aqui
		],
	};
	
	async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
		// Lógica de execução
	}
}

Passo 3: Operações já incluídas

Exemplo de como adicionar uma nova operação:

// Em GenericApi.node.ts, dentro de properties:
{
	displayName: 'Operação',
	name: 'operation',
	type: 'options',
	options: [
		{
			name: 'Buscar Cliente',  // Nome na UI
			value: 'getCustomer',    // Valor interno
			description: 'Busca um cliente por ID',
			action: 'Buscar um cliente',  // Descrição da ação
		},
		// Adicione mais operações aqui
	],
	default: 'getCustomer',
}

Passo 4: Validações

Em GenericApiHelpers.ts, adicione validações customizadas:

// Validação de CPF
validateCPF(cpf: string): boolean {
	// Implementação da validação
	return true;
}

// Validar antes de fazer a requisição
validateInput(data: IDataObject, operation: string): void {
	if (operation === 'createCustomer') {
		if (!this.validateCPF(data.cpf as string)) {
			throw new NodeOperationError(
				this.context.getNode(),
				'CPF inválido'
			);
		}
	}
}

Passo 5: Tratamento de Erros

Sempre use os erros apropriados do n8n:

import { NodeApiError, NodeOperationError } from 'n8n-workflow';

// Para erros de API
throw new NodeApiError(this.getNode(), error, {
	message: 'Falha na API',
	description: 'Verifique suas credenciais',
});

// Para erros de operação
throw new NodeOperationError(
	this.getNode(),
	'Operação inválida',
	{ description: 'Esta operação não é suportada' }
);

💡 Exemplos Práticos

Exemplo 1: Integração com API de CRM

// Modificar operações para CRM
options: [
	{ name: 'Criar Lead', value: 'createLead' },
	{ name: 'Buscar Lead', value: 'getLead' },
	{ name: 'Atualizar Lead', value: 'updateLead' },
	{ name: 'Converter Lead', value: 'convertLead' },
]

// Implementar no execute()
case 'createLead':
	const leadData = {
		name: this.getNodeParameter('name', i) as string,
		email: this.getNodeParameter('email', i) as string,
		phone: this.getNodeParameter('phone', i) as string,
	};
	responseData = await helper.makeRequest(
		'POST',
		'/leads',
		leadData,
		additionalOptions
	);
	break;

Exemplo 2: Adicionar Paginação

case 'getAll':
	const returnAll = this.getNodeParameter('returnAll', i) as boolean;
	
	if (returnAll) {
		// Buscar todas as páginas
		const allData = [];
		let page = 1;
		let hasMore = true;
		
		while (hasMore) {
			const response = await helper.makeRequest(
				'GET',
				`/items?page=${page}&limit=100`
			);
			allData.push(...response.data);
			hasMore = response.hasNextPage;
			page++;
		}
		responseData = allData;
	} else {
		// Buscar apenas o limite especificado
		const limit = this.getNodeParameter('limit', i) as number;
		responseData = await helper.makeRequest(
			'GET',
			`/items?limit=${limit}`
		);
	}
	break;

Exemplo 3: Implementar OAuth2

// Em credentials
{
	displayName: 'Grant Type',
	name: 'grantType',
	type: 'options',
	options: [
		{ name: 'Client Credentials', value: 'clientCredentials' },
		{ name: 'Authorization Code', value: 'authorizationCode' },
	],
	default: 'clientCredentials',
},

// Em helpers, implementar refresh token
async getOAuth2Token(): Promise<string> {
	if (this.tokenExpired()) {
		const response = await this.context.helpers.httpRequest({
			method: 'POST',
			url: `${this.credentials.tokenUrl}`,
			body: {
				grant_type: 'client_credentials',
				client_id: this.credentials.clientId,
				client_secret: this.credentials.clientSecret,
			},
		});
		this.saveToken(response.access_token, response.expires_in);
	}
	return this.currentToken;
}

📝 Scripts e Comandos

# Desenvolvimento
pnpm run dev        # Watch mode - recompila ao salvar
pnpm run build      # Build para produção

# Qualidade de código
pnpm run lint       # Verifica erros de linting
pnpm run lint:fix   # Corrige erros automaticamente
pnpm run format     # Formata código com Prettier

# Publicação
pnpm run prepublishOnly  # Roda antes de publicar (build + lint)

🚢 Deploy e Publicação

Publicar no NPM

  1. Atualize a versão em package.json
  2. Build e teste:
    pnpm run build
    pnpm run lint
    
  3. Publique:
    npm publish
    

Instalar em Produção

# Global
npm install -g n8n-nodes-sua-api

# Ou no diretório custom do n8n
cd ~/.n8n/custom
npm install n8n-nodes-sua-api

Desenvolvimento Local

Para testar no n8n local:

# No diretório do seu node
npm link

# No diretório custom do n8n
cd ~/.n8n/custom
npm link n8n-nodes-sua-api

# Reinicie o n8n
n8n start

✅ Boas Práticas

1. Nomenclatura

  • Credentials: Sempre termine com Api (ex: SuaEmpresaCredentialsApi)
  • Node name: Use camelCase (ex: suaEmpresa)
  • Display name: Use title case (ex: Sua Empresa)
  • Operations: Use verbos descritivos (ex: Create User, não User)

2. Segurança

  • ✅ Nunca logue credenciais
  • ✅ Use typeOptions: { password: true } para campos sensíveis
  • ✅ Valide todos os inputs
  • ✅ Sanitize dados antes de enviar para API
  • ✅ Use HTTPS sempre que possível

3. Performance

  • ✅ Implemente paginação para listas grandes
  • ✅ Use batch operations quando disponível
  • ✅ Adicione timeout apropriado
  • ✅ Implemente retry com backoff exponencial
  • ✅ Cache tokens OAuth quando apropriado

4. UX

  • ✅ Mensagens de erro claras e acionáveis
  • ✅ Placeholders úteis nos campos
  • ✅ Descrições explicativas
  • ✅ Valores padrão sensatos
  • ✅ Use displayOptions para mostrar campos condicionalmente

5. Código

  • ✅ Use TypeScript strict mode
  • ✅ Sempre trate erros
  • ✅ Documente funções complexas
  • ✅ Mantenha funções pequenas e focadas
  • ✅ Use helpers para lógica reutilizável

🐛 Troubleshooting

Problema: "Node não aparece no n8n"

Soluções:

  1. Verifique se o build foi feito: pnpm run build
  2. Confirme o caminho em package.json -> n8n.nodes
  3. Reinicie o n8n após instalar
  4. Verifique logs do n8n para erros de carregamento

Problema: "Credenciais não funcionam"

Soluções:

  1. Nome da credential deve terminar com Api
  2. Verifique se o nome em node.credentials corresponde
  3. Teste a autenticação com Postman/Insomnia primeiro
  4. Verifique os headers sendo enviados

Problema: "TypeScript errors no build"

Soluções:

  1. Instale types: pnpm install -D @types/node
  2. Verifique versão do TypeScript: deve ser 5.x
  3. Use as any para tipos complexos do n8n se necessário

Problema: "Lint errors"

Soluções:

  1. Run: pnpm run lint:fix
  2. Para regras específicas do n8n, pode desabilitar em .eslintrc.js
  3. Mantenha consistência com o estilo do projeto

📚 Recursos Úteis

Documentação Oficial

Exemplos e Templates

Comunidade

Ferramentas Úteis

📄 Licença

MIT - Sinta-se livre para usar este template em seus projetos!

🤝 Contribuindo

Contribuições são bem-vindas! Por favor:

  1. Fork o projeto
  2. Crie sua feature branch (git checkout -b feature/MinhaFeature)
  3. Commit suas mudanças (git commit -m 'Add: MinhaFeature')
  4. Push para a branch (git push origin feature/MinhaFeature)
  5. Abra um Pull Request

💬 Suporte

Se você tiver dúvidas ou precisar de ajuda:

  1. Verifique a seção Troubleshooting
  2. Procure em Issues existentes
  3. Abra uma nova issue com detalhes do problema
  4. Pergunte na comunidade n8n

Desenvolvido com ❤️ para a comunidade n8n

Este é um template base. Personalize-o para suas necessidades específicas!

Discussion