Extension Settings
Los extension settings son la configuración global de tu aplicación dentro de Socialdesk. Se definen en la sección Configuración Avanzada de tu app como un objeto JSON.
Sirven para almacenar información que tu aplicación necesita para funcionar, como URLs de webhook, API keys, o cualquier configuración personalizada por instancia.
¿Cómo se configuran?
Desde la pantalla de configuración de tu aplicación en Socialdesk, encontrarás dos secciones:
- Respuestas Automáticas: checkbox para permitir que tu app envíe mensajes directos al participante.
- Configuración Avanzada: editor JSON donde defines los settings de tu app.

Ejemplo de configuración
{
"webhook": "https://tu-dominio.com/webhook",
"mi_api_key": "sk-example-123",
"shortcuts": [
{
"id": "CB_RESET_COUNTER",
"type": "CALLBACK",
"label": "Reiniciar contador",
"value": {}
}
]
}
¿Cómo se reciben?
Los extension settings se incluyen en todos los eventos webhook que recibe tu aplicación, dentro del campo extension_settings:
{
"type": "DIRECT_MESSAGE",
"payload": { ... },
"extension_settings": {
"webhook": "https://tu-dominio.com/webhook",
"mi_api_key": "sk-example-123",
"shortcuts": [...]
},
"access_token": "eyJhbGciOiJIUzI1NiIs...",
...
}
¿Cómo se acceden desde el código?
const extensionSettings = req.body.extension_settings;
const webhookUrl = extensionSettings.webhook;
const apiKey = extensionSettings.mycustomsetting;
Casos de uso
- API keys: claves de servicios externos (CRM, pasarelas de pago, etc.)
- URLs de webhook: la URL donde Socialdesk enviará los eventos
- IDs de equipos y etiquetas: para no hardcodear valores en el código
- Configuración por instancia: cada instalación de tu app puede tener valores distintos
Shortcuts
Los shortcuts (accesos directos) son botones que se muestran al agente en la barra de escritura de la conversación. Permiten al agente ejecutar manualmente un callback de tu aplicación sin necesidad de que un hint message esté presente.

¿Cómo se configuran?
Los shortcuts se definen dentro del JSON de Configuración Avanzada de tu app, en el campo shortcuts:
{
"shortcuts": [
{
"id": "CB_SEND_QUOTE",
"type": "CALLBACK",
"label": "Enviar mensaje de cotización",
"value": {}
},
{
"id": "CB_RESET_COUNTER",
"type": "CALLBACK",
"label": "Reiniciar contador",
"value": {}
}
]
}
Campos
| Campo | Tipo | Descripción |
|---|---|---|
id | string | Identificador único del shortcut. Debe coincidir con un callback ID de tu app |
type | string | Tipo de shortcut: "CALLBACK" o "PROMPT_CALLBACK" |
label | string | Texto visible para el agente en el panel de accesos directos |
value | any | Valor que se envía cuando el agente ejecuta el shortcut. Para PROMPT_CALLBACK, contiene promptInputs |
¿Cómo funciona?
Cuando un agente selecciona un shortcut desde el panel de accesos directos, tu aplicación recibe un evento REPLY_MESSAGE_CALLBACK. En ambos tipos, payload.id contiene el id del shortcut tal como lo configuraste:
| Tipo | payload.id | payload.value |
|---|---|---|
CALLBACK | El id del shortcut (ej: "CB_RESET_COUNTER") | El value configurado en el shortcut |
PROMPT_CALLBACK | El id del shortcut (ej: "CB_SEND_QUOTE") | Objeto con los datos del formulario + agentName y agentId |
// Callback normal
if (payload.id === 'CB_RESET_COUNTER') { ... }
// Prompt callback — el value contiene los datos del formulario
if (payload.id === 'CB_SEND_QUOTE') {
const { plan, descuento, nota, agentName } = payload.value;
}
Prompt Callbacks
Los prompt callbacks son shortcuts de tipo PROMPT_CALLBACK que, al ser seleccionados por el agente desde el panel de Accesos Directos, abren un formulario modal para recopilar datos adicionales antes de enviar el callback a tu aplicación.
A diferencia de un shortcut CALLBACK normal (que envía un valor fijo al hacer clic), un prompt callback le pide al agente que complete campos y envía esos datos junto con el callback.
Los prompt callbacks solo funcionan como shortcuts en el panel de Accesos Directos. No se pueden enviar como callbacks dentro de un hint message — los hint messages solo soportan callbacks simples de tipo CALLBACK.


