Ferndesk
Widget de autoservicio

Referencia del SDK de Ferndesk

El SDK de Ferndesk es una biblioteca ligera de JavaScript que ofrece control programático sobre el Widget de Autoservicio. Una vez insertado, expone un objeto global Ferndesk en window.Ferndesk que te permite inicializar el widget, abrir artículos, activar búsquedas y gestionar la visibilidad, todo desde el código JavaScript de tu sitio.

Primeros pasos

Instalación

Primero, inserta el script del SDK de Ferndesk en tu HTML (o cópialo desde el panel de Ferndesk):

<!-- Step #1. Install the Ferndesk SDK -->
<script>
    !(function (e, t) {
        var n = 'ferndesk-sdk',
            r = e.FERNDESK_SDK_SRC || 'https://static.ferndesk.com/dist/sdk.js',
            c = 'Ferndesk',
            s = t.currentScript;
        function a() {
            if (!t.getElementById(n)) {
                var e = t.createElement('script');
                ((e.id = n),
                    (e.src = r),
                    (e.async = !0),
                    s && s.nonce && ((e.nonce = s.nonce), e.setAttribute('nonce', s.nonce)));
                var c = t.getElementsByTagName('script')[0];
                c.parentNode.insertBefore(e, c);
            }
        }
        if ('function' != typeof e[c]) {
            var i = [],
                o = function () {
                    i.push(arguments);
                };
            ((o.q = i), (e[c] = o));
        }
        'complete' === t.readyState || 'interactive' === t.readyState
            ? a()
            : t.addEventListener('DOMContentLoaded', a);
    })(window, document);
</script>

Inicialización

Inicializa el widget con tu ID de widget:

<script>
Ferndesk('init', { widgetId: 'YOUR_WIDGET_ID' })
</script>

Una vez inicializado, el widget aparecerá como un botón flotante en tu página y todos los métodos del SDK estarán disponibles.

El parámetro widgetId es obligatorio.

Métodos principales

Init

Inicializa el widget de Ferndesk.

Ferndesk('init', { widgetId: 'YOUR_WIDGET_ID', open: true })

Parámetros:

  • widgetId (cadena, obligatorio): Tu ID de widget desde el panel de Ferndesk.

  • open (booleano, opcional): Si es true, el widget se abre automáticamente al cargar la página. Por defecto: false.

  • hideLauncher (booleano, opcional): Si es true, oculta el botón flotante del widget. El widget permanecerá oculto hasta que llames a open() o toggle(). Por defecto: false.

Devuelve: Nada. Activa la inicialización del widget.

Ejemplo — Botón de ayuda personalizado con lanzador oculto:

<button onclick="Ferndesk('open')">Get Help</button>

<script>
Ferndesk('init', {
  widgetId: 'YOUR_WIDGET_ID',
  hideLauncher: true
});
</script>

Los usuarios hacen clic en tu botón personalizado para abrir el widget. El botón flotante por defecto nunca aparece.

Si configuras hideLauncher como true, asegúrate de proporcionar otra forma para que los usuarios abran el widget (como un botón personalizado). De lo contrario, no podrán acceder a tu centro de ayuda.

Errores de consola:

  • Ferndesk: init requiere un widgetId — falta el parámetro widgetId.

  • Ferndesk widget failed to load widget configuration — El ID del widget no es válido o no se encontró.

Hide

Oculta el botón del widget y desactiva la interacción.

Ferndesk('hide')

Parámetros: Ninguno.

Devuelve: Nada.

Comportamiento: Oculta el botón del widget y cierra cualquier panel abierto. Los usuarios no podrán acceder al widget hasta que se llame a show().

Ejemplo de uso: Ocultar el widget en páginas donde no se necesite ayuda:

if (window.location.pathname === '/checkout') {
  Ferndesk('hide');
}

Show

Muestra el botón del widget y lo vuelve interactivo.

Ferndesk('show')

Parámetros: Ninguno.

Devuelve: Nada.

Comportamiento: Hace que el botón del widget sea visible. Si ya es visible, no ocurre ningún cambio.

Ejemplo de uso: Mostrar el widget después de que un usuario realice una acción determinada:

document.getElementById('help-button').addEventListener('click', () => {
  Ferndesk('show');
});

Open

Abre el panel de ayuda del widget mediante programación.

Ferndesk('open')

Parámetros: Ninguno.

Devuelve: Nada.

