Shopify Webhook in NestJS

Viewed 1527

i am working to connect shopify webhook to nestjs. Although i made the app and made the connection to shopify and installed the app.

Meanwhile, i have created the endpoint in my nestjs application, but it is not reflecting anything from shopify

here are the files below

shopify-orders.service.ts

import "@babel/polyfill";
import { Injectable, BadRequestException, ServiceUnavailableException } from '@nestjs/common';
import "isomorphic-fetch";
import dotenv from "dotenv";
import Koa from 'koa';
const { default: createShopifyAuth } = require('@shopify/koa-shopify-auth');
import { default as Shopify, ApiVersion } from '@shopify/shopify-api';
const { verifyRequest} = require('@shopify/koa-shopify-auth');
// const { default: Shopify, ApiVersion } = require('@shopify/shopify-api');
const Router = require('koa-router');
import {receiveWebhook, registerWebhook} from '@shopify/koa-shopify-webhooks';
const session = require('koa-session');
const app = new Koa();
const router = new Router();

@Injectable()
export class ShopifyOrdersService {
    constructor() {}

    public ShopifyApiCalls = () => {
        const app = new Koa();
        const router = new Router();

    const constport = parseInt(process.env.PORT, 10) || 3000;
    const dev = process.env.NODE_ENV !== "production";
    const { SHOPIFY_API_SECRET, SHOPIFY_API_KEY, SCOPES } = process.env;
    app.use(
        createShopifyAuth({ 
            apiKey: SHOPIFY_API_KEY, 
            secret: SHOPIFY_API_SECRET,
            scopes : [SCOPES],

            async afterAuth(ctx) {
                const { shop, accessToken} = ctx.state.shopify;
                  const handleWebhookRequest = async (topic: string, shop: string, webhookRequestBody: string) => {
        // this handler is triggered when a webhook is sent by the Shopify platform to your application
      }

                const registration = await Shopify.Webhooks.Registry.register({
                    shop,
                    accessToken,
                    path: '/webhooks/orders',
                    topic: 'ORDERS_CREATE', 
                    webhookHandler: handleWebhookRequest,
                })
                if (registration.success) {
                    console.log('Successfully registered webhook!');
                  } else {
                    console.log('Failed to register webhook', registration.result);
                  }

                ctx.redirect(`/?shop=${shop}`);

            }
        })
    )

    app.use(
        receiveWebhook({
            path:'/webhooks/orders',
            secret: SHOPIFY_API_SECRET,
            onReceived(ctx) {
                console.log('received webhook: ',ctx.state.webhook);
            },
        }),
    );
    app.use(verifyRequest());

    app.use(ctx => {
    }); 
}
}

shopify-orders.controller.ts

import "@babel/polyfill";
import {   BadRequestException,
    Body,
    Controller,
    Get,
    Headers,
    HttpCode,
    HttpStatus,
    Post,
    Query, } from '@nestjs/common';
import { ShopifyOrdersService } from './shopify-orders.service';


@Controller('webhooks')
export class ShopifyOrdersController {
    public constructor(
        private readonly shopifyOrdersService: ShopifyOrdersService
    ) {}

    @Get('orders')
    getHello(): any {
        return this.shopifyOrdersService.ShopifyApiCalls();
    }


}

shopify-orders.module.ts

import { Module } from '@nestjs/common';
import { ShopifyOrdersController } from './shopify-orders.controller';
import { ShopifyOrdersService } from './shopify-orders.service';
import { ApiCallsModule } from '../api-calls/api-calls.module'

@Module({
  imports: [
    ApiCallsModule
  ],
  controllers: [ShopifyOrdersController],
  providers: [ShopifyOrdersService]
})
export class ShopifyOrdersModule {}

i dont know what i am missing, thanks

1 Answers

You are using KOA middlewares but my answer will be without koa hope it helps.

1. Install shopify module for node

   npm install --save shopify-api-node

2. First Creation Of Webhook

shopify.service.ts

    const shopify = new Shopify({
       shopName: shop_name,
       accessToken: access_token,
    });
    
    // Create Webhook
    await shopify.webhook.create({
      topic: 'YOUR_WEBHOOK_EVENT',
      format: 'json',
      address: 'YOUR_URL_FOR_WEBHOOK',
      });

3. Receving Webhooks

3.1 In you main.ts use the bodyparser like this

   app.use(
     json({
     verify: (req: any, res, buf, encoding) => {
   
     if (req.headers['x-shopify-hmac-sha256']) {
       req.rawBody = buf.toString(encoding || 'utf8');
     }
    return true;
  },
}),

);

3.2 In your controller

   import * as crypto from 'crypto';

   @Post('YOUR_WEBHOOK_URL')
   async webhookHandle(@Req() req: any) {
   const hmacHeader = req.get('X-Shopify-Hmac-Sha256');
   const hash = crypto.createHmac(
    'sha256',
    'SHOPIFY_API_SECRET',
   ).update(req.rawBody).digest('base64');
   if (hash === hmacHeader) {
   console.log('Notification Requested from Shopify received');
   } else {
   console.log('There is something wrong with this webhook');
   }
  }

Your will start receiving the webhooks.

Related