// initializers/myInitializer.ts import { Initializer, api, config } from "actionhero"; import { Shop } from "../models/Shop" import * as crypto from "crypto"; import * as fetch from "node-fetch"; export class shopifyShops extends Initializer { constructor() { super(); this.name = "shopifyShops"; this.loadPriority = 1001; this.startPriority = 1001; this.stopPriority = 1001; } async initialize() { api.shopifyAuth = api.shopifyAuth || {}; api.shopifyAuth.afterAuth = async (data, accessToken) => { const shop = { token : accessToken.access_token, scopes : accessToken.scope, shop : accessToken.shop }; await api.shopifyShops.createUpdateShop(shop); await api.shopifyShops.install(shop.shop); api.log("Shopify Authorization Complete! Token saved"); return; } api.shopifyShops = {}; api.shopifyShops.createUpdateShop = async (auth) => { let shop = await api.shopifyShops.getShop(auth.shop); if(shop){ shop.token = auth.token; shop.scopes = auth.scopes; return await shop.save(); }else{ return await api.shopifyShops.createShop(auth); } } api.shopifyShops.createShop = async (auth) => { const shopHash = api.shopifyShops.generateShopHash(auth.shop); const shop = { shopHash, ...auth } const response = await Shop.create(shop); return response; } api.shopifyShops.getShop = async (shop) => { const shopHash = api.shopifyShops.generateShopHash(shop); return await Shop.findOne({ where:{shopHash} }); } api.shopifyShops.removeShop = async (shopId) => { const shopHash = api.shopifyShops.generateShopHash(shopId); const shop = await Shop.findOne({ where:{shopHash} }); if(shop) shop.destroy(); } api.shopifyShops.generateShopHash = (shop) => { const apiSecret = process.env.SHOPIFY_API_SECRET const shopHash = crypto.createHmac('sha256', apiSecret) .update(shop) .digest('hex') return shopHash; } api.shopifyShops.install = async (shop) => { const installed = await api.shopSettings.get(shop, "installed"); if(installed.length == 0 || installed[0].value == 0){ api.log(`Installing Shop ${shop}`); await api.shopSettings.setDefaults(shop); await api.shopifyShops.installWebhooks(shop); await api.imports.creatImportFolders(shop); } } api.shopifyShops.getWebhooks = async (shop) => { const { apiCode } = config.shopifyMiddleware; const { forwardingAddress } = config.shopifyAuth; const orderUrl = `https://${shop}/admin/api/${apiCode}/webhooks.json`; const auth = await api.shopifyShops.getShop(shop); const response = await fetch(orderUrl, { method: 'GET', headers: { "X-Shopify-Access-Token": auth.token, 'Content-Type': 'application/json;charset=UTF-8' } }); const responseData = await response.json(); return responseData; } api.shopifyShops.installWebhooks = async (shop) => { const webhooks = await api.shopifyShops.getWebhooks(shop); await api.shopifyShops.installWebhook(shop, "orders/create", "/webhooks/order/export"); await api.shopifyShops.installWebhook(shop, "app/uninstalled", "/webhooks/app/uninstall"); return true; } api.shopifyShops.installWebhook = async (shop, topic, callback) => { const { apiCode } = config.shopifyMiddleware; const { forwardingAddress } = config.shopifyAuth; const callbackUrl = `https://${shop}/admin/api/${apiCode}/webhooks.json`; const auth = await api.shopifyShops.getShop(shop); const data = { "webhook": { "topic": topic, "address": `${forwardingAddress}${callback}`, "format": "json" } } const response = await fetch(callbackUrl, { method: 'POST', body: JSON.stringify(data), headers: { "X-Shopify-Access-Token": auth.token, 'Content-Type': 'application/json;charset=UTF-8' } }); const responseData = await response.json(); return responseData; } } }