What's your biggest current challenge? Have your say in Community Polls along the right column.
Our Partner & Developer boards on the community are moving to a brand new home: the .dev community forums! While you can still access past discussions here, for all your future app and storefront building questions, head over to the new forums.

Heroku server restart makes my script tag disappear on storefront/order-status page

Solved

Heroku server restart makes my script tag disappear on storefront/order-status page

EugeneCXY
Excursionist
16 3 4

Hey,

I've been stuck on this error for some time. Can't seem to find any docs anywhere

I have made a script tag through graphql that displays on the order status page but every time Heroku relocates dyno to a new server(cannot be avoided apparently) the server.js has to restart and requires an auth to access the script tag again.

Here is the error on the logs of heroku  

Capture.JPG

I am currently using the Shopify-Cli code, I have not changed much to it except some console logs to understand the structure.

import "@babel/polyfill";
import dotenv from "dotenv";
import "isomorphic-fetch";
import createShopifyAuth, { verifyRequest } from "@shopify/koa-shopify-auth";
import Shopify, { ApiVersion } from "@shopify/shopify-api";
import Koa from "koa";
import next from "next";
import Router from "koa-router";
import {storeCallback,deleteCallback,loadCallback} from './sessiondb.js'


dotenv.config();
const port = parseInt(process.env.PORT, 10) || 8081;
const dev = process.env.NODE_ENV !== "production";
const app = next({
  dev,
});
const handle = app.getRequestHandler();

console.log("1")
Shopify.Context.initialize({
  API_KEY: process.env.SHOPIFY_API_KEY,
  API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
  SCOPES: process.env.SCOPES.split(","),
  HOST_NAME: process.env.HOST.replace(/https:\/\//, ""),
  API_VERSION: ApiVersion.April21,
  IS_EMBEDDED_APP: true,
  // This should be replaced with your preferred storage strategy
  SESSION_STORAGE: new Shopify.Session.CustomSessionStorage(
    storeCallback,
    loadCallback,
    deleteCallback

  ),

});

// Storing the currently active shops in memory will force them to re-login when your server restarts. You should
// persist this object in your app.
const ACTIVE_SHOPIFY_SHOPS = {};

// const handleWebhookRequest = async (topic, shop, webhookRequestBody) => {
//   console.log("handle webhook" + shop)
//   // this handler is triggered when a webhook is sent by the Shopify platform to your application
// }

app.prepare().then(async () => {
  console.log("2")
  const server = new Koa();
  const router = new Router();
  server.keys = [Shopify.Context.API_SECRET_KEY];
  // Shopify.Webhooks.Registry.webhookRegistry.push({path: "/webhooks", topic: "ORDERS_PAID", webhookHandler: handleWebhookRequest});
  server.use(
    createShopifyAuth({
      async afterAuth(ctx) {
        // Access token and shop available in ctx.state.shopify
        console.log("3")
        const { shop, accessToken, scope } = ctx.state.shopify;
        console.log("IM TESTING THIS"+ shop,accessToken,scope);
        const host = ctx.query.host;
        ACTIVE_SHOPIFY_SHOPS[shop] = scope;
        console.log("4")
        const response = await Shopify.Webhooks.Registry.register({
          shop,
          accessToken,
          path: "/webhooks",
          topic: "APP_UNINSTALLED",
          webhookHandler: async (topic, shop, body) =>
            delete ACTIVE_SHOPIFY_SHOPS[shop],
        });

        if (!response.success) {
          console.log(
            `Failed to register APP_UNINSTALLED webhook: ${response.result}`
          );
        }
        console.log("5")
        // Redirect to app with shop parameter upon auth
        ctx.redirect(`/?shop=${shop}&host=${host}`);
      },
    })
  );

  const handleRequest = async (ctx) => {
    console.log("6")
    await handle(ctx.req, ctx.res);
    ctx.respond = false;
    ctx.res.statusCode = 200;
  };

  router.post("/webhooks", async (ctx) => {
    try {
      console.log("7")
      await Shopify.Webhooks.Registry.process(ctx.req, ctx.res);
      console.log(`Webhook processed, returned status code 200`);
    } catch (error) {
      console.log(`Failed to process webhook: ${error}`);
    }
  });



  router.post(
    "/graphql",
    verifyRequest({ returnHeader: true }),
    async (ctx, next) => {
      console.log("8")
      await Shopify.Utils.graphqlProxy(ctx.req, ctx.res);
    }
  );

  router.get("(/_next/static/.*)", handleRequest); // Static content is clear
  router.get("/_next/webpack-hmr", handleRequest); // Webpack content is clear
  // router.get("(.*)", verifyRequest(),handleRequest);
  router.get("(.*)", async (ctx) => {
    console.log("9")
    const shop = ctx.query.shop;
    console.log("get request "+ shop)
    // This shop hasn't been seen yet, go through OAuth to create a session
    if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
      console.log("its getting redirected")
      ctx.redirect(`/auth?shop=${shop}`);
    } else {
      await handleRequest(ctx);
    }
  });


  server.use(router.allowedMethods());
  server.use(router.routes());
  server.listen(port, () => {
    console.log(`> Ready on http://localhost:${port}`);
  });
});

 

Thanks so much in advance. 

Accepted Solution (1)

EugeneCXY
Excursionist
16 3 4

This is an accepted solution.

It appears that I was using the server to generate the script tag so when the server is restarting, it needs to be re-authenticated to access the start tag. I am now hosting the script tag in AWS cloudfront CDN 

View solution in original post

Reply 1 (1)

EugeneCXY
Excursionist
16 3 4

This is an accepted solution.

It appears that I was using the server to generate the script tag so when the server is restarting, it needs to be re-authenticated to access the start tag. I am now hosting the script tag in AWS cloudfront CDN