Estructura
{
"id": "CB_SET_COUNTER",
"type": "PROMPT_CALLBACK",
"label": "Establecer número de intentos",
"value": {
"promptInputs": [
{
"name": "counter",
"label": "¿Cuantos intentos?",
"type": "text",
"placeholder": "",
"defaultValue": "",
"required": true
},
{
"name": "description",
"label": "Descripción",
"type": "textarea",
"placeholder": "Describe el motivo...",
"defaultValue": "",
"required": true
}
]
}
}
Campos del prompt input
Cada objeto en promptInputs tiene las siguientes propiedades:
| Propiedad | Tipo | Requerido | Descripción |
|---|---|---|---|
name | string | Sí | Identificador del campo. Se usa como key en el objeto de datos enviado al callback |
label | string | Sí | Etiqueta visible del campo en el formulario |
type | string | Sí | Tipo de campo. Ver tipos soportados |
placeholder | string | No | Texto placeholder del campo |
defaultValue | string | No | Valor por defecto del campo |
options | array | No | Opciones para campos de tipo select y checkbox |
required | boolean | No | Si es true, el campo es obligatorio |
Tipos de campo soportados
text
Campo de texto de una línea. Es el tipo por defecto.
{
"name": "nombre",
"label": "Nombre del cliente",
"type": "text",
"placeholder": "Ej: Juan Pérez",
"defaultValue": "",
"required": true
}
textarea
Campo de texto multilínea, ideal para descripciones o notas.
{
"name": "notas",
"label": "Notas adicionales",
"type": "textarea",
"placeholder": "Escribe aquí...",
"defaultValue": "",
"required": false
}
date
Selector de fecha con calendario (datepicker).
El defaultValue acepta:
"today"— establece la fecha actual como valor por defecto- Una fecha específica (ej:
"2025-03-15") — se convierte automáticamente ""— sin valor por defecto
{
"name": "fecha_seguimiento",
"label": "Fecha de seguimiento",
"type": "date",
"defaultValue": "today",
"required": true
}
select
Lista desplegable con opciones predefinidas. Requiere el campo options con un array de objetos { label, value }.
{
"name": "prioridad",
"label": "Nivel de prioridad",
"type": "select",
"required": true,
"options": [
{ "label": "Baja", "value": "low" },
{ "label": "Media", "value": "medium" },
{ "label": "Alta", "value": "high" }
]
}
checkbox
Grupo de casillas de verificación. Requiere options con un array de objetos { label, value, checked }.
Cada opción genera un campo independiente en los datos del formulario con el nombre {value}_checked y un valor true o false.
{
"name": "categorias",
"label": "Categorías aplicables",
"type": "checkbox",
"options": [
{ "label": "Ventas", "value": "ventas", "checked": false },
{ "label": "Soporte", "value": "soporte", "checked": true },
{ "label": "Facturación", "value": "facturacion", "checked": false }
]
}
Otros tipos HTML
Cualquier tipo de input HTML válido (number, email, tel, etc.) también es soportado. Se renderiza como un campo de texto con la validación nativa del navegador.
{
"name": "email",
"label": "Correo electrónico",
"type": "email",
"placeholder": "usuario@ejemplo.com",
"required": true
}
Flujo
1. El administrador configura un shortcut de tipo PROMPT_CALLBACK
con los campos deseados en promptInputs.
2. El agente ve el botón en el panel de "Accesos Directos".
3. El agente hace clic → se abre el formulario modal.
4. El agente completa los campos y hace clic en "Enviar".
5. Socialdesk emite un evento REPLY_MESSAGE_CALLBACK a tu webhook con:
→ id: el ID del shortcut (ej: "CB_SEND_QUOTE")
→ value: { ...datosDelFormulario, agentName, agentId }
6. Tu app procesa los datos y responde.
Recibiendo los datos
Cuando el agente completa el formulario y hace clic en "Enviar", tu aplicación recibe un evento REPLY_MESSAGE_CALLBACK. El value del payload contiene todos los campos del formulario, más agentName y agentId del agente que lo completó.
if (eventType === 'REPLY_MESSAGE_CALLBACK') {
const payload = webhook.getPayload();
// payload.id contiene el ID del shortcut directamente
if (payload.id === 'CB_ADD_NOTE') {
// Los datos del formulario vienen en payload.value
const { categoria, nota, agentName, agentId } = payload.value;
// categoria: "followup"
// nota: "Cliente pidió llamada de seguimiento"
// agentName: "Ana López"
// agentId: "agent_abc123"
}
}
Estructura del value por tipo de campo
| Tipo de campo | Clave en value | Valor |
|---|---|---|
text, textarea, email, etc. | name del campo | string con el texto ingresado |
date | name del campo | string en formato ISO (ej: "2025-03-15T00:00:00.000Z") |
select | name del campo | string con el value de la opción seleccionada |
checkbox | {optionValue}_checked | boolean (true o false) por cada opción |
| — | agentName | string — nombre del agente que completó el formulario |
| — | agentId | string — ID del agente que completó el formulario |
Ejemplo
Prompt callback que le permite al agente registrar una nota interna con categoría:
Configuración
{
"id": "CB_ADD_NOTE",
"type": "PROMPT_CALLBACK",
"label": "Agregar nota interna",
"value": {
"promptInputs": [
{
"name": "categoria",
"label": "Categoría",
"type": "select",
"required": true,
"options": [
{ "label": "Seguimiento", "value": "followup" },
{ "label": "Escalación", "value": "escalation" },
{ "label": "Información", "value": "info" }
]
},
{
"name": "nota",
"label": "Nota",
"type": "textarea",
"placeholder": "Escribe la nota...",
"required": true
}
]
}
}
Handler
if (eventType === 'REPLY_MESSAGE_CALLBACK') {
const payload = webhook.getPayload();
if (payload.id === 'CB_ADD_NOTE') {
const { categoria, nota, agentName } = payload.value;
// Guardar la nota en tu sistema o en el application_context
await client.sendHintMessage({
text: `Nota registrada por ${agentName} [${categoria}]: ${nota}`,
message_id: payload.message.id,
conversation_id: webhook.getConversationId(),
});
}
}