n8n-nodes-rd-station-crm
Version:
Nós personalizados do n8n para integração com a API do RD Station CRM (v1)
738 lines (737 loc) • 34.2 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.RdStationCrmContacts = void 0;
const n8n_workflow_1 = require("n8n-workflow");
/**
* Classe para o nó de Contatos do RD Station CRM
* Este nó permite interações com a API de Contatos do RD Station CRM.
*
* Documentação oficial: https://developers.rdstation.com/reference/api-rd-station-doc
*/
class RdStationCrmContacts {
constructor() {
this.description = {
// Informações básicas do nó
displayName: "RD Station CRM Contatos",
name: "rdStationCrmContacts",
icon: "file:rdstation.svg",
group: ["transform"],
version: 1,
subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
description: "Operações com contatos no RD Station CRM",
defaults: {
name: "RD Station CRM Contatos",
},
inputs: ["main"],
outputs: ["main"],
credentials: [
{
name: "rdStationCrmApi",
required: true,
},
],
properties: [
// Seleção do recurso
{
displayName: "Recurso",
name: "resource",
type: "options",
noDataExpression: true,
options: [
{
name: "Contato",
value: "contact",
},
],
default: "contact",
required: true,
},
// Seleção da operação
{
displayName: "Operação",
name: "operation",
type: "options",
noDataExpression: true,
displayOptions: {
show: {
resource: ["contact"],
},
},
options: [
{
name: "Criar",
value: "create",
description: "Criar um novo contato",
action: "Criar um contato",
},
{
name: "Atualizar",
value: "update",
description: "Atualizar um contato existente",
action: "Atualizar um contato",
},
{
name: "Listar",
value: "getAll",
description: "Listar contatos",
action: "Listar contatos",
},
{
name: "Obter",
value: "get",
description: "Obter um contato pelo ID",
action: "Obter um contato",
},
],
default: "getAll",
},
// ===== CAMPOS PARA LISTAR CONTATOS =====
{
displayName: "Filtros",
name: "filters",
type: "collection",
placeholder: "Adicionar Filtro",
default: {},
displayOptions: {
show: {
resource: ["contact"],
operation: ["getAll"],
},
},
options: [
{
displayName: "Página",
name: "page",
type: "number",
default: 1,
description: "Número da página listada. Valor padrão é 1",
},
{
displayName: "Limite",
name: "limit",
type: "number",
default: 20,
description: "Limite de contatos que virão por listagem. Valor padrão é 20. Valor máximo é 200",
},
{
displayName: "Ordenar Por",
name: "order",
type: "options",
options: [
{
name: "Nome",
value: "name",
},
{
name: "Data de Criação",
value: "created_at",
},
{
name: "Data de Atualização",
value: "updated_at",
},
],
default: "name",
description: "Campo para ordenação",
},
{
displayName: "Direção",
name: "direction",
type: "options",
options: [
{
name: "Ascendente",
value: "asc",
},
{
name: "Descendente",
value: "desc",
},
],
default: "asc",
description: 'Ordenação da lista. "asc" ou "desc", padrão é "asc"',
},
{
displayName: "Busca",
name: "q",
type: "string",
default: "",
description: "Busca por nome do contato",
},
{
displayName: "E-mail",
name: "email",
type: "string",
default: "",
description: "Filtrar por e-mail do contato",
},
{
displayName: "Telefone",
name: "phone",
type: "string",
default: "",
description: "Filtrar por telefone do contato",
},
{
displayName: "Cargo",
name: "title",
type: "string",
default: "",
description: "Filtrar por cargo do contato",
},
{
displayName: "ID da Organização",
name: "organization_id",
type: "string",
default: "",
description: "ID da organização à qual o contato pertence",
},
{
displayName: "ID do Usuário",
name: "user_id",
type: "string",
default: "",
description: "ID do usuário responsável pelo contato",
},
],
},
// ===== CAMPOS PARA OBTER CONTATO =====
{
displayName: "ID do Contato",
name: "contact_id",
type: "string",
default: "",
required: true,
displayOptions: {
show: {
resource: ["contact"],
operation: ["get", "update"],
},
},
description: "ID do contato",
},
// ===== CAMPOS PARA CRIAR CONTATO =====
{
displayName: "Nome",
name: "name",
type: "string",
default: "",
required: true,
displayOptions: {
show: {
resource: ["contact"],
operation: ["create"],
},
},
description: "Nome do contato (obrigatório, mínimo 2 caracteres)",
},
// ===== CAMPOS PARA CRIAR/ATUALIZAR CONTATO =====
{
displayName: "Dados do Contato",
name: "contactData",
type: "collection",
placeholder: "Adicionar Campo",
default: {},
displayOptions: {
show: {
resource: ["contact"],
operation: ["create", "update"],
},
},
options: [
{
displayName: "Nome",
name: "name",
type: "string",
default: "",
description: "Nome do contato (mínimo 2 caracteres)",
displayOptions: {
show: {
"/operation": ["update"],
},
},
},
{
displayName: "Cargo",
name: "title",
type: "string",
default: "",
description: "Cargo do contato",
},
{
displayName: "Aniversário",
name: "birthday",
type: "dateTime",
default: "",
description: "Data de aniversário (formato: yyyy-mm-dd)",
},
{
displayName: "ID da Organização",
name: "organization_id",
type: "string",
default: "",
description: "ID da organização à qual o contato pertence",
},
{
displayName: "IDs das Negociações",
name: "deal_ids",
type: "string",
default: "",
description: "IDs das negociações separados por vírgula (ex: id1,id2,id3)",
},
{
displayName: "Facebook",
name: "facebook",
type: "string",
default: "",
description: "Perfil do Facebook",
},
{
displayName: "LinkedIn",
name: "linkedin",
type: "string",
default: "",
description: "Perfil do LinkedIn",
},
{
displayName: "Skype",
name: "skype",
type: "string",
default: "",
description: "Usuário do Skype",
},
],
},
// E-mails do contato
{
displayName: "E-mails",
name: "emails",
type: "fixedCollection",
typeOptions: {
multipleValues: true,
},
placeholder: "Adicionar E-mail",
default: {},
displayOptions: {
show: {
resource: ["contact"],
operation: ["create", "update"],
},
},
options: [
{
name: "emailValues",
displayName: "E-mail",
values: [
{
displayName: "E-mail",
name: "email",
type: "string",
default: "",
description: "Endereço de e-mail",
required: true,
},
{
displayName: "Tipo",
name: "type",
type: "options",
options: [
{
name: "Pessoal",
value: "personal",
},
{
name: "Comercial",
value: "work",
},
{
name: "Outro",
value: "other",
},
],
default: "personal",
description: "Tipo de e-mail",
},
{
displayName: "Principal",
name: "primary",
type: "boolean",
default: false,
description: "Definir como e-mail principal",
},
],
},
],
},
// Telefones do contato
{
displayName: "Telefones",
name: "phones",
type: "fixedCollection",
typeOptions: {
multipleValues: true,
},
placeholder: "Adicionar Telefone",
default: {},
displayOptions: {
show: {
resource: ["contact"],
operation: ["create", "update"],
},
},
options: [
{
name: "phoneValues",
displayName: "Telefone",
values: [
{
displayName: "Número",
name: "phone",
type: "string",
default: "",
description: "Número de telefone",
required: true,
},
{
displayName: "Tipo",
name: "type",
type: "options",
options: [
{
name: "Celular",
value: "mobile",
},
{
name: "Residencial",
value: "home",
},
{
name: "Comercial",
value: "work",
},
{
name: "Fax",
value: "fax",
},
],
default: "mobile",
description: "Tipo de telefone",
},
],
},
],
},
// Campos customizados
{
displayName: "Campos Customizados",
name: "contact_custom_fields",
type: "fixedCollection",
typeOptions: {
multipleValues: true,
},
placeholder: "Adicionar Campo Customizado",
default: {},
displayOptions: {
show: {
resource: ["contact"],
operation: ["create", "update"],
},
},
options: [
{
name: "customFieldValues",
displayName: "Campo Customizado",
values: [
{
displayName: "ID do Campo",
name: "custom_field_id",
type: "string",
default: "",
description: "ID do campo customizado",
},
{
displayName: "Valor",
name: "value",
type: "string",
default: "",
description: "Valor do campo customizado",
},
],
},
],
},
// Base legal
{
displayName: "Base Legal",
name: "legal_bases",
type: "fixedCollection",
typeOptions: {
multipleValues: true,
},
placeholder: "Adicionar Base Legal",
default: {},
displayOptions: {
show: {
resource: ["contact"],
operation: ["create", "update"],
},
},
options: [
{
name: "legalBaseValues",
displayName: "Base Legal",
values: [
{
displayName: "ID da Base Legal",
name: "id",
type: "string",
default: "",
description: "ID da base legal",
},
{
displayName: "Categoria",
name: "category",
type: "string",
default: "",
description: "Categoria da base legal",
},
],
},
],
},
],
};
}
/**
* 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,
};
if (resource === "contact") {
if (operation === "getAll") {
// LISTAR CONTATOS
options.method = "GET";
options.uri = `${baseUrl}/contacts`;
// Obter filtros
const filters = this.getNodeParameter("filters", i);
const qs = {};
// Adicionar filtros
if (filters.page)
qs.page = filters.page;
if (filters.limit)
qs.limit = filters.limit;
if (filters.order)
qs.order = filters.order;
if (filters.direction)
qs.direction = filters.direction;
if (filters.q)
qs.q = filters.q;
if (filters.email)
qs.email = filters.email;
if (filters.phone)
qs.phone = filters.phone;
if (filters.title)
qs.title = filters.title;
if (filters.organization_id)
qs.organization_id = filters.organization_id;
if (filters.user_id)
qs.user_id = filters.user_id;
options.qs = qs;
}
else if (operation === "get") {
// OBTER CONTATO
const contactId = this.getNodeParameter("contact_id", i);
if (!contactId) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), "ID do contato é obrigatório!", { itemIndex: i });
}
options.method = "GET";
options.uri = `${baseUrl}/contacts/${contactId}`;
}
else if (operation === "create") {
// CRIAR CONTATO
options.method = "POST";
options.uri = `${baseUrl}/contacts`;
const name = this.getNodeParameter("name", i);
if (!name || name.length < 2) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), "Nome do contato é obrigatório e deve ter no mínimo 2 caracteres!", { itemIndex: i });
}
// Construir o corpo da requisição
const body = {
contact: {
name,
},
};
// Dados do contato
const contactData = this.getNodeParameter("contactData", i);
if (contactData.title)
body.contact.title = contactData.title;
if (contactData.birthday) {
const date = new Date(contactData.birthday);
body.contact.birthday = date.toISOString().split("T")[0];
}
if (contactData.organization_id)
body.contact.organization_id = contactData.organization_id;
if (contactData.deal_ids) {
const dealIds = contactData.deal_ids
.split(",")
.map((id) => id.trim());
body.contact.deal_ids = dealIds;
}
if (contactData.facebook)
body.contact.facebook = contactData.facebook;
if (contactData.linkedin)
body.contact.linkedin = contactData.linkedin;
if (contactData.skype)
body.contact.skype = contactData.skype;
// E-mails
const emails = this.getNodeParameter("emails", i);
if (emails.emailValues && emails.emailValues.length > 0) {
body.contact.emails = emails.emailValues.map((e) => ({
email: e.email,
type: e.type || "personal",
primary: e.primary || false,
}));
}
// Telefones
const phones = this.getNodeParameter("phones", i);
if (phones.phoneValues && phones.phoneValues.length > 0) {
body.contact.phones = phones.phoneValues.map((p) => ({
phone: p.phone,
type: p.type || "",
}));
}
// Campos customizados
const customFields = this.getNodeParameter("contact_custom_fields", i);
if (customFields.customFieldValues &&
customFields.customFieldValues.length > 0) {
body.contact.contact_custom_fields =
customFields.customFieldValues.map((field) => ({
custom_field_id: field.custom_field_id,
value: field.value,
}));
}
// Base legal
const legalBases = this.getNodeParameter("legal_bases", i);
if (legalBases.legalBaseValues &&
legalBases.legalBaseValues.length > 0) {
body.contact.legal_bases = legalBases.legalBaseValues;
}
options.body = body;
}
else if (operation === "update") {
// ATUALIZAR CONTATO
const contactId = this.getNodeParameter("contact_id", i);
if (!contactId) {
throw new n8n_workflow_1.NodeOperationError(this.getNode(), "ID do contato é obrigatório!", { itemIndex: i });
}
options.method = "PUT";
options.uri = `${baseUrl}/contacts/${contactId}`;
// Construir o corpo da requisição
const body = {
contact: {},
};
// Dados do contato
const contactData = this.getNodeParameter("contactData", i);
if (contactData.name && contactData.name.length >= 2)
body.contact.name = contactData.name;
if (contactData.title)
body.contact.title = contactData.title;
if (contactData.birthday) {
const date = new Date(contactData.birthday);
body.contact.birthday = date.toISOString().split("T")[0];
}
if (contactData.organization_id)
body.contact.organization_id = contactData.organization_id;
if (contactData.deal_ids) {
const dealIds = contactData.deal_ids
.split(",")
.map((id) => id.trim());
body.contact.deal_ids = dealIds;
}
if (contactData.facebook)
body.contact.facebook = contactData.facebook;
if (contactData.linkedin)
body.contact.linkedin = contactData.linkedin;
if (contactData.skype)
body.contact.skype = contactData.skype;
// E-mails
const emails = this.getNodeParameter("emails", i);
if (emails.emailValues && emails.emailValues.length > 0) {
body.contact.emails = emails.emailValues.map((e) => ({
email: e.email,
type: e.type || "personal",
primary: e.primary || false,
}));
}
// Telefones
const phones = this.getNodeParameter("phones", i);
if (phones.phoneValues && phones.phoneValues.length > 0) {
body.contact.phones = phones.phoneValues.map((p) => ({
phone: p.phone,
type: p.type || "",
}));
}
// Campos customizados
const customFields = this.getNodeParameter("contact_custom_fields", i);
if (customFields.customFieldValues &&
customFields.customFieldValues.length > 0) {
body.contact.contact_custom_fields =
customFields.customFieldValues.map((field) => ({
custom_field_id: field.custom_field_id,
value: field.value,
}));
}
// Base legal
const legalBases = this.getNodeParameter("legal_bases", i);
if (legalBases.legalBaseValues &&
legalBases.legalBaseValues.length > 0) {
body.contact.legal_bases = legalBases.legalBaseValues;
}
options.body = body;
}
}
// Executar a requisição
const response = await this.helpers.requestWithAuthentication.call(this, "rdStationCrmApi", options);
// Extrair os dados da resposta
const responseData = response.body;
returnData.push({
json: responseData,
pairedItem: { item: i },
});
}
catch (error) {
// Tratamento de erros
if (this.continueOnFail()) {
returnData.push({
json: {
error: error instanceof Error ? error.message : String(error),
},
pairedItem: { item: i },
});
continue;
}
throw error;
}
}
return [returnData];
}
}
exports.RdStationCrmContacts = RdStationCrmContacts;