Skip to content

Commit

Permalink
Merge branch 'dev' into 'main'
Browse files Browse the repository at this point in the history
compatibility for pixel region

See merge request engineering/sm/discovery-connectors/shopify-discovery-connector-v2!25
  • Loading branch information
ksalic committed Jan 23, 2025
2 parents 9f435fe + 445723f commit afd767e
Show file tree
Hide file tree
Showing 15 changed files with 103 additions and 38 deletions.
7 changes: 7 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## 2.2.1

### Fixed

- [`Fixed`]: Fix settings error when markets are disabled or managed by a third party (https://bloomreach.atlassian.net/browse/DCONN-92).
- [`ADDED`]: Created a settings for pixel to toggle region: EU or US

## 2.2.0

### Added
Expand Down
7 changes: 7 additions & 0 deletions app/components/CatalogsForm/CatalogsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ export default function CatalogsForm({ account, markets }: CatalogsFormProps) {
mappings: useList(catalogMappings.map(mapping => ({ catalog: mapping.catalog ?? '' })) ?? []),
};

useEffect(() => {
if (!catalogMappings.length) {
fields.multi_catalog_enabled.onChange(false);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [catalogMappings.length]);

const reset = useReset(fields);

const isDirty = useDirty(fields);
Expand Down
2 changes: 1 addition & 1 deletion app/components/CatalogsForm/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"fields": {
"multiCatalogEnabled": {
"title": "Enable multi-catalog support",
"disabled": "Multi-catalog is only supported when there is at least one market"
"disabled": "There is no Shopify market defined, or your Shopify markets are managed by a third party"
},
"defaultCatalog": {
"title": "Default Bloomreach Catalog",
Expand Down
14 changes: 12 additions & 2 deletions app/routes/app.pixel/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@ import { json } from "@remix-run/node";
import { BlockStack, Card, Layout, Page, Text } from "@shopify/polaris";
import { useI18n } from "@shopify/react-i18n";
import { PageWrapper, LoadingPage, ExternalLink } from "~/components";
import { getStore } from "~/services";
import { getAppSettings, getStore, getWebPixelId, upsertWebPixel } from "~/services";
import { authenticate, extensionId } from "../../shopify.server";
import { generateDeeplinkingUrl } from "~/utils";
import { NAMESPACE_ACCOUNT } from "~/models";

import en from "./en.json";

import type { LoaderFunctionArgs } from "@remix-run/node";
import type { Account } from "~/types/store";

export const loader = async ({ request }: LoaderFunctionArgs) => {
const { session } = await authenticate.admin(request);
const { admin, session } = await authenticate.admin(request);
console.log("log: PixelPage: loader");
const webPixelId = await getWebPixelId(admin);
if (!webPixelId) {
const account = await getAppSettings<Account>(admin, NAMESPACE_ACCOUNT);
if (account.account_id) {
console.log("log: PixelPage: loader: init webPixel: account_id: %s", account.account_id);
await upsertWebPixel(admin, { settings: { account_id: account.account_id } });
}
}
const shopUrl = session.shop;
const { working_theme } = await getStore(shopUrl) ?? {};
return json({ shopUrl, extensionId, workingTheme: working_theme });
Expand Down
4 changes: 2 additions & 2 deletions app/routes/app.settings/route.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export const action = async ({ request }: ActionFunctionArgs): Promise<TypedResp
await updateAccount(admin, account);
console.log("log: SettingsPage: action: update account: success.");
}
if (catalogMappings) {
if (catalogMappings?.length) {
console.log("log: SettingsPage: action: update catalog mappings");
await updateCatalogMappings(admin, catalogMappings);
console.log("log: SettingsPage: action: update catalog mappings: success.");
Expand All @@ -51,7 +51,7 @@ export const action = async ({ request }: ActionFunctionArgs): Promise<TypedResp
await updateStore(session.shop, store);
console.log("log: SettingsPage: action: update store: success.");
}
if (viewMappings) {
if (viewMappings?.length) {
console.log("log: SettingsPage: action: update view mappings");
await updateViewMappings(admin, viewMappings);
console.log("log: SettingsPage: action: update view mappings: success.");
Expand Down
1 change: 1 addition & 0 deletions app/services/admin.server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,7 @@ export {
getThemes,
getMarketsWithCatalogsViews,
getMarketsForNamespace,
getWebPixelId,
upsertWebPixel,
getOrCreateMetaDefinitions,
MetafieldOwnerType,
Expand Down
9 changes: 7 additions & 2 deletions app/utils/markets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ import type { MarketCatalogMapping, MarketCatalogViewReturn, MarketReturn, Marke
export function getCatalogMappingsFromMarkets(markets: MarketCatalogViewReturn[]): MarketCatalogMapping[] {
const mappings: MarketCatalogMapping[] = [];

const primaryMarket = markets.find((market) => market.primary)!;
const primaryMarket = markets.find((market) => market.primary);

if (!primaryMarket?.webPresence) {
console.log("warn: cannot get languages data from Shopify markets");
return [];
}

for (const market of markets) {
if (!market.enabled) {
continue;
}

const webPresence = market.webPresence ?? primaryMarket.webPresence!;
const webPresence = market.webPresence ?? primaryMarket.webPresence;
const languages = webPresence.rootUrls.map<string>((rootUrl) => rootUrl.locale);

// Create mappings from existing metafields, if any
Expand Down
Binary file added docs/images/pixel-app-embeds_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion docs/shopify-app-user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -955,7 +955,7 @@ Next, in the opened theme editor, under **Bloomreach Configurations** app embed,
"images": [
{
"image": [
"https://raw.githubusercontent.com/bloomreach/shopify-discovery-connector-v2/main/docs/images/pixel-app-embeds.png",
"https://raw.githubusercontent.com/bloomreach/shopify-discovery-connector-v2/main/docs/images/pixel-app-embeds_2.png",
null,
"Enable Pixel"
],
Expand All @@ -981,6 +981,7 @@ Once **enabled**, the app will inject the pixel into your theme. The pixel will
In addition, you can customize the following options in the app embed settings:

- **Enable debug mode**: Flag the pixel data as test data for real-time debugging purpose. You can track debug events using **Integration mode** in Bloomreach Dashboard's [Events Management](https://documentation.bloomreach.com/discovery/docs/events-management#21-mode). Note that debug events are discarded and don’t impact any production features. So you should turn this option **off** on your live site.
- **Pixel Region**: Define to which region the pixel should send the pixel data. The region is depending on what region your account is provisioned in: North America or Europe
- **Product ID field**: Specify the Shopify product field used as the unique **product_id** (**pid**) sent in your Bloomreach feed. Can be either **handle** or **id**. You should set this option based on your Bloomreach product feed data.

#### Page View Pixels
Expand Down
56 changes: 33 additions & 23 deletions extensions/bloomreach-web-pixel/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { register } from "@shopify/web-pixels-extension";
import { escape, getPid, sendPixelData } from "./utils";
import {register} from "@shopify/web-pixels-extension";
import {escape, getPid, sendPixelData} from "./utils";

register(async ({ analytics, browser, init, settings }) => {
register(async ({analytics, browser, init, settings}) => {
// Bootstrap and insert pixel script tag here
const accountId = settings.account_id;
let br_data: Record<string, any> | null = null;
Expand All @@ -13,6 +13,16 @@ register(async ({ analytics, browser, init, settings }) => {
} catch (e) {
//ignore
}

const br_region = await (async () => {
try {
const region = await browser.localStorage.getItem('br_region');
return region || 'p.brsrvr.com';
} catch {
return 'p.brsrvr.com';
}
})();

if (!br_data) {
return;
}
Expand Down Expand Up @@ -44,7 +54,7 @@ register(async ({ analytics, browser, init, settings }) => {
type: "pageview",
};

sendPixelData(data);
sendPixelData(br_region, data);
});

analytics.subscribe('checkout_completed', (event) => {
Expand All @@ -61,15 +71,15 @@ register(async ({ analytics, browser, init, settings }) => {
};

data.basket = checkout.lineItems.reduce<string>((str, lineItem) =>
str.concat('!',
`i${escape(lineItem.variant?.product.id ?? '')}%27`,
lineItem.variant?.sku ? `s${escape(lineItem.variant.sku)}%27` : '',
`n${escape(lineItem.title)}%27`,
`q${lineItem.quantity}%27`,
`p${lineItem.variant?.price.amount ?? ''}`)
str.concat('!',
`i${escape(lineItem.variant?.product.id ?? '')}%27`,
lineItem.variant?.sku ? `s${escape(lineItem.variant.sku)}%27` : '',
`n${escape(lineItem.title)}%27`,
`q${lineItem.quantity}%27`,
`p${lineItem.variant?.price.amount ?? ''}`)
, '');

sendPixelData(data);
sendPixelData(br_region, data);
browser.localStorage.removeItem('br_data');
});

Expand All @@ -92,7 +102,7 @@ register(async ({ analytics, browser, init, settings }) => {

console.log('product_added_to_cart: cartLine: ', cartLine);
console.log('product_added_to_cart: brAtcEventData: ', eventData);
const { pid_field, ...extraParams } = eventData;
const {pid_field, ...extraParams} = eventData;
const pid = getPid(cartLine.merchandise.product, pid_field);
const data: Record<string, any> = {
...br_data,
Expand All @@ -110,12 +120,12 @@ register(async ({ analytics, browser, init, settings }) => {
data.sku = cartLine.merchandise.sku;
}

sendPixelData(data);
sendPixelData(br_region, data);
browser.sessionStorage.removeItem('br_atc_event_data');
});

analytics.subscribe('br_product_quickview', async (event) => {
const { customData } = event;
const {customData} = event;
console.log('br_product_quickview: customData: ', customData);
const data: Record<string, any> = {
...br_data,
Expand All @@ -124,11 +134,11 @@ register(async ({ analytics, browser, init, settings }) => {
type: "event",
...customData,
};
sendPixelData(data);
sendPixelData(br_region, data);
});

analytics.subscribe('br_suggest_submit', async (event) => {
const { customData } = event;
const {customData} = event;
console.log('br_suggest_submit: customData: ', customData);
const data: Record<string, any> = {
...br_data,
Expand All @@ -137,11 +147,11 @@ register(async ({ analytics, browser, init, settings }) => {
type: "event",
...customData,
};
sendPixelData(data);
sendPixelData(br_region, data);
});

analytics.subscribe('br_suggest_click', async (event) => {
const { customData } = event;
const {customData} = event;
console.log('br_suggest_click: customData: ', customData);
const data: Record<string, any> = {
...br_data,
Expand All @@ -150,11 +160,11 @@ register(async ({ analytics, browser, init, settings }) => {
type: "event",
...customData,
};
sendPixelData(data);
sendPixelData(br_region, data);
});

analytics.subscribe('br_widget_click', async (event) => {
const { customData } = event;
const {customData} = event;
console.log('br_widget_click: customData: ', customData);
const data: Record<string, any> = {
...br_data,
Expand All @@ -163,11 +173,11 @@ register(async ({ analytics, browser, init, settings }) => {
type: "event",
...customData,
};
sendPixelData(data);
sendPixelData(br_region, data);
});

analytics.subscribe('br_widget_view', async (event) => {
const { customData } = event;
const {customData} = event;
console.log('br_widget_view: customData: ', customData);
const data: Record<string, any> = {
...br_data,
Expand All @@ -176,6 +186,6 @@ register(async ({ analytics, browser, init, settings }) => {
type: "event",
...customData,
};
sendPixelData(data);
sendPixelData(br_region, data);
});
});
6 changes: 3 additions & 3 deletions extensions/bloomreach-web-pixel/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ export function escape(str?: string | null): string {
.replaceAll(")", "%29");
}

export function sendPixelData(data: Record<string, any>) {
export function sendPixelData(region:string, data: Record<string, any>) {
console.log('sendPixelData: data: ', data);
const params = Object.keys(data).filter((key) => !!data[key]).map((key) => `${key}=${data[key]}`).join('&');
console.log('sendPixelData: params: ', params);
fetch(`https://p.brsrvr.com/pix.gif?${params}`, {
console.log('sendPixelData: params: ', params, region);
fetch(`https://${region}/pix.gif?${params}`, {
method: 'GET',
mode: 'no-cors',
});
Expand Down
20 changes: 20 additions & 0 deletions extensions/theme-extension/blocks/bloomreach-config.liquid
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@
enabled: true,
};
localStorage.setItem("br_region", "{{block.settings.pixel_region }}");
(function() {
const br_data = {};
br_data.ptype = "{{ page_type }}";
Expand Down Expand Up @@ -166,6 +168,7 @@
{%- endif -%}
localStorage.setItem("br_data", JSON.stringify(br_data));
{% comment %}localStorage.setItem("br_region", "{{block.settings.pixel_region }}");{% endcomment %}
document.addEventListener("brCartClickAdd", (event) => {
event.stopImmediatePropagation();
Expand Down Expand Up @@ -284,6 +287,23 @@
"type": "checkbox",
"label": "t:pixelConfig.enable.label"
},
{
"id": "pixel_region",
"type": "select",
"label": "t:pixelConfig.region.label",
"info": "t:pixelConfig.region.info",
"options": [
{
"label": "North America",
"value": "p.brsrvr.com"
},
{
"label": "Europe",
"value": "p-eu.brsrvr.com"
}
],
"default": "p.brsrvr.com"
},
{
"id": "pixel_debug",
"type": "checkbox",
Expand Down
4 changes: 4 additions & 0 deletions extensions/theme-extension/locales/en.default.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@
"enable": {
"label": "Enable Bloomreach Pixel"
},
"region": {
"label": "Pixel Region",
"info": "The region the account is provisioned in"
},
"debug": {
"label": "Enable debug mode",
"info": "Flag the pixel data as test data for real-time debugging purpose. You can track debug events using Integration mode in [Events Management](https://documentation.bloomreach.com/discovery/docs/events-management#21-mode). Note that debug events are discarded and don’t impact any production features."
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "bloomreach-connector",
"version": "2.2.0",
"version": "2.2.1",
"sdkVersion": "3.2.0",
"private": true,
"scripts": {
Expand Down
6 changes: 3 additions & 3 deletions shopify.app.qa.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

client_id = "b24120d153af45ae89ab672fed5b60d7"
name = "Bloomreach Connector QA"
handle = "bloomreachconnector"
handle = "bloomreachconnectorqa"
application_url = "https://bloomreach-discovery-v2-qa-975ae9b0aa97.herokuapp.com/"
embedded = true

Expand All @@ -12,7 +12,7 @@ include_config_on_deploy = true

[access_scopes]
# Learn more at https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes
scopes = "read_themes"
scopes = "read_customer_events,read_markets,read_themes,write_markets,write_pixels"

[auth]
redirect_urls = [
Expand All @@ -22,7 +22,7 @@ redirect_urls = [
]

[webhooks]
api_version = "2024-04"
api_version = "2024-07"

[[webhooks.subscriptions]]
uri = "https://bloomreach-discovery-v2-qa-975ae9b0aa97.herokuapp.com/webhooks/customers_redact"
Expand Down

0 comments on commit afd767e

Please sign in to comment.