pulkitgangwar / shopify-web-pixel-api-example

9 stars 2 forks source link

getting the error no extension found #1

Closed adventuretocode closed 1 year ago

adventuretocode commented 1 year ago

webPixelCreate: null }, errors: [ { message: 'No extension found.', locations: [ { line: 3, column: 9 } ], path: [ 'webPixelCreate' ] } ],

due to this line ' settings: { accountID: "crypto.randomUUID", },'

Screenshot from 2023-09-13 16-53-51

pulkitgangwar commented 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
keenborder786 commented 1 year ago

@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
adventuretocode commented 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

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.

keenborder786 commented 1 year ago

@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

pulkitgangwar commented 1 year ago

@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.

pulkitgangwar commented 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

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.

keenborder786 commented 1 year ago

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,

pulkitgangwar commented 1 year ago

@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
adventuretocode commented 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

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 commented 1 year ago
 settings: {
            accountID: crypto.randomUUID(),
          },

@keenborder786 you need to pass the

settings: { accountID: 'correct_settings_value_as_per_toml', },

pulkitgangwar commented 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

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

pulkitgangwar commented 1 year ago
 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'
          },
        },
      },
    },
  });

read more

keenborder786 commented 1 year ago

@pulkitgangwar You were right I needed to enable the extension from the partner dashboard: image 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.

keenborder786 commented 1 year ago

@pulkitgangwar nvm it worked. Their was something wrong with my pixel code. Thank you for this repo. You are a superstar.

pulkitgangwar commented 1 year ago

@pulkitgangwar You were right I needed to enable the extension from the partner dashboard: image 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