/** * El nodo de HubSpot: contactos, empresas, negocios y tickets del CRM. * * ## Por qué existe * * [2026-10-10] Ariel: «quiero implementar HubSpot», trigger y acción, por * OAuth con la app de HostWebhook (un proyecto de la CLI de HubSpot, * distribución `marketplace`). El alcance de la primera versión lo aprobó él: * crear, actualizar, leer, buscar y borrar contactos (con «crear o actualizar * por email»), empresas, negocios y tickets; asociar registros; notas y * tareas; añadir y quitar de listas. * * ## Se elige de una lista, no se escribe * * Owners, pipelines, etapas, listas, las opciones de una propiedad * (lifecycle stage, lead status, prioridad) y las propiedades mismas salen de * la cuenta conectada: el panel las pide al api y las enseña en un selector * (con «escribir a mano» detrás, para las plantillas). Son los tipos * `owner`, `pipeline`, `stage`, `list`, `enum`, `property`, `propertyList` y * `properties`. * * ## Los campos y las propiedades de HubSpot * * Un parámetro con `propiedad` rellena ESA propiedad del registro. «Other * properties» (`properties`) añade las demás —también las personalizadas de * la cuenta— y gana a los campos de arriba si repiten nombre: es lo último * que se escribe. Un campo vacío no se manda (en «update», queda como * estaba). * * ## Cómo se nombra todo * * Por su id de HubSpot (un número, en texto). Lo normal es que venga del * trigger: `{{payload.objectId}}`. * * ## Lo que se añadió para terminarlo (2026-10-11) * * Ariel aprobó todo lo que quedaba fuera de la primera versión: borrar un * contacto para siempre (GDPR), etiquetas de asociación, registrar llamadas y * reuniones, productos con sus partidas en los negocios, presupuestos, * formularios y conversaciones. Productos, partidas, presupuestos, * formularios y conversaciones piden permisos opcionales nuevos: una cuenta * conectada antes tiene que reconectar (el error lo dice). * * ⚠️ El orden de este array es el orden del desplegable. */ export declare const HUBSPOT_OPERATIONS: readonly ["createContact", "updateContact", "upsertContact", "getContact", "searchContacts", "deleteContact", "gdprDeleteContact", "createCompany", "updateCompany", "getCompany", "searchCompanies", "deleteCompany", "createDeal", "updateDeal", "getDeal", "searchDeals", "deleteDeal", "createTicket", "updateTicket", "getTicket", "searchTickets", "deleteTicket", "associateRecords", "removeAssociation", "listAssociationLabels", "createNote", "createTask", "logCall", "logMeeting", "createProduct", "updateProduct", "getProduct", "searchProducts", "deleteProduct", "addLineItemToDeal", "listDealLineItems", "deleteLineItem", "createQuote", "getQuote", "searchQuotes", "listForms", "getFormSubmissions", "listThreads", "getThreadMessages", "replyToThread", "updateThreadStatus", "listLists", "addToList", "removeFromList", "listOwners", "listPipelines"]; export type HubspotOperation = (typeof HUBSPOT_OPERATIONS)[number]; export declare function isHubspotOperation(value: unknown): value is HubspotOperation; /** * Los objetos del CRM que toca el nodo, con el nombre que usa la API. Son * los de los selectores de propiedades (`GET /crm/properties/…/{objeto}`). */ export declare const HUBSPOT_OBJETOS: readonly ["contacts", "companies", "deals", "tickets", "products", "line_items", "quotes"]; export type HubspotObjeto = (typeof HUBSPOT_OBJETOS)[number]; /** * Los que se enlazan con «Link two records» y «Unlink two records»: los * cuatro del CRM. Productos, partidas y presupuestos se enlazan solos al * crearse (una partida, a su negocio; un presupuesto, a su negocio). */ export declare const HUBSPOT_OBJETOS_ENLAZABLES: readonly ["contacts", "companies", "deals", "tickets"]; export type HubspotObjetoEnlazable = (typeof HUBSPOT_OBJETOS_ENLAZABLES)[number]; /** Los grupos del desplegable, en su orden. */ export declare const HUBSPOT_OPERATION_GROUPS: ReadonlyArray<{ label: string; operations: ReadonlyArray; }>; /** * Las que devuelven una COLECCIÓN sobre la que el nodo de abajo repite. Cada * una itera SU campo (`iterateField` en la spec), con el nombre de lo que * trae (`contacts`, `deals`, `owners`…) y no `results`: ése es el campo de * una tanda (la entrada era una lista) y en una búsqueda dentro de una tanda * habría dos `results` anidados. */ export declare const HUBSPOT_ITERABLE_OPERATIONS: ReadonlyArray; /** * Las que BORRAN. Van a la papelera de HubSpot (90 días) —salvo el borrado * GDPR, que no tiene vuelta atrás—, pero un agente que decide solo no borra * registros del CRM hasta que el dueño lo desbloquea: en el toolkit nacen * bloqueadas. Single operation las corre como las demás. */ export declare const HUBSPOT_OPERACIONES_SENSIBLES: ReadonlyArray; /** Las que no se pueden deshacer: ni papelera ni restaurar. */ export declare const HUBSPOT_OPERACIONES_SIN_VUELTA_ATRAS: ReadonlyArray; export type HubspotParamType = "template" | "textarea" | "json" | "select" | "number" /** Un owner de la cuenta (`GET /crm/owners`). */ | "owner" /** Un pipeline del objeto de la operación (negocios o tickets). */ | "pipeline" /** Una etapa del pipeline elegido en el parámetro `dependsOn`. */ | "stage" /** Una lista de contactos que admite altas a mano (MANUAL o SNAPSHOT). */ | "list" /** Una de las opciones de la propiedad `propiedad` en ESTA cuenta. */ | "enum" /** El nombre de una propiedad del objeto (para filtrar). */ | "property" /** Varios nombres de propiedad, separados por comas (qué devolver). */ | "propertyList" /** Pares propiedad → valor (JSON), con las claves elegidas de la cuenta. */ | "properties" /** * Una etiqueta de asociación entre los objetos de los `select` `fromObject` * y `toObject` de la operación. Se guarda como `CATEGORIA:typeId` * (`USER_DEFINED:36`): el número solo no basta, HubSpot pide las dos cosas. */ | "associationLabel" /** Un producto de la biblioteca de productos de la cuenta. */ | "product" /** Un formulario de la cuenta (su id, un GUID). */ | "form" /** Una bandeja de conversaciones (inbox) de la cuenta. */ | "inbox"; export interface HubspotParamSpec { name: string; label: string; type: HubspotParamType; required?: boolean; description?: string; placeholder?: string; default?: string | number; options?: ReadonlyArray<{ value: string; label: string; }>; min?: number; max?: number; advanced?: boolean; /** La propiedad de HubSpot que rellena este campo al crear o actualizar. */ propiedad?: string; /** `stage`: el parámetro `pipeline` del que salen sus etapas. */ dependsOn?: string; } export interface HubspotOperationSpec { label: string; labelShort?: string; description: string; apiRoute: string; /** El objeto del CRM, para los selectores de propiedades y pipelines. */ objeto: HubspotObjeto | null; params: HubspotParamSpec[]; /** El campo de la salida que se itera; sólo en las iterables. */ iterateField?: string; } /** La versión de la API de HubSpot (por fecha) que usa el nodo. */ export declare const HUBSPOT_API_VERSION = "2026-09"; /** El nombre del campo del id de cada objeto (`contactId`, `lineItemId`…). */ export declare const HUBSPOT_CAMPO_DEL_ID: Readonly>; /** Los operadores que no llevan valor. */ export declare const HUBSPOT_OPERADORES_SIN_VALOR: ReadonlyArray; /** Lo más que se pide por búsqueda (lo más que da HubSpot por página es 200). */ export declare const HUBSPOT_LIMITE_MAXIMO = 100; /** Las propiedades que trae una partida al listarla o copiarla. */ export declare const HUBSPOT_PROPIEDADES_DE_PARTIDA: ReadonlyArray; /** Las propiedades que trae un presupuesto si no se piden otras. */ export declare const HUBSPOT_PROPIEDADES_DE_PRESUPUESTO: ReadonlyArray; export declare const HUBSPOT_OPERATION_SPECS: Record; /** * Los ids de asociación por defecto de HubSpot (`HUBSPOT_DEFINED`) que usa el * nodo al crear con «Link to…» y al colgar notas y tareas. Sacados de la * guía de Associations v4 (2026-09). */ export declare const HUBSPOT_TIPOS_DE_ASOCIACION: Readonly>;