Typeform
Typeform es una herramienta fácil de usar para recopilar datos, opiniones y mucho más.
Al integrar Braze y Typeform, puedes:
- Actualizar los perfiles de usuario en Braze con los datos recopilados de su respuesta a Typeform
- Desencadenar mensajería en Braze en función de la interacción de un usuario con un typeform
- Personalizar la mensajería de Braze en función de las respuestas de un usuario a Typeform
Requisitos previos
| Requisito | Descripción |
|---|---|
| Cuenta de Typeform | Se requiere una cuenta de Typeform con acceso a webhooks para aprovechar esta integración. |
| Transformación de datos de Braze | Es necesaria una URL de transformación de datos para recibir datos de Typeform. |
Integración
Paso 1: Configura la transformación de datos de Braze para aceptar los webhooks de Typeform
En el panel de Braze, ve a Configuración de datos > Transformación de datos.
Selecciona Crear transformación para darle un nombre a tu transformación y, a continuación, elige tu experiencia de edición.

Selecciona Utilizar una plantilla para examinar una biblioteca de plantillas, incluidos los ejemplos de transformación de datos. O bien, selecciona Empezar de cero para cargar una plantilla de código predeterminada.
Si empiezas de cero, elige un destino para tu transformación. Todavía puedes insertar una plantilla de código de la biblioteca de plantillas.
Más sobre destinos
- POST: Track users: Transforma los webhooks de una plataforma de origen en actualizaciones del perfil de usuario, como atributos, eventos o compras.
- PUT: Update multiple catalog items: Transforma los webhooks de una plataforma de origen en actualizaciones de elementos del catálogo.
- DELETE: Delete multiple catalog items: Transforma los webhooks de una plataforma de origen en eliminaciones de elementos del catálogo.
- PATCH: Edit multiple catalog items: Transforma los webhooks de una plataforma de origen en ediciones de elementos del catálogo.
- POST: Send messages immediately via API Only: Transforma los webhooks de una plataforma de origen para enviar mensajes inmediatos a usuarios designados.

Después de crear tu transformación, verás la vista detallada de la transformación. Aquí puedes ver el webhook más reciente recibido para esta transformación en Webhook details y un espacio para escribir tu código de transformación en Transformation code.

Copia tu URL del webhook para utilizarla en el siguiente paso.
Paso 2: Configura los webhooks de Typeform
Sigue los pasos de la documentación de webhooks de Typeform para configurar un webhook.
En el paso 4, añade la URL del webhook de tu transformación de datos como la URL de destino.

Envía un evento de prueba a tu transformación de datos haciendo clic en View deliveries y luego en Send test request.

Paso 3: Escribe el código de transformación para aceptar los eventos de Typeform que elijas
En este paso, transformas la carga útil del webhook que se envía desde Typeform en un valor de retorno de objeto JavaScript.
- Actualiza tu transformación de datos y asegúrate de que puedes ver la carga útil de prueba de Typeform en los Detalles del webhook.
- Actualiza el código de tu transformación de datos para que sea compatible con los eventos de Typeform que hayas elegido.
- Haz clic en Validate para obtener una vista previa de la salida de tu código y comprobar si es una solicitud
/users/trackaceptable. - Guarda y activa tu transformación de datos.

