Ir al contenido

Salesforce - Upsert registro

↩ Parte de la integración Salesforce.

Crea o actualiza un registro identificado por un campo de id externo (PATCH /sobjects/{sobject}/{extField}/{extValue}).

Salesforce decide por vos: si ya existe un registro con ese valor externo lo actualiza, y si no lo crea. Es el nodo que usás cuando sincronizás desde otro sistema —un ERP, una tienda, una base de datos— y tenés la clave de ese sistema, no el id de Salesforce.

Como la misma llamada se puede repetir sin riesgo, el upsert es además la manera de hacer un flujo idempotente: ejecutarlo dos veces no crea dos registros.

CampoTipoObligatorioDescripción
credentials_idcredentialsSíCredencial de Salesforce
sobjecttextSíNombre de API del objeto: Account, Contact, Lead…
external_id_fieldtextSíCampo de id externo, ej. ExternalId__c
external_id_valuetextSíValor del id externo con el que se busca la coincidencia
fieldsjsonSíCampos del registro

Todos los parámetros aceptan variables dinámicas; el texto de fields se resuelve antes de parsearse como JSON.

Este módulo necesita una credencial de Salesforce:

CampoDescripción
login_urlhttps://login.salesforce.com o https://test.salesforce.com para una sandbox
client_id / client_secretConsumer Key y Secret de la Connected App
usernameUsuario de Salesforce
passwordContraseña más el security token, concatenados

Cuando Salesforce crea el registro responde 201 con cuerpo, y data queda así:

{
"id": "0015g00000AbCdEFGH",
"success": true,
"created": true
}

Cuando actualiza uno existente responde 204 sin cuerpo, así que el nodo arma la confirmación:

{
"external_id": "ERP-10045",
"upserted": true,
"created": false
}

Junto con él, _meta:

{ "moduleVersion": "1.0.0", "success": true, "id": "0015g00000AbCdEFGH", "created": true, "totalMs": 410 }

Ramificá según created para distinguir un alta de una actualización. Ojo: en el camino de actualización no hay id en la salida; si lo necesitás, leé el registro con Leer registro o una consulta SOQL.

{
"credentials_id": "salesforce_prod",
"sobject": "Account",
"external_id_field": "ERP_Code__c",
"external_id_value": "{{data.codigoErp}}",
"fields": {
"Name": "{{data.nombre}}",
"Phone": "{{data.telefono}}",
"BillingCity": "{{data.ciudad}}"
}
}
{
"credentials_id": "salesforce_prod",
"sobject": "Contact",
"external_id_field": "External_Email__c",
"external_id_value": "{{data.email}}",
"fields": {
"FirstName": "{{data.nombre}}",
"LastName": "{{data.apellido}}",
"Email": "{{data.email}}"
}
}
{
"credentials_id": "salesforce_prod",
"sobject": "Suscripcion__c",
"external_id_field": "Shop_Order_Id__c",
"external_id_value": "{{data.orderId}}",
"fields": {
"Estado__c": "Activa",
"Importe__c": "{{data.total}}"
}
}
  • El campo que nombrás en external_id_field tiene que estar marcado como External ID en Salesforce (Setup → Object Manager → Fields → External ID). Un campo normal devuelve 400 NOT_FOUND o INVALID_FIELD.
  • Marcalo también como Unique. Si varios registros comparten el valor, Salesforce responde 300 Multiple Choices y el upsert falla.
  • No repitas el id externo dentro de fields: ya viaja en la URL.
  • El campo estándar Email de un Contact no es un id externo. Para identificar por email necesitás un campo External ID personalizado, como en el segundo ejemplo.
  • Se aplican el resto de las reglas de una actualización: se disparan las reglas de validación, se rechazan los campos de solo lectura y esos errores 400 no se reintentan.