Comportamiento: Abre el panel principal del widget sin navegar a un artículo específico. Los usuarios ven la página de inicio del centro de ayuda.

Ejemplo de uso: Abrir la ayuda cuando un usuario hace clic en un botón de "Obtener ayuda":

document.getElementById('get-help').addEventListener('click', () => {
  Ferndesk('open');
});

Close

Cierra el panel del widget que esté abierto.

Ferndesk('close')

Parámetros: Ninguno.

Devuelve: Nada.

Comportamiento: Cierra cualquier panel de widget, barra lateral o modal abierto. El botón del widget sigue siendo visible y clicable.

Destroy

Elimina el widget por completo y libera recursos.

Ferndesk('destroy')

Parámetros: Ninguno.

Devuelve: Nada.

Comportamiento: Elimina el widget de la página, borra los escuchadores de eventos y restablece el estado. Para usar el widget de nuevo, llama a init() con un nuevo ID de widget.

Ejemplo de uso: Limpiar el widget al descargar la página en aplicaciones de una sola página (SPA):

window.addEventListener('beforeunload', () => {
  Ferndesk('destroy');
});

Identify

Autentica e identifica a un usuario con un token JWT.

Ferndesk('identify', { token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...' })

Parámetros:

  • token (cadena, obligatorio): Un token JWT firmado que contiene la información de identidad del usuario.

Devuelve: Nada.

Comportamiento: Autentica al usuario en el widget, permitiendo contenido de ayuda personalizado e identificación segura. El token debe generarse en el servidor y firmarse con tu clave secreta de Ferndesk.

El método identify debe llamarse desde el mismo dominio que tu centro de ayuda o desde un subdominio de primer nivel (por ejemplo, si tu centro de ayuda está en ayuda.ejemplo.com, puedes llamar a identify desde ayuda.ejemplo.com o app.ejemplo.com, pero no desde dominio-diferente.com).

Ejemplo — Identificar usuario conectado:

// After user logs in, get JWT from your backend
const userToken = await fetch('/api/ferndesk-token').then(r => r.text());

Ferndesk('init', { widgetId: 'your-widget-id' });
Ferndesk('identify', { token: userToken });

Llama a identify después de init y antes de abrir el widget. El token debe incluir el ID de usuario, el correo electrónico y cualquier atributo personalizado que desees rastrear.

Errores de consola:

  • Ferndesk: identify requiere un token — falta el parámetro token.

  • Ferndesk: identify failed - invalid token — El token JWT está mal formado o la verificación de la firma falló.

  • Ferndesk: identify must be called from the same domain or 1-level subdomai — Se detectó una discrepancia de dominio.

Para una guía completa sobre la implementación de la identificación silenciosa por JWT, consulta Identificación silenciosa de usuarios mediante JWT.

Prefill

Rellena previamente los campos del formulario de contacto con datos del usuario.

Ferndesk('prefill', { name: 'Jane Doe', email: '[email protected]', subject: 'Billing Issue', message: 'Details here...' })

Parámetros: Objeto con campos de cadena opcionales:

  • name (cadena, opcional): Nombre del usuario

  • email (cadena, opcional): Correo electrónico del usuario

  • subject (cadena, opcional): Línea de asunto del ticket

  • message (cadena, opcional): Cuerpo del mensaje

Devuelve: Nada.

Comportamiento: Rellena automáticamente los campos del formulario de contacto cuando el usuario lo abre. Solo se aplica a campos vacíos; no sobrescribirá la entrada del usuario. Los datos se encolan si se llama antes de la inicialización.

El rellenado previo solo funciona cuando el método de contacto de tu widget está configurado como "formulario" (no "enlace"). Verifica la configuración de tu panel en Widget > Contacto.

Ejemplo — Rellenar previamente desde un usuario conectado:

Ferndesk('init', { widgetId: 'your-widget-id' });
Ferndesk('prefill', {
  name: user.fullName,
  email: user.email
});
Ferndesk('open');

Ejemplo — Informe de errores:

// On crash page
Ferndesk('prefill', {
  subject: 'App Error',
  message: 'Error: ' + error.message
});
Ferndesk('open');

Llama a prefill después de init pero antes de abrir el widget para obtener mejores resultados. Los datos persisten al abrir o cerrar el widget, pero se restablecen tras enviar el formulario.

Advertencias de consola:

  • Ferndesk: 'prefill' se ignoró porque el widget no ha sido inicializado — Llama primero a init().

Métodos de navegación de contenido

OpenArticle

Abre un artículo específico en el widget.

Ferndesk('openArticle', { shortId: 'help-123', presentation: 'widget' })

Parámetros:

  • shortId (cadena, obligatorio): La última parte del artículo.

  • presentation (cadena, opcional): Cómo mostrar el artículo. Opciones: 'widget' (por defecto), 'sidebar', 'modal', 'inline'.

  • anchor (elemento HTML, opcional): Obligatorio para la presentación 'inline'. El elemento cerca del cual se anclará el artículo.

Devuelve: Nada.

Modos de presentación:

  • widget (por defecto): El artículo se abre dentro del widget de ayuda principal.

  • sidebar: El artículo se desliza desde el borde derecho como un panel lateral.

  • modal: El artículo se abre en una superposición centrada a pantalla completa.

  • inline: El artículo se expande cerca del elemento de anclaje (requiere el parámetro anchor).

Ejemplo — Abrir artículo en modal al hacer clic en un botón:

document.getElementById('faq-button').addEventListener('click', () => {
  Ferndesk('openArticle', { shortId: 'faq-pricing', presentation: 'modal' });
});

Ejemplo — Abrir artículo inline junto a un elemento:

const anchorElement = document.getElementById('billing-info');
Ferndesk('openArticle', {
  shortId: 'billing-faq',
  presentation: 'inline',
  anchor: anchorElement
});

Errores de consola:

  • Ferndesk: openArticle requiere un shortId — falta el shortId.

  • Ferndesk: El artículo flotante inline requiere un elemento de anclaje — se usó presentation: 'inline' pero no se proporcionó anclaje.

  • Ferndesk: openArticle se ignoró porque el widget no ha sido inicializado — aún no se ha llamado a init().

OpenCollection

Abre una colección específica en el widget.

Ferndesk('openCollection', { shortId: 'getting-started' })

Parámetros:

  • shortId (cadena, obligatorio): El ID corto de la colección desde tu centro de ayuda.

Devuelve: Nada.

Comportamiento: Abre la colección dentro del panel de ayuda del widget, mostrando todos los artículos de esa colección.

Ejemplo — Explorar artículos de resolución de problemas:

Ferndesk('openCollection', { shortId: 'xFqsqw' });

Rellena la búsqueda del widget y muestra los resultados.

Ferndesk('search', { query: 'billing issues' })

Parámetros:

  • query (cadena, obligatorio): La consulta de búsqueda. No debe estar vacía.

Devuelve: Nada.

Comportamiento: Abre el widget y muestra los resultados de búsqueda que coincidan con la consulta. Si no hay coincidencias, muestra "No se encontraron resultados".

Ejemplo — Buscar cuando el usuario presiona una combinación de teclas:

document.addEventListener('keydown', (e) => {
  if (e.key === '?' && e.ctrlKey) {
    Ferndesk('search', { query: 'download videos' });
  }
});

Errores de consola:

  • Ferndesk: la búsqueda requiere una consulta no vacía — el parámetro query está vacío o falta.

Atributos de datos para activadores inline

Además de los métodos del SDK, puedes usar atributos de datos HTML para activar acciones del widget sin JavaScript:

data-ferndesk-article

Abre un artículo en modo widget al hacer clic.

<button data-ferndesk-article="help-123">Learn More</button>

Al hacer clic en este botón, se abre el artículo con ID "help-123" en el panel principal del widget.

data-ferndesk-article-modal

Abre un artículo en modo modal al hacer clic.

<a href="#" data-ferndesk-article-modal="pricing-faq">View Pricing FAQs</a>

Al hacer clic en este enlace, el artículo se abre en una superposición modal centrada.

data-ferndesk-article-sidebar

Abre un artículo en modo de barra lateral al hacer clic.

<button data-ferndesk-article-sidebar="troubleshooting">Troubleshoot</button>

Al hacer clic, se abre el artículo en una barra lateral deslizante.

data-ferndesk-article-inline

Abre un artículo en modo inline anclado al elemento clicado.

<button id="my-button" data-ferndesk-article-inline="quick-help">Quick Help</button>

Al hacer clic en este botón, se abre el artículo de forma inline cerca del botón. Si no se encuentra un anclaje, la consola del navegador avisará y volverá al modo modal.

Gestión de errores y registros

El SDK registra errores y advertencias en la consola del navegador (no visibles para los usuarios finales). Los mensajes comunes incluyen:

Mensaje

Causa

Solución

Ferndesk: init requiere un widgetId

Falta el parámetro widgetId

Proporciona tu ID de widget en la llamada init

Ferndesk widget failed to load widget configuration

ID de widget inválido o caducado

Verifica el ID en el panel; vuelve a generarlo si es necesario

Ferndesk service not found

El script del SDK no se cargó (bloqueado por ad blocker, CSP, etc.)

Revisa las peticiones de red; añade el dominio de Ferndesk a la lista blanca en la CSP

Ferndesk: search requiere una consulta no vacía

Consulta de búsqueda vacía o inexistente

Proporciona una cadena no vacía para el parámetro query

Ferndesk: El artículo flotante inline requiere un elemento de anclaje

Uso de la presentación inline sin anclaje

Proporciona un elemento HTML en el parámetro anchor

Ferndesk: 'method' se ignoró porque el widget no ha sido inicializado

Se llamó a un método antes de que finalizara init()

Asegúrate de llamar a init() antes que a otros métodos (o espera a que el SDK cargue)

Ferndesk: unknown command 'method'

Se llamó a un método inexistente

Comprueba el nombre del método y su ortografía en la referencia del SDK

Cumplimiento de la Política de Seguridad de Contenido (CSP)

Si tu sitio utiliza una Política de Seguridad de Contenido estricta, es posible que debas autorizar el dominio de Ferndesk:

Ejemplo de encabezado CSP:

script-src 'self' https://static.ferndesk.com;

Si la CSP bloquea el script del SDK, la consola registrará un error de violación de la CSP. Añade https://static.ferndesk.com a tu directiva script-src para permitirlo.

Consideraciones de rendimiento

El SDK utiliza carga asíncrona para evitar bloquear el renderizado de la página. El tiempo de carga típico es de 200 a 500 ms en una conexión estándar.

  • Carga asíncrona: El script del SDK se carga de forma asíncrona en segundo plano. Tu página continúa cargándose mientras el SDK se inicializa.

  • Aislamiento mediante Shadow DOM: El widget utiliza Shadow DOM para encapsular los estilos y evitar conflictos con el CSS de tu sitio.

  • Carga de contenido perezosa (Lazy loading): Los artículos y los resultados de búsqueda se cargan bajo demanda, no todos a la vez.

  • Sin impacto en el rendimiento: El SDK añade una sobrecarga mínima, normalmente menos de 50 KB de JavaScript.

Ejemplos

Configuración básica

<html>
  <body>
    <!-- Your page content -->
    
    <script src="https://static.ferndesk.com/dist/sdk.js"></script>
    <script>
      Ferndesk('init', { widgetId: 'your-widget-id' });
    </script>
  </body>
</html>

Abrir artículo al hacer clic en un botón

<button id="help-btn">Get Help</button>

<script>
Ferndesk('init', { widgetId: 'your-widget-id' });

document.getElementById('help-btn').addEventListener('click', () => {
  Ferndesk('openArticle', {
    shortId: 'faq-overview',
    presentation: 'modal'
  });
});
</script>

Buscar según la entrada del usuario

<input id="search-input" type="text" placeholder="Search help..."/>

<script>
Ferndesk('init', { widgetId: 'your-widget-id' });

document.getElementById('search-input').addEventListener('keypress', (e) => {
  if (e.key === 'Enter') {
    Ferndesk('search', { query: e.target.value });
  }
});
</script>

Ayuda contextual en una aplicación React

import { useEffect, useState } from 'react';

export default function App() {
  const [currentPage, setCurrentPage] = useState('home');

  useEffect(() => {
    // Initialize SDK
    const script = document.createElement('script');
    script.src = 'https://static.ferndesk.com/dist/sdk.js';
    script.async = true;
    document.body.appendChild(script);

    script.onload = () => {
      window.Ferndesk('init', { widgetId: 'your-widget-id' });
    };
  }, []);

  useEffect(() => {
    // Hide widget on checkout page, show elsewhere
    if (currentPage === 'checkout') {
      window.Ferndesk('hide');
    } else {
      window.Ferndesk('show');
    }
  }, [currentPage]);

  return (
    <div>
      {/* Your page content */}
    </div>
  );
}

Siguientes pasos

¿Te fue util?