Ir al contenido
Consola

Feedback (CSAT)

Una micro-encuesta de tres tipos (emoji3, scale7, thumbs), una vez por visitante por ventana de cadencia. Viene apagada y ver resultados es Pro.

Feedback es una micro-encuesta que Espejo les muestra a tus usuarios finales. Un toque, un voto, y cae en el dashboard de Satisfaction. Es la forma más barata de preguntar “¿qué tal estuvo?” sin construir tu propia herramienta de encuestas.

Espejo trae dos cosas distintas, y van a dos lugares distintos:

  • La encuesta CSAT — la preguntita de acá abajo — es un voto. Va a Satisfaction.
  • El botón “Reportar un problema” (🐞) es una grabación. Va a Recordings.

Una mide cómo se siente la gente; el otro captura qué salió mal. Se activan y se leen por separado.

TipoSe ve comoSirve para
emoji3tres caritas 🙁 😐 🙂una lectura rápida de humor
scale7una escala 1–7un puntaje más fino, estilo NPS
thumbs👍 / 👎un sí/no directo

Elegís uno por proyecto. Cada voto va a la misma vista de Satisfaction.

La encuesta viene apagada por defecto en todos los proyectos. Se activa en la consola:

  1. Abrí Project Settings → Feedback.
  2. Elegí el tipo — emoji3, scale7 o thumbs.
  3. Fijá cadence_days — cuánto pasa antes de volver a preguntarle al mismo visitante.

Nada cambia en tu página; el SDK lee la config del proyecto. Un visitante ve la encuesta una vez por ventana de cadencia, y el sello de “visto” se escribe cuando aparece — no cuando responde — así que alguien que la descarta no vuelve a ser molestado hasta que la ventana da la vuelta.

La config del proyecto es el default. Para suprimir la encuesta en una página o build puntual, poné el atributo en el script:

<script src="https://app.espejo.dev/sdk/espejo.js"
data-key="pk_live_..."
data-feedback="off"></script>

Cuando la encuesta tiene que seguir tu diseño, o aparecer en el momento que tú elijas, puedes dibujarla tú y mandar los votos con el SDK. Llegan al mismo dashboard de Satisfaction que los del widget. La encuesta igual tiene que estar activada en Project Settings → Feedback: ahí el proyecto elige su tipo, y un proyecto con la encuesta apagada rechaza los votos.

Para que tus visitantes no vean dos encuestas, apaga la nuestra en las páginas que muestran la tuya. Con npm, pasa feedback: "off" al constructor:

import { Espejo } from "@espejo/browser";
const espejo = new Espejo({ key: "pk_live_...", feedback: "off" });
espejo.start();

Con el script, agrega data-feedback="off", como en Cómo apagarla desde la página. En los dos casos solo desaparece el widget: getFeedbackConfig() y vote() siguen funcionando.

getFeedbackConfig(): Promise<FeedbackConfig | null>
interface FeedbackConfig {
enabled: boolean; // siempre true cuando la config no es null
kind: "emoji3" | "scale7" | "thumbs";
cadence_days: number; // de 1 a 365
}

Devuelve la config de la encuesta del proyecto, o null si está apagada. También devuelve null si la config no se pudo cargar (sin red, un error de la API o sin respuesta en 2 segundos). Nunca lanza un error. Úsala para decidir si muestras tu formulario y qué pregunta dibujas. El navegador puede guardar la respuesta en caché hasta 5 minutos, así que un cambio en la consola puede tardar eso en llegar a una página abierta.

FeedbackConfig y FeedbackKind se exportan como tipos desde @espejo/browser.

vote(value: number, options?: { kind?: FeedbackKind }): Promise<void>

Manda un voto y se resuelve cuando la API lo acepta. value es la respuesta cruda, un entero dentro del rango de su tipo:

Tipovalue
emoji30 (triste), 1 (neutral) o 2 (contento)
scale7de 1 a 7
thumbs0 (pulgar abajo) o 1 (pulgar arriba)

options.kind toma por defecto el tipo del proyecto. vote() también manda el host de la página actual y tu userRef (del constructor, de data-user-ref o de identify()), igual que el widget.

Se rechaza con un Error en estos casos:

CasoEl mensaje empieza con
La encuesta está apagada, o su config no se pudo cargar.Espejo: feedback is off
value no es un entero dentro del rango del tipo. No se manda nada.Espejo: invalid <kind> vote
La API contestó con un status fuera de 2xx.ingest rejected the vote: HTTP <status>, seguido del comienzo del cuerpo de la respuesta