Formato del cuerpo de la solicitud
Este valor de retorno debe cumplir con el formato del cuerpo de la solicitud /users/track de Braze:
- El código de transformación se acepta en el lenguaje de programación JavaScript. Se admite cualquier flujo de control estándar de JavaScript, como la lógica if/else.
- El código de transformación accede al cuerpo de la solicitud del webhook a través de la variable
payload. Esta variable es un objeto que se completa al analizar el JSON del cuerpo de la solicitud. - Se admite cualquier característica compatible con nuestro endpoint
/users/track, incluyendo:- Objetos de atributos de usuario, objetos de eventos y objetos de compra
- Atributos anidados y propiedades de eventos personalizados anidadas
- Actualizaciones de grupos de suscripción
- Dirección de correo electrónico como identificador
Ejemplo de carga útil de webhook de Typeform
Content-Type: application/json
{
"event_id": "01HC3PTZN05GJWT0QDXXB2QV8F",
"event_type": "form_response",
"form_response": {
"form_id": "uaIA4a7Y",
"token": "7pctqdoqxg41to97pctqdibhqn6hqvto",
"landed_at": "2023-10-06T23:57:52Z",
"submitted_at": "2023-10-06T23:58:18Z",
"hidden": {
"user_id": "hidden_value"
},
"definition": {
"id": "uaIA4a7Y",
"title": "Project Feedback Survey",
"fields": [
{
"id": "G0IbXtfvsfjV",
"ref": "814b9fc2-e6d2-4672-accf-22f754b84f20",
"type": "email",
"title": "Please provide your email",
"properties": {}
},
{
"id": "lg82q3t0rK03",
"ref": "e1503b62-0241-4269-9902-5c539abf305e",
"type": "short_text",
"title": "What was your role in the project?",
"properties": {}
},
{
"id": "UXftY0tSmuDV",
"ref": "5b839dbb-566b-47de-a47e-b0914d9ccf7c",
"type": "opinion_scale",
"title": "How would you rate the overall performance of the team?",
"properties": {}
},
{
"id": "fE17bXVUEB4E",
"ref": "fd6be99d-1ed1-4a4d-b811-f6ecdd8fa9b6",
"type": "yes_no",
"title": "Did the project meet its intended outcomes?",
"properties": {}
},
{
"id": "NmVOQFuI0vv9",
"ref": "cd2b4176-db9a-49bb-a918-4463720bbc79",
"type": "multiple_choice",
"title": "Which area of the project do you think went well?",
"properties": {},
"choices": [
{
"id": "RvV3LaMEQ2eK",
"ref": "2d5e0913-afe9-491c-b31c-0648dd397d56",
"label": "Communication"
},
{
"id": "7iXmfpPMeQvz",
"ref": "7a7749d2-5cd6-4bf7-9726-65c7ab11ec83",
"label": "Planning"
},
{
"id": "1No85DZlvP6f",
"ref": "d7b7304a-776b-4630-8bee-7dc7ef9c9404",
"label": "Execution"
},
{
"id": "ruMnsZWjyalW",
"ref": "41dc926a-85af-4625-8a61-725fda35afda",
"label": "Problem Solving"
},
{
"id": "CexnFN3roprG",
"ref": "cfdd2da4-8c57-4ff1-b4c0-1a5262e2ff84",
"label": "Other"
}
]
},
{
"id": "ZJop9pvoObzk",
"ref": "ce903cda-7e27-4b4c-9fa8-0623c47c61b4",
"type": "multiple_choice",
"title": "Which area of the project do you think could be improved?",
"properties": {},
"choices": [
{
"id": "YQLArFf0Wks5",
"ref": "09fa30c7-7bdc-4753-971e-0d922638d023",
"label": "Communication"
},
{
"id": "iGjaELgfnChw",
"ref": "61820c89-3426-464d-b031-c06de5125fd5",
"label": "Planning"
},
{
"id": "2EyI5tozFxro",
"ref": "c35f71b2-2a6d-4488-a1ba-87c2e711ce19",
"label": "Execution"
},
{
"id": "VGtsIHBLAhME",
"ref": "6c171a9a-9324-4f7d-adb9-290bd701efe9",
"label": "Problem Solving"
},
{
"id": "lVdV7MIL1anS",
"ref": "faba551f-4e6b-4377-9f74-11ca4fcc8ed5",
"label": "Other"
}
]
},
{
"id": "hcCNsLUHGXgv",
"ref": "d1ae8537-0d5a-4ca8-bb6b-f8057f04d7e2",
"type": "opinion_scale",
"title": "How satisfied were you with the level of communication during the project?",
"properties": {}
},
{
"id": "dBqPlgeKejN2",
"ref": "e2c884c1-0d92-4f18-9833-79dff0b3eef2",
"type": "nps",
"title": "How likely are you to recommend Braze for customer engagement services?",
"properties": {}
},
{
"id": "vLdpFmCmulF5",
"ref": "a86e48ec-6d10-49fc-ac03-4ac1aad4bfec",
"type": "dropdown",
"title": "In which country was the project executed?",
"properties": {}
}
],
"endings": [
{
"id": "LUpVm67y72vb",
"ref": "30c03bdf-80b3-45f5-8307-df8ca49046b1",
"title": "Thank you for taking the time to complete our survey!",
"type": "thankyou_screen",
"properties": {
"button_text": "Create a typeform",
"show_button": true,
"share_icons": true,
"button_mode": "default_redirect"
}
}
]
},
"answers": [
{
"type": "email",
"email": "[email protected]",
"field": {
"id": "G0IbXtfvsfjV",
"type": "email",
"ref": "814b9fc2-e6d2-4672-accf-22f754b84f20"
}
},
{
"type": "text",
"text": "Project",
"field": {
"id": "lg82q3t0rK03",
"type": "short_text",
"ref": "e1503b62-0241-4269-9902-5c539abf305e"
}
},
{
"type": "number",
"number": 9,
"field": {
"id": "UXftY0tSmuDV",
"type": "opinion_scale",
"ref": "5b839dbb-566b-47de-a47e-b0914d9ccf7c"
}
},
{
"type": "boolean",
"boolean": true,
"field": {
"id": "fE17bXVUEB4E",
"type": "yes_no",
"ref": "fd6be99d-1ed1-4a4d-b811-f6ecdd8fa9b6"
}
},
{
"type": "choice",
"choice": {
"id": "ruMnsZWjyalW",
"label": "Problem Solving",
"ref": "41dc926a-85af-4625-8a61-725fda35afda"
},
"field": {
"id": "NmVOQFuI0vv9",
"type": "multiple_choice",
"ref": "cd2b4176-db9a-49bb-a918-4463720bbc79"
}
},
{
"type": "choice",
"choice": {
"id": "lVdV7MIL1anS",
"label": "Other",
"ref": "faba551f-4e6b-4377-9f74-11ca4fcc8ed5"
},
"field": {
"id": "ZJop9pvoObzk",
"type": "multiple_choice",
"ref": "ce903cda-7e27-4b4c-9fa8-0623c47c61b4"
}
},
{
"type": "number",
"number": 8,
"field": {
"id": "hcCNsLUHGXgv",
"type": "opinion_scale",
"ref": "d1ae8537-0d5a-4ca8-bb6b-f8057f04d7e2"
}
},
{
"type": "number",
"number": 6,
"field": {
"id": "dBqPlgeKejN2",
"type": "nps",
"ref": "e2c884c1-0d92-4f18-9833-79dff0b3eef2"
}
},
{
"type": "choice",
"choice": {
"id": "KESjdqLseWmC",
"label": "Brazil",
"ref": "250210d9-33f6-4734-8ec6-06005a8ef66d"
},
"field": {
"id": "vLdpFmCmulF5",
"type": "dropdown",
"ref": "a86e48ec-6d10-49fc-ac03-4ac1aad4bfec"
}
}
],
"ending": {
"id": "LUpVm67y72vb",
"ref": "30c03bdf-80b3-45f5-8307-df8ca49046b1"
}
}
}
Ejemplos de Data Transformation
Las siguientes son plantillas de ejemplo creadas con nuestra carga útil de webhook de ejemplo de Typeform. Estas plantillas pueden utilizarse como punto de partida. Puedes crear una nueva plantilla o eliminar componentes específicos según tus necesidades.
En estas plantillas de ejemplo, estamos registrando un evento personalizado en el perfil de Braze. El título del Typeform se pasa como el nombre del evento personalizado, y los resultados del Typeform se pasan como propiedades del evento. Estas plantillas de ejemplo no contemplan los tipos de pregunta Calendly, Carga de archivos o Pago en Typeform.
Ejemplo: correo electrónico como identificador
En esta plantilla de ejemplo, utilizamos una dirección de correo electrónico (capturada de una pregunta de dirección de correo electrónico dentro del typeform) como identificador.

