Closed adventuretocode closed 1 year ago
Have you tried the command to create an extension for the app before running the query?
npm run shopify app generate extension
@pulkitgangwar , I have created the extension. It's a runtime error, when i execute the query to create the webpixel. For some reason it say's no extension found. This might be a bug with shopify:
2023-09-22 09:47:19 │ backend │ GraphqlQueryError: No extension found.
2023-09-22 09:47:19 │ backend │ at NewGraphqlClient.<anonymous> (/home/mohtashimkhan/marketing-platform-eko/rudderstack/code/shopify-rudderstack-app/shopify-web-pixel/node_mo
dules/@shopify/shopify-api/lib/clients/graphql/graphql_client.js:52:23)
2023-09-22 09:47:19 │ backend │ at Generator.next (<anonymous>)
2023-09-22 09:47:19 │ backend │ at fulfilled
(/home/mohtashimkhan/marketing-platform-eko/rudderstack/code/shopify-rudderstack-app/shopify-web-pixel/node_modules/tslib/tslib.js:164:62)
2023-09-22 09:47:19 │ backend │ at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
2023-09-22 09:47:19 │ backend │ response: {
2023-09-22 09:47:19 │ backend │ data: { webPixelCreate: null },
2023-09-22 09:47:19 │ backend │ errors: [
2023-09-22 09:47:19 │ backend │ {
2023-09-22 09:47:19 │ backend │ message: 'No extension found.',
2023-09-22 09:47:19 │ backend │ locations: [ { line: 3, column: 9 } ],
2023-09-22 09:47:19 │ backend │ path: [ 'webPixelCreate' ]
2023-09-22 09:47:19 │ backend │ }
2023-09-22 09:47:19 │ backend │ ],
2023-09-22 09:47:19 │ backend │ extensions: {
2023-09-22 09:47:19 │ backend │ cost: {
2023-09-22 09:47:19 │ backend │ requestedQueryCost: 10,
2023-09-22 09:47:19 │ backend │ actualQueryCost: 10,
2023-09-22 09:47:19 │ backend │ throttleStatus: {
2023-09-22 09:47:19 │ backend │ maximumAvailable: 1000,
2023-09-22 09:47:19 │ backend │ currentlyAvailable: 980,
2023-09-22 09:47:19 │ backend │ restoreRate: 50
2023-09-22 09:47:19 │ backend │ }
2023-09-22 09:47:19 │ backend │ }
2023-09-22 09:47:19 │ backend │ }
2023-09-22 09:47:19 │ backend │ },
2023-09-22 09:47:19 │ backend │ headers: {
2023-09-22 09:47:19 │ backend │ 'Alt-Svc': [ 'h3=":443"; ma=86400' ],
2023-09-22 09:47:19 │ backend │ 'Cf-Cache-Status': [ 'DYNAMIC' ],
2023-09-22 09:47:19 │ backend │ 'Cf-Ray': [ '80a9a032589ab8a0-AMS' ],
2023-09-22 09:47:19 │ backend │ Connection: [ 'close' ],
2023-09-22 09:47:19 │ backend │ 'Content-Encoding': [ 'gzip' ],
2023-09-22 09:47:19 │ backend │ 'Content-Language': [ 'en' ],
2023-09-22 09:47:19 │ backend │ 'Content-Security-Policy': [
2023-09-22 09:47:19 │ backend │ "default-src 'self' data: blob: 'unsafe-inline' 'unsafe-eval' https://* shopify-pos://*; block-all-mixed-content; child-src 'self' https://*
shopify-pos://*; connect-src 'self' wss://* https://*; frame-ancestors 'none'; img-src 'self' data: blob: https:; script-src
https://cdn.shopify.com https://cdn.shopifycdn.net https://checkout.shopifycs.com https://api.stripe.com https://mpsnare.iesnare.com
https://appcenter.intuit.com https://www.paypal.com https://js.braintreegateway.com https://c.paypal.com https://maps.googleapis.com
https://www.google-analytics.com https://v.shopify.com 'self' 'unsafe-inline' 'unsafe-eval'; upgrade-insecure-requests; report-uri
/csp-report?source%5Baction%5D=query&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=admin%2Fgraphql&source%5Bsection%5D=admin_api&source%5Buuid%5D
=e23c5517-5b03-4dd4-9407-838bbe1f68dd"
2023-09-22 09:47:19 │ backend │ ],
2023-09-22 09:47:19 │ backend │ 'Content-Type': [ 'application/json; charset=utf-8' ],
2023-09-22 09:47:19 │ backend │ Date: [ 'Fri, 22 Sep 2023 09:47:18 GMT' ],
2023-09-22 09:47:19 │ backend │ Nel: [
2023-09-22 09:47:19 │ backend │ '{"success_fraction":0.01,"report_to":"cf-nel","max_age":604800}'
2023-09-22 09:47:19 │ backend │ ],
2023-09-22 09:47:19 │ backend │ 'Referrer-Policy': [ 'origin-when-cross-origin' ],
2023-09-22 09:47:19 │ backend │ 'Report-To': [
2023-09-22 09:47:19 │ backend │ '{"endpoints":[{"url":"https:\\/\\/a.nel.cloudflare.com\\/report\\/v3?s=5z4xF2IdtjPb0437Dh15E5zy03LwaADQPmva1Zv%2FRsv0F1OoiCPaQDxno9nc2hHewd
y3VAfZUc0Zc1PN60uOObr1A1pnClx7Xta5JG0NGJ4r7SWOxI7k7MpW2NwzTANw9FgQn05qzfLipg%3D%3D"}],"group":"cf-nel","max_age":604800}'
2023-09-22 09:47:19 │ backend │ ],
2023-09-22 09:47:19 │ backend │ Server: [ 'cloudflare' ],
2023-09-22 09:47:19 │ backend │ 'Server-Timing': [
2023-09-22 09:47:19 │ backend │ 'processing;dur=61, graphql;desc="admin/mutation/other", cfRequestDuration;dur=195.999861'
2023-09-22 09:47:19 │ backend │ ],
2023-09-22 09:47:19 │ backend │ 'Strict-Transport-Security': [ 'max-age=7889238' ],
2023-09-22 09:47:19 │ backend │ 'Transfer-Encoding': [ 'chunked' ],
2023-09-22 09:47:19 │ backend │ Vary: [ 'Accept-Encoding' ],
2023-09-22 09:47:19 │ backend │ 'X-Content-Type-Options': [ 'nosniff' ],
2023-09-22 09:47:19 │ backend │ 'X-Dc': [ 'gcp-europe-west4,gcp-us-east1,gcp-us-east1' ],
2023-09-22 09:47:19 │ backend │ 'X-Download-Options': [ 'noopen' ],
2023-09-22 09:47:19 │ backend │ 'X-Frame-Options': [ 'DENY' ],
2023-09-22 09:47:19 │ backend │ 'X-Permitted-Cross-Domain-Policies': [ 'none' ],
2023-09-22 09:47:19 │ backend │ 'X-Request-Id': [ 'e23c5517-5b03-4dd4-9407-838bbe1f68dd' ],
2023-09-22 09:47:19 │ backend │ 'X-Shardid': [ '295' ],
2023-09-22 09:47:19 │ backend │ 'X-Shopid': [ '82534039848' ],
2023-09-22 09:47:19 │ backend │ 'X-Shopify-Api-Version': [ '2023-04' ],
2023-09-22 09:47:19 │ backend │ 'X-Shopify-Stage': [ 'production' ],
2023-09-22 09:47:19 │ backend │ 'X-Sorting-Hat-Podid': [ '295' ],
2023-09-22 09:47:19 │ backend │ 'X-Sorting-Hat-Shopid': [ '82534039848' ],
2023-09-22 09:47:19 │ backend │ 'X-Stats-Apiclientid': [ '62095982593' ],
2023-09-22 09:47:19 │ backend │ 'X-Stats-Apipermissionid': [ '634323239208' ],
2023-09-22 09:47:19 │ backend │ 'X-Stats-Userid': [ '' ],
2023-09-22 09:47:19 │ backend │ 'X-Xss-Protection': [
2023-09-22 09:47:19 │ backend │ '1; mode=block; report=/xss-report?source%5Baction%5D=query&source%5Bapp%5D=Shopify&source%5Bcontroller%5D=admin%2Fgraphql&source%5Bsection%
5D=admin_api&source%5Buuid%5D=e23c5517-5b03-4dd4-9407-838bbe1f68dd'
2023-09-22 09:47:19 │ backend │ ]
2023-09-22 09:47:19 │ backend │ }
2023-09-22 09:47:19 │ backend │ }
2023-09-22 09:47:19 │ backend │
2023-09-22 09:47:19 │ backend │ Node.js v20.6.1
Have you tried the command to create an extension for the app before running the query?
npm run shopify app generate extension
yes I have generated the web pixel extension successfully. i can also see into the app/ extension release version.
i am got confused in about the passing the Id in graphQL query.
@adventuretocode @pulkitgangwar I am facing the same error. I have raised the issue on shopify channel as well: https://community.shopify.com/c/technical-q-a/unable-to-set-up-web-pixel-app-extension/m-p/2236759#M138805
@keenborder786 Can you show me the graphql query and also how you are passing variables into the query and the web pixels extension's toml file.
Have you tried the command to create an extension for the app before running the query?
npm run shopify app generate extension
yes I have generated the web pixel extension successfully. i can also see into the app/ extension release version.
i am got confused in about the passing the Id in graphQL query.
@adventuretocode account id is just an example you can pass anything in the settings that the webpixel might need to process things but you have to define the structure of the variable that you are passing in query. you can set the structure in webpixel toml file.
Hello @pulkitgangwar thank you so much for replying back. I am using the same code that you are using in the repo. But still for your reference:
import { join } from "path";
import { readFileSync } from "fs";
import express from "express";
import serveStatic from "serve-static";
import * as crypto from "crypto";
import shopify from "./shopify.js";
import GDPRWebhookHandlers from "./gdpr.js";
const PORT = parseInt(
process.env.BACKEND_PORT || process.env.PORT || "3000",
10
);
const STATIC_PATH =
process.env.NODE_ENV === "production"
? `${process.cwd()}/frontend/dist`
: `${process.cwd()}/frontend/`;
const app = express();
// Set up Shopify authentication and webhook handling
app.get(shopify.config.auth.path, shopify.auth.begin());
app.get(
shopify.config.auth.callbackPath,
shopify.auth.callback(),
shopify.redirectToShopifyOrAppRoot()
);
app.post(
shopify.config.webhooks.path,
shopify.processWebhooks({ webhookHandlers: GDPRWebhookHandlers })
);
// If you are adding routes outside of the /api path, remember to
// also add a proxy rule for them in web/frontend/vite.config.js
app.use("/api/protected/*", shopify.validateAuthenticatedSession());
app.post("/api/track", (_req, res) => {
console.log(_req.body);
});
app.use(express.json());
app.post("/api/protected/webpixel", async (_req, res) => {
const client = new shopify.api.clients.Graphql({
session: res.locals.shopify.session,
});
const response = await client.query({
data: {
query: `
mutation webPixelCreate($webPixelInput: WebPixelInput!) {
webPixelCreate(webPixel: $webPixelInput) {
webPixel {
settings
id
}
userErrors {
code
field
message
}
}
}
`,
variables: {
webPixelInput: {
settings: {
accountID: crypto.randomUUID(),
},
},
},
},
});
if (response.body.data.webPixelCreate.userErrors.length) {
console.log(JSON.stringify(response, null, 4));
const errors = queryResponse.body.data.webPixelCreate.userErrors;
throw new Error(errors.map((error) => error.message).join(" , "));
}
return response.body.data.webPixelCreate.webPixel;
});
app.use(shopify.cspHeaders());
app.use(serveStatic(STATIC_PATH, { index: false }));
app.use("/*", shopify.ensureInstalledOnShop(), async (_req, res, _next) => {
return res
.status(200)
.set("Content-Type", "text/html")
.send(readFileSync(join(STATIC_PATH, "index.html")));
});
app.listen(PORT);
The above request is being trigged by the react button you have in frontend which raises the error,
@keenborder786 Can you confirm that your extension is live and enabled from shopify partner dashboard. Also can you show me the output of this command.
yarn shopify app info
Have you tried the command to create an extension for the app before running the query?
npm run shopify app generate extension
yes I have generated the web pixel extension successfully. i can also see into the app/ extension release version. i am got confused in about the passing the Id in graphQL query.
@adventuretocode account id is just an example you can pass anything in the settings that the webpixel might need to process things but you have to define the structure of the variable that you are passing in query. you can set the structure in webpixel toml file.
@pulkitgangwar Thanks it was working fine..
nice work your code was superb but you used the crypt that was confusion
How the app data can be access into the webpixel code ? for example i want to get the APP settings ga4_id how I can access that?
settings: { accountID: crypto.randomUUID(), },
@keenborder786 you need to pass the
settings: { accountID: 'correct_settings_value_as_per_toml', },
Have you tried the command to create an extension for the app before running the query?
npm run shopify app generate extension
yes I have generated the web pixel extension successfully. i can also see into the app/ extension release version. i am got confused in about the passing the Id in graphQL query.
@adventuretocode account id is just an example you can pass anything in the settings that the webpixel might need to process things but you have to define the structure of the variable that you are passing in query. you can set the structure in webpixel toml file.
@pulkitgangwar Thanks it was working fine..
nice work your code was superb but you used the crypt that was confusion
How the app data can be access into the webpixel code ? for example i want to get the APP settings ga4_id how I can access that?
@adventuretocode You have to define structure of that variable in your toml file and pass the variable using webpixelcreate or webpixelupdate mutation. You can access that variable using the settings JSON object settings JSON
settings: { accountID: crypto.randomUUID(), },
@keenborder786 you need to pass the
settings: { accountID: 'correct_settings_value_as_per_toml', },
toml file
type = "web_pixel_extension"
name = "tracker"
runtime_context = "strict"
[settings]
type = "object"
[settings.fields.accountID]
name = "Account ID"
description = "Account ID"
type = "single_line_text_field"
validations = [
{ name = "min", value = "1" }
]
[settings.fields.ga_id]
name = "ga4_id"
description = "google analytics 4 id"
type = "single_line_text_field"
query
const response = await client.query({
data: {
query: `
mutation webPixelCreate($webPixelInput: WebPixelInput!) {
webPixelCreate(webPixel: $webPixelInput) {
webPixel {
settings
id
}
userErrors {
code
field
message
}
}
}
`,
variables: {
webPixelInput: {
settings: {
accountID: crypto.randomUUID(),
ga_id: 'ga id'
},
},
},
},
});
@pulkitgangwar You were right I needed to enable the extension from the partner dashboard: Even though, now it says connected in my customer events and no more 'no extension found' however when it tries to send the events the web console shows the following error:
[Web Pixels] Error: The creation of Web Pixel id "89456936" failed: {}
Bt ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5543
$t ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5618
e ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5854
init ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5847
onload cart:402
e cart:402
<anonymous> cart:402
ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:formatted:5864:34
e ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5864
(Async: promise callback)
e ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5862
init ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5847
onload cart:402
(Async: EventListener.handleEvent)
e cart:402
<anonymous> cart:402
I guess it might be due to accountID. I am still confused about it. What exactly accountID is and where do i find it. Please help me.
@pulkitgangwar nvm it worked. Their was something wrong with my pixel code. Thank you for this repo. You are a superstar.
@pulkitgangwar You were right I needed to enable the extension from the partner dashboard: Even though, now it says connected in my customer events and no more 'no extension found' however when it tries to send the events the web console shows the following error:
[Web Pixels] Error: The creation of Web Pixel id "89456936" failed: {} Bt ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5543 $t ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5618 e ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5854 init ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5847 onload cart:402 e cart:402 <anonymous> cart:402 ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:formatted:5864:34 e ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5864 (Async: promise callback) e ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5862 init ba77fdd7bw358f7696p66f33b40maf4a7d89m.js:5847 onload cart:402 (Async: EventListener.handleEvent) e cart:402 <anonymous> cart:402
I guess it might be due to accountID. I am still confused about it. What exactly accountID is and where do i find it. Please help me.
accountId is just random example you can completely remove it and pass an empty object to settings in query
webPixelCreate: null }, errors: [ { message: 'No extension found.', locations: [ { line: 3, column: 9 } ], path: [ 'webPixelCreate' ] } ],
due to this line ' settings: { accountID: "crypto.randomUUID", },'