Si falla la red, se rechaza con el error del propio navegador.

vote() no aplica cadence_days ni recuerda quién ya respondió. Cuándo preguntar, y cada cuánto, lo decide tu código. La config te da el cadence_days del proyecto por si quieres seguirlo.

Tres botones de emoji que aparecen solo si la encuesta está activada, y como mucho una vez cada cadence_days por navegador.

<div id="csat" hidden>
<p>¿Qué tal tu experiencia?</p>
<button data-value="0">🙁</button>
<button data-value="1">😐</button>
<button data-value="2">🙂</button>
</div>
import { Espejo } from "@espejo/browser";
const espejo = new Espejo({ key: "pk_live_...", feedback: "off" });
espejo.start();
const LAST_ASKED = "my-app:csat-asked-at";
const DAY_MS = 24 * 60 * 60 * 1000;
async function maybeAsk() {
const config = await espejo.getFeedbackConfig();
if (!config || config.kind !== "emoji3") return;
const last = Number(localStorage.getItem(LAST_ASKED) ?? 0);
if (Date.now() - last < config.cadence_days * DAY_MS) return;
localStorage.setItem(LAST_ASKED, String(Date.now()));
const box = document.getElementById("csat")!;
box.hidden = false;
box.querySelectorAll<HTMLButtonElement>("button").forEach((button) => {
button.addEventListener("click", async () => {
box.hidden = true;
try {
await espejo.vote(Number(button.dataset.value));
} catch (error) {
console.warn("No se guardó el voto", error);
}
});
});
}
maybeAsk();

Con el script, la misma instancia es window.espejo, con los mismos getFeedbackConfig() y vote():

<script src="https://app.espejo.dev/sdk/espejo.js"
data-key="pk_live_..."
data-feedback="off"></script>
<script>
window.espejo.getFeedbackConfig().then((config) => {
if (!config) return;
// Muestra tu formulario y, al hacer clic:
// window.espejo.vote(2).catch((error) => console.warn(error));
});
</script>

window.espejo existe una vez que espejo.js se ejecutó. Cárgalo sin async ni defer si un script inline justo después lo usa, o espera al evento load.

Para un formulario que no usa el SDK. Llámalo desde el navegador del visitante.

Config: GET https://app.espejo.dev/v1/ingest/feedback-config?key=pk_live_... siempre contesta 200 con { "success": true, "data": { "enabled", "kind", "cadence_days" } }. Una clave desconocida o revocada, una cuenta desactivada y una encuesta apagada devuelven enabled: false.

Voto: POST https://app.espejo.dev/v1/ingest/feedback

  • Cabeceras: x-espejo-key: pk_live_... y content-type: application/json. El navegador manda Origin, y tiene que ser uno de los orígenes permitidos del proyecto (un proyecto sin orígenes permitidos acepta cualquiera). Mándalo sin cookies (credentials: "omit").
  • Cuerpo: { "kind": "emoji3", "value": 2, "page_host": "app.example.com", "user_ref": "user-123" }. kind y value son obligatorios, con los rangos de arriba. page_host (hasta 255 caracteres) y user_ref (hasta 400) son strings opcionales. El cuerpo puede pesar hasta 16 KB.
  • Respuesta: 200 con { "success": true, "data": { "vote_id": "<32 caracteres hex>" } }.
StatusMensajeCausa
400`kind` must be one of: emoji3, scale7, thumbs.Falta kind o no es uno de los tres.
400`value` is out of range for this feedback kind.value no es un entero dentro del rango de kind.
403Missing x-espejo-key header. o Invalid ingest key.Sin clave, o una desconocida o revocada.
403This account is deactivated. Recording is off.La cuenta está desactivada.
403Origin <origin> is not allowed for this project.El Origin no está en la lista de permitidos.
403Feedback is disabled for this project.La encuesta está apagada en Project Settings → Feedback.
403This project hit its daily feedback vote cap. It resets at midnight UTC.El proyecto llegó a 50.000 votos hoy.
503Ingest is unavailable: the database is not configured.El servicio no está disponible.
  • Un voto es un número. No hay comentario de texto libre: la API no tiene un campo para eso.
  • Hasta 50.000 votos por proyecto por día. El conteo se reinicia a la medianoche UTC.
  • Uno de los tres tipos por proyecto, elegido en la consola.