Si tienes la intención de utilizar una dirección de correo electrónico como identificador, consulta nuestras preguntas frecuentes del endpoint /users/track para obtener más información sobre el comportamiento esperado.
/* In the Typeform webhook payload each question is stored as a “title” within each object of the “fields” array. Our code defines a “title” variable where we store the value of each field title. */
const titles = payload.form_response.definition.fields.map(field => field.title);
/* The answers array is saved to a “tfAnswers” variable so this can be iterated through */
const tfAnswers = payload.form_response.answers;
/* The value of a response will change based on the type of question, to account for this we have created a function that iterates through the answers, determines what the answer type is and then, based on the type, adds the associated response to an extractedValues array. */
const extractValues = (tfAnswers) => {
const extractedValues = [];
tfAnswers.forEach((tfAnswer) => {
let result = null;
if (tfAnswer.type === 'choices') {
if (tfAnswer.choices) {
// Multiple choices
let labels = tfAnswer.choices.labels || [];
if (tfAnswer.choices.other) {
labels.push(tfAnswer.choices.other);
}
result = labels;
}
} else if (tfAnswer.type === 'choice' && Object.keys(tfAnswer.choice).length > 1) {
// Single choice
result = tfAnswer.choice && tfAnswer.choice.other ?
tfAnswer.choice.other.toString() :
tfAnswer.choice.label.toString();
} else if (tfAnswer.type === 'dropdown') {
// Dropdown
result = tfAnswer.text;
} else {
// For other types, use the type-specific value
result = tfAnswer[tfAnswer.type];
}
extractedValues.push(result);
});
return extractedValues;
};
/* We use the above defined function, passing it the “tfAnswers” variable that holds the answers portion of the Typeform webhook payload and save the output to a ”values” variable */
const values = extractValues(tfAnswers);
/* Finally, the values within the previously assigned “titles” variable and “values” variable are paired together in an object as the values to a “question” key and “answer” key in a “responses” array of objects variable. */
const results = titles.map((title, index) => {
return {
question: title,
answer: values[index],
};
});
/* The code defines a variable, "brazecall", to build a /users/track request. Within the request, the typeform title is populated as the event name, and our “results” variable (where all of our question/answer pairs are stored), is assigned as the event’s properties. */
let brazecall = {
"events": [{
"email": payload.form_response.answers.find(answer => answer.type === 'email').email,
"name": payload.form_response.definition.title,
"time": new Date().toISOString(),
"properties": {
"responses": results
}
}]
};
// After the /users/track request is assigned to brazecall, you will want to explicitly return “brazecall” to create an output
return brazecall;
{
"events": [
{
"email": "[email protected]",
"name": "Project Feedback Survey",
"time": "2023-10-17T18:21:39.527Z",
"properties": {
"responses": [
{
"question": "Please provide your email",
"answer": "[email protected]"
},
{
"question": "What was your role in the project?",
"answer": "Lorem ipsum dolor"
},
{
"question": "How would you rate the overall performance of the team?",
"answer": 5
},
{
"question": "Did the project meet its intended outcomes?",
"answer": true
},
{
"question": "If you answered \"No\" to the previous question, please explain why. If you answered \"Yes\", skip this question.",
"answer": "Lorem ipsum dolor"
},
{
"question": "Which area of the project do you think went well?",
"answer": "Communication"
},
{
"question": "Which area of the project do you think could be improved?",
"answer": "Communication"
},
{
"question": "How satisfied were you with the level of communication during the project?",
"answer": 5
},
{
"question": "How likely are you to recommend Braze for customer engagement services?",
"answer": 5
},
{
"question": "In which country was the project executed?",
"answer": "United States"
}
]
}
}
]
}
Ejemplo: uso de un identificador pasado en Hidden Fields
Puedes utilizar los Hidden Fields de Typeform para pasar datos en la carga útil del webhook de Typeform, como el ID de un usuario, sin tener que pasar esta información en la respuesta de Typeform.
En esta plantilla de ejemplo, utilizamos un Hidden Field “user_id” y lo pasamos en la carga útil de la solicitud /users/track como el external_id. Aunque estamos utilizando “user_id”, los campos pueden modificarse según tus necesidades.
/* In the Typeform webhook payload each question is stored as a “title” within each object of the “fields” array. Our code defines a “title” variable where we store the value of each field title. */
const titles = payload.form_response.definition.fields.map(field => field.title);
/* The answers array is saved to a “tfAnswers” variable so this can be iterated through */
const tfAnswers = payload.form_response.answers;
/* The value of a response will change based on the type of question, to account for this we have created a function that iterates through the answers, determines what the answer type is and then, based on the type, adds the associated response to an extractedValues array. */
const extractValues = (tfAnswers) => {
const extractedValues = [];
tfAnswers.forEach((tfAnswer) => {
let result = null;
if (tfAnswer.type === 'choices') {
if (tfAnswer.choices) {
// Multiple choices
let labels = tfAnswer.choices.labels || [];
if (tfAnswer.choices.other) {
labels.push(tfAnswer.choices.other);
}
result = labels;
}
} else if (tfAnswer.type === 'choice' && Object.keys(tfAnswer.choice).length > 1) {
// Single choice
result = tfAnswer.choice && tfAnswer.choice.other ?
tfAnswer.choice.other.toString() :
tfAnswer.choice.label.toString();
} else if (tfAnswer.type === 'dropdown') {
// Dropdown
result = tfAnswer.text;
} else {
// For other types, use the type-specific value
result = tfAnswer[tfAnswer.type];
}
extractedValues.push(result);
});
return extractedValues;
};
/* We use the above defined function, passing it the “tfAnswers” variable that holds the answers portion of the Typeform webhook payload and save the output to a ”values” variable */
const values = extractValues(tfAnswers);
/* Finally, the values within the previously assigned “titles” variable and “values” variable are paired together in an object as the values to a “question” key and “answer” key in a “responses” array of objects variable. */
const results = titles.map((title, index) => {
return {
question: title,
answer: values[index],
};
});
/* The code defines a variable, "brazecall", to build a /users/track request. Within the request, the typeform title is populated as the event name, and our “results” variable (where all of our question/answer pairs are stored), is assigned as the event’s properties. */
let brazecall = {
"events": [{
"external_id": payload.form_response.hidden.user_id,
"name": payload.form_response.definition.title,
"time": new Date().toISOString(),
"properties": {
"responses": results
}
}]
};
// After the /users/track request is assigned to brazecall, you will want to explicitly return “brazecall” to create an output
return brazecall;
{
"events": [
{
"external_id": "hidden_value",
"name": "Project Feedback Survey",
"time": "2023-10-17T18:27:22.209Z",
"properties": {
"responses": [
{
"question": "Please provide your email",
"answer": "[email protected]"
},
{
"question": "What was your role in the project?",
"answer": "Lorem ipsum dolor"
},
{
"question": "How would you rate the overall performance of the team?",
"answer": 5
},
{
"question": "Did the project meet its intended outcomes?",
"answer": true
},
{
"question": "If you answered \"No\" to the previous question, please explain why. If you answered \"Yes\", skip this question.",
"answer": "Lorem ipsum dolor"
},
{
"question": "Which area of the project do you think went well?",
"answer": "Communication"
},
{
"question": "Which area of the project do you think could be improved?",
"answer": "Communication"
},
{
"question": "How satisfied were you with the level of communication during the project?",
"answer": 5
},
{
"question": "How likely are you to recommend Braze for customer engagement services?",
"answer": 5
},
{
"question": "In which country was the project executed?",
"answer": "United States"
}
]
}
}
]
}
Paso 4: Publica tu webhook de Typeform
Una vez que hayas escrito tu Data Transformation, haz clic en Validate para asegurarte de que el código de tu Data Transformation tiene el formato correcto y funcionará como se espera. Después, guarda y activa tu Data Transformation.
Una vez activada, los datos de eventos personalizados se registran en el perfil de un usuario cuando completa tu formulario.

Supervisión y solución de problemas
Consulta la sección Supervisar tu transformación para obtener más información sobre la supervisión y la solución de problemas de tu transformación.