<!-- Crescendo assistant widget begin -->
<link href="https://cdn.crescendo.ai/bot-widget/latest/enegelaibot.css" rel="stylesheet">
<script src="https://cdn.crescendo.ai/bot-widget/latest/enegelaibot.umd.js" type="text/javascript" async></script>
<style>
enegelai-bot {
--enegelai-bot-header-background: {{ section.settings.header_bg_color }};
--enegelai-bot-header-color: {{ section.settings.header_text_color }};
--enegelai-bot-message-user-background: {{ section.settings.user_msg_bg }};
--enegelai-bot-message-user-color: {{ section.settings.user_msg_color }};
--enegelai-bot-message-bot-background: {{ section.settings.bot_msg_bg }};
--enegelai-bot-message-bot-color: {{ section.settings.bot_msg_color }};
--enegelai-bot-anchor-background: {{ section.settings.anchor_bg_color }};
--enegelai-bot-anchor-border-color: {{ section.settings.anchor_border_color }};
--enegelai-bot-form-submit-background: {{ section.settings.submit_bg_color }};
--enegelai-bot-form-submit-border: {{ section.settings.submit_border_color }};
--enegelai-bot-popup-min-height: {{ section.settings.popup_min_height }}px;
}
</style>
<script>
(function () {
{% assign resolved_bot_url = section.settings.bot_url | default: 'bot.crescendo.ai' | strip | remove: 'https://' | remove: 'http://' | split: '/' | first %}
var el = document.createElement('enegelai-bot');
el.setAttribute('url', {{ resolved_bot_url | json }});
el.setAttribute('org-id', {{ section.settings.org_id | json }});
el.setAttribute('name', {{ section.settings.bot_name | json }});
el.setAttribute('bot-id', {{ section.settings.bot_id | json }});
{% if section.settings.logo_url != blank %}
el.setAttribute('logo-url', {{ section.settings.logo_url | json }});
{% else %}
el.setAttribute('logo-url', '');
{% endif %}
document.body.appendChild(el);
})();
</script>
<script>
const C7O_ATTRIBUTION_KEY = 'c7o_attribution';
function getAttribution() {
try {
return window.sessionStorage.getItem(C7O_ATTRIBUTION_KEY);
} catch (error) {
return null;
}
}
function setAttribution() {
try {
window.sessionStorage.setItem(C7O_ATTRIBUTION_KEY, 'crescendo');
} catch (error) {}
}
function captureAttributionFromUrl() {
const params = new URLSearchParams(window.location.search);
if (params.get('utm_source') === 'crescendo') {
setAttribution();
}
}
async function updateCartTags(tags = {}) {
try {
const attributes = {
bot_timestamp: Date.now(),
...tags
};
if (!attributes.bot_source) {
attributes.bot_source = 'crescendo';
}
if (!attributes.bot_conversation_id) {
delete attributes.bot_conversation_id;
}
const res = await fetch(`${window.Shopify.routes.root}cart/update.js`, {
method: 'POST',
credentials: 'same-origin',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify({
attributes,
note: 'crescendo'
})
});
return await res.json();
} catch (error) {
console.error('Crescendo assistant: failed to update cart attribution', error);
}
}
async function syncAttribution() {
if (!getAttribution()) {
return null;
}
return updateCartTags();
}
async function resolveStorefrontCartGid() {
let cartId = null;
const cookieMatch = document.cookie.match(/(?:^|;\s*)cart=([^;]+)/);
if (cookieMatch) {
const tokenWithKey = decodeURIComponent(cookieMatch[1]);
if (tokenWithKey.includes('?key=')) {
cartId = `gid://shopify/Cart/${tokenWithKey}`;
}
}
if (!cartId) {
const res = await fetch(`${window.Shopify.routes.root}cart.js`, {
credentials: 'same-origin',
headers: { 'Accept': 'application/json' },
cache: 'no-store'
});
const cart = await res.json();
if (cart?.token && cart.token.includes('?key=')) {
cartId = `gid://shopify/Cart/${cart.token}`;
}
}
if (!cartId) {
const upd = await fetch(`${window.Shopify.routes.root}cart/update.js`, {
method: 'POST',
credentials: 'same-origin',
headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
body: JSON.stringify({ attributes: { _bot_probe: String(Date.now()) } })
});
const updated = await upd.json();
if (updated?.token && updated.token.includes('?key=')) {
cartId = `gid://shopify/Cart/${updated.token}`;
}
}
return cartId;
}
captureAttributionFromUrl();
document.addEventListener('page:change', function () {
captureAttributionFromUrl();
syncAttribution();
});
document.addEventListener('shopify:section:load', function () {
syncAttribution();
});
window.addEventListener('c7o:bot:conversationStart', (event) => {
setAttribution();
const conversationId = event?.detail?.conversationId || `conv_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;
updateCartTags({
bot_conversation_id: conversationId,
bot_source: 'crescendo',
bot_initiated: new Date().toISOString()
});
});
window.addEventListener('load', async () => {
const chatBot = document.querySelector('enegelai-bot');
const contextData = {};
try {
await syncAttribution();
} catch (error) {
console.error('Crescendo assistant: failed to sync attribution', error);
}
contextData.locale = {{ request.locale.iso_code | default: localization.language.iso_code | json }};
contextData.language = {{ localization.language.iso_code | default: request.locale.iso_code | json }};
contextData.country = {{ localization.country.iso_code | json }};
contextData.currency = {{ cart.currency.iso_code | default: localization.country.currency.iso_code | default: shop.currency | json }};
contextData.market_handle = {{ localization.market.handle | default: '' | json }};
{% if customer %}
contextData.email = {{ customer.email | json }};
contextData.phone = {{ customer.phone | json }};
contextData.name = {{ customer.name | json }};
try {
{% if customer.last_order %}
contextData.last_order = {
order_number: {{ customer.last_order.order_number | json }},
created_at: {{ customer.last_order.created_at | json }},
order_status_url: {{ customer.last_order.order_status_url | json }},
fulfillment_status: {{ customer.last_order.fulfillment_status | json }},
line_items: []
};
{% if customer.last_order.line_items.size > 0 %}
{% for item in customer.last_order.line_items %}
contextData.last_order.line_items.push({
title: {{ item.title | json }},
quantity: {{ item.quantity | json }}
});
{% endfor %}
{% endif %}
{% if customer.last_order.fulfillments.first.tracking_url %}
contextData.last_order.fulfillments = [{
tracking_url: {{ customer.last_order.fulfillments.first.tracking_url | json }}
}];
{% endif %}
{% endif %}
} catch(error) {
console.warn('Crescendo assistant: not able to add last order information to context', error);
}
{% endif %}
try {
const cartId = await resolveStorefrontCartGid();
if (cartId) {
contextData.cart_id = cartId;
}
} catch(error) {
console.error('Crescendo assistant: error getting cart ID', error);
}
chatBot.setContext(contextData);
});
</script>
<!-- Crescendo assistant widget end -->
{% schema %}
{
"name": "Crescendo Assistant",
"tag": "section",
"class": "section",
"presets": [{
"name": "Crescendo Assistant",
"category": "Footer"
}],
"settings": [
{
"type": "header",
"content": "Assistant Configuration"
},
{
"type": "text",
"id": "bot_name",
"label": "Assistant Name",
"placeholder": "Assistant Widget Name",
"default": "Crescendo Assistant",
"info": "Name that will be displayed in the header of the widget"
},
{
"type": "text",
"id": "org_id",
"label": "Org ID",
"info": "Your Crescendo Org ID"
},
{
"type": "text",
"id": "bot_id",
"label": "Assistant ID",
"info": "Your Crescendo assistant identifier"
},
{
"type": "text",
"id": "bot_url",
"label": "Service host",
"placeholder": "bot.crescendo.ai",
"info": "Crescendo bot service host. Leave blank for production; use the host value provided by Crescendo for staging or other environments."
},
{
"type": "text",
"id": "logo_url",
"label": "Logo URL",
"placeholder": "https://example.com/logo.png",
"info": "Optional custom logo"
},
{
"type": "header",
"content": "Assistant Appearance"
},
{
"type": "color",
"id": "header_bg_color",
"label": "Header Background Color",
"default": "#00d176"
},
{
"type": "color",
"id": "header_text_color",
"label": "Header Text Color",
"default": "#ffffff"
},
{
"type": "color",
"id": "user_msg_bg",
"label": "User Message Background",
"default": "#fafafa"
},
{
"type": "color",
"id": "user_msg_color",
"label": "User Message Text Color",
"default": "#000000"
},
{
"type": "color",
"id": "bot_msg_bg",
"label": "Assistant Message Background",
"default": "#fafafa"
},
{
"type": "color",
"id": "bot_msg_color",
"label": "Assistant Message Text Color",
"default": "#000000"
},
{
"type": "color",
"id": "anchor_bg_color",
"label": "Anchor Background Color",
"default": "#00d176"
},
{
"type": "color",
"id": "anchor_border_color",
"label": "Anchor Border Color",
"default": "#00d176"
},
{
"type": "color",
"id": "submit_bg_color",
"label": "Submit Button Background",
"default": "#00d176"
},
{
"type": "color",
"id": "submit_border_color",
"label": "Submit Button Border",
"default": "#00d176"
},
{
"type": "range",
"id": "popup_min_height",
"label": "Popup Minimum Height",
"min": 40,
"max": 100,
"step": 10,
"default": 60,
"unit": "px"
}
]
}
{% endschema %}