n8n-rdstation-crm
Version:
Nós personalizados do n8n para integração com a API do RD Station CRM (v1)
523 lines (522 loc) • 24.8 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RdStationCrmDeals = void 0;
const n8n_workflow_1 = require("n8n-workflow");
/**
* Classe para o nó de Negócios (Deals) do RD Station CRM
* Este nó permite interações com a API de Negócios do RD Station CRM.
*/
class RdStationCrmDeals {
constructor() {
this.description = {
// Informações básicas do nó
displayName: 'RD Station CRM Negócios',
name: 'rdStationCrmDeals',
icon: 'file:rdstation.svg',
group: ['transform'],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: 'Operações com negócios no RD Station CRM',
defaults: {
name: 'RD Station CRM Negócios',
},
inputs: ['main'],
outputs: ['main'],
credentials: [
{
name: 'rdStationCrmApi',
required: true,
},
],
properties: [
// Seleção do recurso (neste caso, só temos negócios/deals)
{
displayName: 'Recurso',
name: 'resource',
type: 'options',
noDataExpression: true,
options: [
{
name: 'Negócio',
value: 'deal',
},
],
default: 'deal',
required: true,
},
// Seleção da operação a ser realizada
{
displayName: 'Operação',
name: 'operation',
type: 'options',
noDataExpression: true,
displayOptions: {
show: {
resource: [
'deal',
],
},
},
options: [
{
name: 'Criar',
value: 'create',
description: 'Criar um novo negócio',
action: 'Criar um negócio',
},
{
name: 'Atualizar',
value: 'update',
description: 'Atualizar um negócio existente',
action: 'Atualizar um negócio',
},
{
name: 'Listar',
value: 'getAll',
description: 'Listar negócios',
action: 'Listar negócios',
},
{
name: 'Obter',
value: 'get',
description: 'Obter um negócio pelo ID',
action: 'Obter um negócio',
},
{
name: 'Listar Contatos do Negócio',
value: 'getContacts',
description: 'Listar contatos associados a um negócio',
action: 'Listar contatos de um negócio',
},
],
default: 'getAll',
},
// Campos para a operação LISTAR NEGÓCIOS
{
displayName: 'Parâmetros de Listagem',
name: 'listParameters',
type: 'collection',
placeholder: 'Adicionar Parâmetros',
default: {},
displayOptions: {
show: {
resource: [
'deal',
],
operation: [
'getAll',
],
},
},
options: [
{
displayName: 'Limite',
name: 'limit',
type: 'number',
default: 50,
description: 'Número máximo de negócios a retornar',
},
{
displayName: 'Página',
name: 'page',
type: 'number',
default: 1,
description: 'Número da página para retornar',
},
{
displayName: 'ID do Funil',
name: 'deal_pipeline_id',
type: 'string',
default: '',
description: 'Filtrar negócios por funil específico',
},
{
displayName: 'ID da Etapa',
name: 'deal_stage_id',
type: 'string',
default: '',
description: 'Filtrar negócios por etapa específica do funil',
},
{
displayName: 'ID do Usuário Responsável',
name: 'user_id',
type: 'string',
default: '',
description: 'Filtrar negócios por usuário responsável',
},
{
displayName: 'Status',
name: 'status',
type: 'options',
options: [
{
name: 'Aberto',
value: 'open',
},
{
name: 'Ganho',
value: 'won',
},
{
name: 'Perdido',
value: 'lost',
},
{
name: 'Todos',
value: 'all',
},
],
default: 'open',
description: 'Status do negócio a ser filtrado',
},
{
displayName: 'Ordenação',
name: 'order',
type: 'options',
options: [
{
name: 'Título',
value: 'title',
},
{
name: 'Data de Criação',
value: 'created_at',
},
{
name: 'Valor',
value: 'value',
},
],
default: 'created_at',
description: 'Campo pelo qual ordenar os resultados',
},
{
displayName: 'Direção da Ordenação',
name: 'direction',
type: 'options',
options: [
{
name: 'Ascendente',
value: 'asc',
},
{
name: 'Descendente',
value: 'desc',
},
],
default: 'desc',
description: 'Direção da ordenação (crescente ou decrescente)',
},
],
},
// Campos para a operação OBTER NEGÓCIO
{
displayName: 'ID do Negócio',
name: 'dealId',
type: 'string',
default: '',
required: true,
displayOptions: {
show: {
resource: [
'deal',
],
operation: [
'get',
'update',
'getContacts',
],
},
},
description: 'ID do negócio a ser consultado/atualizado',
},
// Campos para CRIAR e ATUALIZAR negócios
{
displayName: 'Dados do Negócio',
name: 'dealData',
type: 'collection',
placeholder: 'Adicionar Dados',
default: {},
displayOptions: {
show: {
resource: [
'deal',
],
operation: [
'create',
'update',
],
},
},
options: [
{
displayName: 'Título',
name: 'title',
type: 'string',
default: '',
description: 'Título ou nome do negócio (obrigatório para criação)',
},
{
displayName: 'ID da Empresa',
name: 'organization_id',
type: 'string',
default: '',
description: 'ID da empresa relacionada ao negócio',
},
{
displayName: 'ID do Funil',
name: 'deal_pipeline_id',
type: 'string',
default: '',
description: 'ID do funil de vendas no qual o negócio será criado',
},
{
displayName: 'ID da Etapa',
name: 'deal_stage_id',
type: 'string',
default: '',
description: 'ID da etapa do funil onde o negócio está atualmente',
},
{
displayName: 'ID do Usuário Responsável',
name: 'user_id',
type: 'string',
default: '',
description: 'ID do usuário responsável (owner) por esse negócio',
},
{
displayName: 'Valor',
name: 'value',
type: 'number',
default: 0,
description: 'Valor monetário do negócio',
},
{
displayName: 'Moeda',
name: 'currency',
type: 'options',
options: [
{
name: 'Real (BRL)',
value: 'BRL',
},
{
name: 'Dólar (USD)',
value: 'USD',
},
{
name: 'Euro (EUR)',
value: 'EUR',
},
],
default: 'BRL',
description: 'Moeda do valor do negócio',
},
],
},
// IDs de contatos para associar ao criar um negócio
{
displayName: 'IDs de Contatos',
name: 'contactIds',
placeholder: 'Adicionar ID de Contato',
type: 'fixedCollection',
typeOptions: {
multipleValues: true,
},
displayOptions: {
show: {
resource: [
'deal',
],
operation: [
'create',
'update',
],
},
},
default: {},
options: [
{
name: 'contactIdValues',
displayName: 'ID de Contato',
values: [
{
displayName: 'ID do Contato',
name: 'id',
type: 'string',
default: '',
description: 'ID do contato a ser associado ao negócio',
required: true,
},
],
},
],
},
],
};
}
/**
* Método principal que executa o nó com base na operação selecionada
*/
async execute() {
const items = this.getInputData();
const returnData = [];
// URL base da API do RD Station CRM
const baseUrl = 'https://crm.rdstation.com/api/v1';
const resource = this.getNodeParameter('resource', 0);
const operation = this.getNodeParameter('operation', 0);
// Para cada item de entrada, processa a operação solicitada
for (let i = 0; i < items.length; i++) {
try {
// Configuração comum para todas as requisições
const options = {
uri: '',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
json: true,
resolveWithFullResponse: true,
};
// Vamos determinar qual operação executar com base no recurso e operação selecionados
if (resource === 'deal') {
if (operation === 'getAll') {
// Operação: LISTAR NEGÓCIOS
// Preparando a requisição para listar negócios
options.method = 'GET';
options.uri = `${baseUrl}/deals`;
// Obtendo e aplicando parâmetros de filtro/paginação
const listParameters = this.getNodeParameter('listParameters', i);
const qs = {};
// Adicionando os parâmetros à query string
if (listParameters.limit)
qs.limit = listParameters.limit;
if (listParameters.page)
qs.page = listParameters.page;
if (listParameters.deal_pipeline_id)
qs.deal_pipeline_id = listParameters.deal_pipeline_id;
if (listParameters.deal_stage_id)
qs.deal_stage_id = listParameters.deal_stage_id;
if (listParameters.user_id)
qs.user_id = listParameters.user_id;
if (listParameters.status)
qs.status = listParameters.status;
if (listParameters.order)
qs.order = listParameters.order;
if (listParameters.direction)
qs.direction = listParameters.direction;
options.qs = qs;
}
else if (operation === 'get') {
// Operação: OBTER NEGÓCIO ESPECÍFICO
// Obtém o ID do negócio a ser consultado
const dealId = this.getNodeParameter('dealId', i);
// Verifica se o ID do negócio foi fornecido
if (!dealId) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'É necessário fornecer um ID de negócio válido!', { itemIndex: i });
}
// Configurando a requisição para buscar um negócio específico
options.method = 'GET';
options.uri = `${baseUrl}/deals/${dealId}`;
}
else if (operation === 'getContacts') {
// Operação: LISTAR CONTATOS DO NEGÓCIO
// Obtém o ID do negócio para listar seus contatos
const dealId = this.getNodeParameter('dealId', i);
// Verifica se o ID do negócio foi fornecido
if (!dealId) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'É necessário fornecer um ID de negócio válido!', { itemIndex: i });
}
// Configurando a requisição para buscar contatos de um negócio específico
options.method = 'GET';
options.uri = `${baseUrl}/deals/${dealId}/contacts`;
}
else if (operation === 'create') {
// Operação: CRIAR NEGÓCIO
// Configurando requisição para criar negócio
options.method = 'POST';
options.uri = `${baseUrl}/deals`;
// Obtendo os dados do negócio
const dealData = this.getNodeParameter('dealData', i);
// Verificando se o título foi fornecido (obrigatório para criação)
if (!dealData.title) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'O título do negócio é obrigatório para criação!', { itemIndex: i });
}
// Preparando o corpo da requisição
const body = { ...dealData };
// Adicionando IDs de contatos ao corpo
const contactIdsCollection = this.getNodeParameter('contactIds', i);
if (contactIdsCollection.contactIdValues && contactIdsCollection.contactIdValues.length > 0) {
body.contact_ids = contactIdsCollection.contactIdValues.map(item => item.id);
}
options.body = body;
}
else if (operation === 'update') {
// Operação: ATUALIZAR NEGÓCIO
// Obtém o ID do negócio a ser atualizado
const dealId = this.getNodeParameter('dealId', i);
// Verifica se o ID do negócio foi fornecido
if (!dealId) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'É necessário fornecer um ID de negócio válido para atualização!', { itemIndex: i });
}
// Configurando a requisição para atualizar o negócio
options.method = 'PUT';
options.uri = `${baseUrl}/deals/${dealId}`;
// Obtendo os dados a serem atualizados
const dealData = this.getNodeParameter('dealData', i);
// Preparando o corpo da requisição
const body = {};
// Adicionando apenas campos que não estão vazios
if (dealData.title)
body.title = dealData.title;
if (dealData.organization_id)
body.organization_id = dealData.organization_id;
if (dealData.deal_pipeline_id)
body.deal_pipeline_id = dealData.deal_pipeline_id;
if (dealData.deal_stage_id)
body.deal_stage_id = dealData.deal_stage_id;
if (dealData.user_id)
body.user_id = dealData.user_id;
if (dealData.value !== undefined)
body.value = dealData.value;
if (dealData.currency)
body.currency = dealData.currency;
// Adicionando IDs de contatos ao corpo, se fornecidos
const contactIdsCollection = this.getNodeParameter('contactIds', i);
if (contactIdsCollection.contactIdValues && contactIdsCollection.contactIdValues.length > 0) {
body.contact_ids = contactIdsCollection.contactIdValues.map(item => item.id);
}
// Verifica se há campos para atualizar
if (Object.keys(body).length === 0) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'É necessário fornecer pelo menos um campo para atualizar o negócio!', { itemIndex: i });
}
options.body = body;
}
}
// Executa a requisição HTTP com as opções configuradas
const response = await this.helpers.requestWithAuthentication.call(this, 'rdStationCrmApi', options);
// Extrai os dados da resposta e adiciona ao retorno
const responseData = response.body;
returnData.push({
json: responseData,
pairedItem: { item: i },
});
}
catch (error) {
// Trata e reporta erros ocorridos durante a execução
if (this.continueOnFail()) {
returnData.push({
json: {
error: error instanceof Error ? error.message : String(error),
},
pairedItem: { item: i },
});
continue;
}
throw error;
}
}
return [returnData];
}
}
exports.RdStationCrmDeals = RdStationCrmDeals;