Omniconnect use cases
Your function exceeded the 500 ms execution time, 64 MB memory limit, or returned more than 50 commands. Optimize the function and retest with Test transformation. See Transformation function limits.
Connect platforms without direct integrations
If a platform supports outgoing webhooks, you can connect it to Bloomreach through Omniconnect. Your transformation function handles the data mapping—no custom middleware or manual exports required.
Examples
- Loyalty: Bring loyalty data from platforms like Eagle Eye or CrowdTwist into Bloomreach to enrich customer properties and trigger campaigns.
- Lead generation: Capture leads from platforms like TikTok Lead Gen or Typeform directly into Bloomreach. Leads flow into your campaigns automatically, without manual exports or third-party sync tools.
- Customer support: Bring support ticket events from platforms like Kustomer into Bloomreach. Include support history in segmentation and automation—for example, suppressing promotional emails for customers with open tickets.
- Bookings and reservations: Connect platforms like OpenTable to import reservation events. Use that data to trigger post-visit campaigns or build segments based on booking behavior.
Write custom transformation functions
Omniconnect includes a JavaScript runtime where you write transformation functions to reshape incoming webhook data before it reaches Bloomreach. This is useful when:
- Field names in the source payload don't match Bloomreach's data model
- .Data types need converting (for example, string dates to timestamps).
- You want to split a single incoming event into multiple Bloomreach events.
Replace existing middleware
If you're using a separate integration platform to move and transform data between a third-party source and Bloomreach, Omniconnect can replace it. Transformations run inside Bloomreach, removing the cost and maintenance overhead of an additional tool.
Example: Typeform integration
The transformation function below handles webhooks from Typeform. It converts each form submission into multiple Bloomreach events:
- One survey event for the overall submission.
- One survey event per answer, with the question text, ID, type, and answer value.
This lets you segment and trigger automations based on individual responses—not just the fact that someone submitted a form.
/**
* Params to be set to allow customization
* @param {Array<string>} idQuestions - List of question ids where id is stored to use for customer identification
* @param {string} idKey - Field id where id is stored
*/
const idQuestions = ["OyreMH40gpaO"];
const idKey = "registered";
/**
* Handler is the entry point for the function that enables the transformation of the data.
* @param {object} data - The input data
* @returns {Array<object>} - Array of transformed events
*/
function handler(data) {
const response = [];
const { form_response: formResponse } = data;
const timestamp = getTimestamp(formResponse.submitted_at);
const idValue = getIdValue(formResponse.answers);
const customerIds = {
[idKey]: idValue
};
response.push(returnEvent(getEventProperties(data, "submission"), customerIds, timestamp));
formResponse.definition.fields.slice(0, 50).forEach((field, index) => {
const answer = processAnswer(formResponse.answers[index]);
const properties = {
...getEventProperties(data, "answer"),
question: field.title,
question_id: field.id,
question_type: field.type,
question_index: index,
answer_type: formResponse.answers[index].type,
answer
};
response.push(returnEvent(properties, customerIds, timestamp));
});
return response;
}
/**
* Extracts id from the form response answers
* @param {Array<object>} answers - The answers from the form response
* @returns {string | undefined} - The id or undefined if not found
*/
function getIdValue(answers) {
const idAnswer = answers.find(obj => idQuestions.includes(obj.field.id));
return idAnswer?.email || answers.find(obj => obj.type === 'email')?.email;
}
/**
* Process the answer based on its type.
* @param {object} answer - The answer object
* @returns {*} - Processed answer
*/
function processAnswer(answer) {
switch (answer.type) {
case 'date':
return getMiddayUtcTimestamp(answer.date);
case 'choice':
return answer.choice.label;
case 'choices':
return answer.choices.labels;
default:
return answer[answer.type];
}
}
/**
* Get the properties for an event.
* @param {object} data - The input data
* @param {string} action - The action type
* @returns {object} - Event properties
*/
function getEventProperties(data, action) {
const { form_response: formResponse } = data;
return {
action,
integration_name: INTEGRATION_NAME,
integration_id: INTEGRATION_ID,
survey_name: formResponse.definition.title,
survey_id: formResponse.form_id,
token: formResponse.token,
landed_at: getTimestamp(formResponse.landed_at)
};
}
/**
* Construct an event.
* @param {object} properties - Event properties
* @param {object} customerIds - Customer IDs
* @param {number} timestamp - Event timestamp
* @returns {object} - The event object
*/
function returnEvent(properties, customerIds, timestamp) {
return {
name: "customers/events",
data: {
customer_ids: customerIds,
event_type: "survey",
timestamp,
properties
}
};
}
/**
* Convert a string date to a timestamp.
* @param {string} stringDate - The string representation of the date
* @returns {number} - The timestamp
*/
function getTimestamp(stringDate) {
const date = new Date(stringDate);
return Math.floor(date.getTime() / 1000);
}
/**
* Convert a string date to a midday UTC timestamp.
* @param {string} dateString - The string representation of the date
* @returns {number} - The midday UTC timestamp
*/
function getMiddayUtcTimestamp(dateString) {
const date = new Date(dateString);
date.setUTCHours(12, 0, 0, 0);
return Math.floor(date.getTime() / 1000);
}Updated 4 days ago

