abcdefgh

<pre> Here is my E2E test class.</pre> <p>&nbsp;</p> <pre> import {Test} from &#39;@nestjs/testing&#39;; import {ModuleMocker, MockFunctionMetadata} from &#39;jest-mock&#39;; import axios from &#39;axios&#39;; import {ConfigService} from &#39;@nestjs/config&#39;; import {ProcessfulfillmentHelper} from &#39;./processfulfillment-helper&#39;; import ProcessService from &#39;../src/process/process.service&#39;; import AxiosUtil from &#39;../src/applib/util/axios.util&#39;; import {HttpException} from &quot;@nestjs/common&quot;; const moduleMocker = new ModuleMocker(global); jest.setTimeout(10000); jest.mock(&#39;axios&#39;, () =&gt; ({ default: { create: jest.fn(() =&gt; axios), post: jest.fn((url, headers) =&gt; { let response; const experienceApiResponse = ProcessfulfillmentHelper.getExperienceApiResponse(headers.case); if (url === &#39;https://sit2www.cvsspecialty.com/apims/client/experience/v1/load&#39; &amp;&amp; !headers.isExpired) { response = experienceApiResponse; } else if (url === &#39;https://sit2www.cvsspecialty.com/apims/client/experience/v1/load&#39; &amp;&amp; headers.isExpired) { return Promise.reject({message: &quot;401 unauthorized&quot;}); } return Promise.resolve(response); }), }, // post: jest.fn(() =&gt; Promise.resolve({ data: ProcessfulfillmentHelper.cacheSavingsResponseFromAxios() })), put: () =&gt; new Promise(() =&gt; { }), delete: () =&gt; new Promise(() =&gt; { }), })); describe(&#39;Get process fulfillment&#39;, () =&gt; { let processService: ProcessService; beforeEach(async () =&gt; { const moduleRef = await Test.createTestingModule({ providers: [ProcessService], }) .useMocker((token) =&gt; { if (token === AxiosUtil) { return { getInstance: jest.fn(() =&gt; { return { post: (url, payload, headers) =&gt; { const experienceApiResponse = ProcessfulfillmentHelper.getExperienceApiResponse(headers.headers.case); if (url === &#39;https://sit2www.cvsspecialty.com/apims/client/experience/v1/load&#39; &amp;&amp; !headers?.headers?.isExpired) { return Promise.resolve(experienceApiResponse); } else if (url === &#39;https://digital-retail-rx-qa.internal.cvshealth.com/microservices/bff-rest/bff/v1/loadExperience&#39; &amp;&amp; !headers?.headers?.isExpired) { return Promise.resolve(experienceApiResponse); } else if (url === &#39;https://sit2www.cvsspecialty.com/apims/client/experience/v1/load&#39; &amp;&amp; headers?.headers?.isExpired) { throw new HttpException(&quot;UnAuthorized&quot;, 401); } else if (url === &#39;https://digital-retail-rx-qa.internal.cvshealth.com/microservices/bff-rest/bff/v1/loadExperience&#39; &amp;&amp; headers?.headers?.isExpired) { throw new HttpException(&quot;UnAuthorized&quot;, 401); } }, }; }), } } if (token === ConfigService) { return { get: (key) =&gt; { let value; switch (key) { case &#39;Agents&#39;: value = ProcessfulfillmentHelper.getAgentConfig(); break; } return value; }, }; } if (typeof token === &#39;function&#39;) { const mockMetadata = moduleMocker.getMetadata(token) as MockFunctionMetadata&lt;any, any&gt;; const Mock = moduleMocker.generateFromMetadata(mockMetadata); return new Mock(); } return null; }) .compile(); processService = moduleRef.get(ProcessService); }); describe(&#39;get process fulfillment service&#39;, () =&gt; { it(&#39;calling experienceapi method test for refills&#39;, async () =&gt; { const intentRequestModel = ProcessfulfillmentHelper.getProcessFulfillmentRequest(&#39;refills&#39;); const {agentName} = intentRequestModel; const {intentName} = intentRequestModel; const headers = { &#39;x-grid&#39;: &#39;11223344&#39;, &#39;content-type&#39;: &#39;application/json&#39;, authorization: &#39;Bearer eyJraWQiOiI4ZWEwZWEzYy1lMmU1LTQxNjgtYWRhNC1hMmZiNWZkYmZjNzgiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJyc2FkZHJlc3MxQGdtYWlsLmNvbSIsImF1ZCI6ImFwaS5jdnNoZWFsdGguY29tIiwieC1jbGllbnQtaWQiOiJmQ1I5QTl2ekp5ZnNDS0JZazN4dkduWjNiSzlBN2hEcSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJpc3MiOiJhcGkuY3Zzc3BlY2lhbHR5LmNvbSIsIngtbWVtYmVyLXRva2VuIjoiN2I0MDYyYzljMWU1NGNlZWFjZTlhMWIwNDA1YWY1ZTVjOTQ0ZWM3NGE3NjU0ZTIxODdjYzY4NTgzN2ZjMmQ4NCIsIngtbG9iIjoiU3BlY2lhbHR5IiwieC1ncmlkIjoicnJ0LTY1MzgwNjQ2NjI5NjI5NTEwNjMtYS1nd28xLTcyMTUtMTY5NTg2MjA2LTIiLCJ4LWNvbnRleHQtdHlwZSI6ImxvZ2luVG9rZW5DYWNoZSIsImV4cCI6MTY5NTkxNDI4NSwiaWF0IjoxNjk1OTEzNjg1LCJqdGkiOiI5OGZlM2Q1My0xYjI0LTQ0YzItYWYwMy01MTFjYzFmMTZkY2YifQ.VziaVRLD5rsBbZjlPqWfOsu0sNWBl0ujOkSEt4H5CL8hL9DdiNAnT5TK7t1hJKb70r3AxPrXDELhX6ozmX05Gz8n3FIAKFk2ridgZrn9CYz5A2taAFXgOmRY1zdF7urizZr5Mx_Nw10UxxdG-Ae7AZ52u561Y9hUl0d7C8S_Qw09N3v7ogp2eE_EDXSapV82hgZIQkK-AE7Xn0ooC2NS_PlH90ZreiY_wtoJLmor-fqVgMs4RAOpl4CSYh5JUNVP-aTUNtDrKdoTWAFsBfOBBVvKD2jZQN4_tluW27t0pyMd-eYcrnVQhZ6Vw3Hsy8k-szNBjlS4icrHj1_iJVnTvw&#39;, &#39;user-agent&#39;: &#39;PostmanRuntime/7.28.4&#39;, accept: &#39;*/*&#39;, &#39;postman-token&#39;: &#39;d815d09b-853c-49e1-9e5c-053c661fd919&#39;, host: &#39;localhost:21120&#39;, &#39;accept-encoding&#39;: &#39;gzip, deflate, br&#39;, connection: &#39;keep-alive&#39;, &#39;content-length&#39;: &#39;18893&#39;, isExpired: false, case: &#39;refills&#39; }; const jsonDataResult = ProcessfulfillmentHelper.getJsonDataResult(headers.case); const experienceApiResponseActual = await processService.callExperienceApi( agentName, intentName, headers, jsonDataResult, ); const experienceApiResponse = ProcessfulfillmentHelper.getExperienceApiResponse(headers.case); expect(JSON.stringify(experienceApiResponseActual)).toStrictEqual(JSON.stringify(experienceApiResponse)); }); it(&#39;calling experienceapi method test for questions&#39;, async () =&gt; { const intentRequestModel = ProcessfulfillmentHelper.getProcessFulfillmentRequest(&#39;questions&#39;); const {agentName} = intentRequestModel; const {intentName} = intentRequestModel; const headers = { &#39;x-grid&#39;: &#39;11223344&#39;, &#39;content-type&#39;: &#39;application/json&#39;, authorization: &#39;Bearer eyJraWQiOiI4ZWEwZWEzYy1lMmU1LTQxNjgtYWRhNC1hMmZiNWZkYmZjNzgiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJyc2FkZHJlc3MxQGdtYWlsLmNvbSIsImF1ZCI6ImFwaS5jdnNoZWFsdGguY29tIiwieC1jbGllbnQtaWQiOiJmQ1I5QTl2ekp5ZnNDS0JZazN4dkduWjNiSzlBN2hEcSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJpc3MiOiJhcGkuY3Zzc3BlY2lhbHR5LmNvbSIsIngtbWVtYmVyLXRva2VuIjoiN2I0MDYyYzljMWU1NGNlZWFjZTlhMWIwNDA1YWY1ZTVjOTQ0ZWM3NGE3NjU0ZTIxODdjYzY4NTgzN2ZjMmQ4NCIsIngtbG9iIjoiU3BlY2lhbHR5IiwieC1ncmlkIjoicnJ0LTY1MzgwNjQ2NjI5NjI5NTEwNjMtYS1nd28xLTcyMTUtMTY5NTg2MjA2LTIiLCJ4LWNvbnRleHQtdHlwZSI6ImxvZ2luVG9rZW5DYWNoZSIsImV4cCI6MTY5NTkxNDI4NSwiaWF0IjoxNjk1OTEzNjg1LCJqdGkiOiI5OGZlM2Q1My0xYjI0LTQ0YzItYWYwMy01MTFjYzFmMTZkY2YifQ.VziaVRLD5rsBbZjlPqWfOsu0sNWBl0ujOkSEt4H5CL8hL9DdiNAnT5TK7t1hJKb70r3AxPrXDELhX6ozmX05Gz8n3FIAKFk2ridgZrn9CYz5A2taAFXgOmRY1zdF7urizZr5Mx_Nw10UxxdG-Ae7AZ52u561Y9hUl0d7C8S_Qw09N3v7ogp2eE_EDXSapV82hgZIQkK-AE7Xn0ooC2NS_PlH90ZreiY_wtoJLmor-fqVgMs4RAOpl4CSYh5JUNVP-aTUNtDrKdoTWAFsBfOBBVvKD2jZQN4_tluW27t0pyMd-eYcrnVQhZ6Vw3Hsy8k-szNBjlS4icrHj1_iJVnTvw&#39;, &#39;user-agent&#39;: &#39;PostmanRuntime/7.28.4&#39;, accept: &#39;*/*&#39;, &#39;postman-token&#39;: &#39;d815d09b-853c-49e1-9e5c-053c661fd919&#39;, host: &#39;localhost:21120&#39;, &#39;accept-encoding&#39;: &#39;gzip, deflate, br&#39;, connection: &#39;keep-alive&#39;, &#39;content-length&#39;: &#39;18893&#39;, isExpired: false, case: &#39;questions&#39; }; const jsonDataResult = ProcessfulfillmentHelper.getJsonDataResult(headers.case); const experienceApiResponseActual = await processService.callExperienceApi( agentName, intentName, headers, jsonDataResult, ); const experienceApiResponse = ProcessfulfillmentHelper.getExperienceApiResponse(headers.case); expect(JSON.stringify(experienceApiResponseActual)).toStrictEqual(JSON.stringify(experienceApiResponse)); }); it(&#39;calling experienceapi refills method test with expired token&#39;, async () =&gt; { const intentRequestModel = ProcessfulfillmentHelper.getProcessFulfillmentRequest(&#39;refills&#39;); const {agentName} = intentRequestModel; const {intentName} = intentRequestModel; const headers = { &#39;x-grid&#39;: &#39;11223344&#39;, &#39;content-type&#39;: &#39;application/json&#39;, authorization: &#39;Bearer eyJraWQiOiI4ZWEwZWEzYy1lMmU1LTQxNjgtYWRhNC1hMmZiNWZkYmZjNzgiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJyc2FkZHJlc3MxQGdtYWlsLmNvbSIsImF1ZCI6ImFwaS5jdnNoZWFsdGguY29tIiwieC1jbGllbnQtaWQiOiJmQ1I5QTl2ekp5ZnNDS0JZazN4dkduWjNiSzlBN2hEcSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJpc3MiOiJhcGkuY3Zzc3BlY2lhbHR5LmNvbSIsIngtbWVtYmVyLXRva2VuIjoiN2I0MDYyYzljMWU1NGNlZWFjZTlhMWIwNDA1YWY1ZTVjOTQ0ZWM3NGE3NjU0ZTIxODdjYzY4NTgzN2ZjMmQ4NCIsIngtbG9iIjoiU3BlY2lhbHR5IiwieC1ncmlkIjoicnJ0LTY1MzgwNjQ2NjI5NjI5NTEwNjMtYS1nd28xLTcyMTUtMTY5NTg2MjA2LTIiLCJ4LWNvbnRleHQtdHlwZSI6ImxvZ2luVG9rZW5DYWNoZSIsImV4cCI6MTY5NTkxNDI4NSwiaWF0IjoxNjk1OTEzNjg1LCJqdGkiOiI5OGZlM2Q1My0xYjI0LTQ0YzItYWYwMy01MTFjYzFmMTZkY2YifQ.VziaVRLD5rsBbZjlPqWfOsu0sNWBl0ujOkSEt4H5CL8hL9DdiNAnT5TK7t1hJKb70r3AxPrXDELhX6ozmX05Gz8n3FIAKFk2ridgZrn9CYz5A2taAFXgOmRY1zdF7urizZr5Mx_Nw10UxxdG-Ae7AZ52u561Y9hUl0d7C8S_Qw09N3v7ogp2eE_EDXSapV82hgZIQkK-AE7Xn0ooC2NS_PlH90ZreiY_wtoJLmor-fqVgMs4RAOpl4CSYh5JUNVP-aTUNtDrKdoTWAFsBfOBBVvKD2jZQN4_tluW27t0pyMd-eYcrnVQhZ6Vw3Hsy8k-szNBjlS4icrHj1_iJVnTvw&#39;, &#39;user-agent&#39;: &#39;PostmanRuntime/7.28.4&#39;, accept: &#39;*/*&#39;, &#39;postman-token&#39;: &#39;d815d09b-853c-49e1-9e5c-053c661fd919&#39;, host: &#39;localhost:21120&#39;, &#39;accept-encoding&#39;: &#39;gzip, deflate, br&#39;, connection: &#39;keep-alive&#39;, &#39;content-length&#39;: &#39;18893&#39;, isExpired: true, case: &#39;refills&#39; }; const jsonDataResult = ProcessfulfillmentHelper.getJsonDataResult(headers.case); try { await processService.callExperienceApi( agentName, intentName, headers, jsonDataResult, ); } catch (e) { expect(e.status).toBe(401); } }); it(&#39;calling experienceapi questions method test with expired token&#39;, async () =&gt; { const intentRequestModel = ProcessfulfillmentHelper.getProcessFulfillmentRequest(&#39;questions&#39;); const {agentName} = intentRequestModel; const {intentName} = intentRequestModel; const headers = { &#39;x-grid&#39;: &#39;11223344&#39;, &#39;content-type&#39;: &#39;application/json&#39;, authorization: &#39;Bearer eyJraWQiOiI4ZWEwZWEzYy1lMmU1LTQxNjgtYWRhNC1hMmZiNWZkYmZjNzgiLCJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJyc2FkZHJlc3MxQGdtYWlsLmNvbSIsImF1ZCI6ImFwaS5jdnNoZWFsdGguY29tIiwieC1jbGllbnQtaWQiOiJmQ1I5QTl2ekp5ZnNDS0JZazN4dkduWjNiSzlBN2hEcSIsInNjb3BlIjoib3BlbmlkIHByb2ZpbGUgZW1haWwiLCJpc3MiOiJhcGkuY3Zzc3BlY2lhbHR5LmNvbSIsIngtbWVtYmVyLXRva2VuIjoiN2I0MDYyYzljMWU1NGNlZWFjZTlhMWIwNDA1YWY1ZTVjOTQ0ZWM3NGE3NjU0ZTIxODdjYzY4NTgzN2ZjMmQ4NCIsIngtbG9iIjoiU3BlY2lhbHR5IiwieC1ncmlkIjoicnJ0LTY1MzgwNjQ2NjI5NjI5NTEwNjMtYS1nd28xLTcyMTUtMTY5NTg2MjA2LTIiLCJ4LWNvbnRleHQtdHlwZSI6ImxvZ2luVG9rZW5DYWNoZSIsImV4cCI6MTY5NTkxNDI4NSwiaWF0IjoxNjk1OTEzNjg1LCJqdGkiOiI5OGZlM2Q1My0xYjI0LTQ0YzItYWYwMy01MTFjYzFmMTZkY2YifQ.VziaVRLD5rsBbZjlPqWfOsu0sNWBl0ujOkSEt4H5CL8hL9DdiNAnT5TK7t1hJKb70r3AxPrXDELhX6ozmX05Gz8n3FIAKFk2ridgZrn9CYz5A2taAFXgOmRY1zdF7urizZr5Mx_Nw10UxxdG-Ae7AZ52u561Y9hUl0d7C8S_Qw09N3v7ogp2eE_EDXSapV82hgZIQkK-AE7Xn0ooC2NS_PlH90ZreiY_wtoJLmor-fqVgMs4RAOpl4CSYh5JUNVP-aTUNtDrKdoTWAFsBfOBBVvKD2jZQN4_tluW27t0pyMd-eYcrnVQhZ6Vw3Hsy8k-szNBjlS4icrHj1_iJVnTvw&#39;, &#39;user-agent&#39;: &#39;PostmanRuntime/7.28.4&#39;, accept: &#39;*/*&#39;, &#39;postman-token&#39;: &#39;d815d09b-853c-49e1-9e5c-053c661fd919&#39;, host: &#39;localhost:21120&#39;, &#39;accept-encoding&#39;: &#39;gzip, deflate, br&#39;, connection: &#39;keep-alive&#39;, &#39;content-length&#39;: &#39;18893&#39;, isExpired: true, case: &#39;questions&#39; }; const jsonDataResult = ProcessfulfillmentHelper.getJsonDataResult(headers.case); try { await processService.callExperienceApi( agentName, intentName, headers, jsonDataResult, ); } catch (e) { expect(e.status).toBe(401); } }); }); });</pre> <p>&nbsp;</p> <p>Here is my controller</p> <p>&nbsp;</p> <pre> import {Body, Controller, HttpCode,HttpException, Logger, Post, Req} from &#39;@nestjs/common&#39;; import { ApiOperation, ApiParam, ApiResponse, ApiTags } from &#39;@nestjs/swagger&#39;; import { Request } from &#39;express&#39;; import ProcessService from &#39;./process.service&#39;; import { IntentRequestModel } from &#39;./model/IntentRequest.model&#39;; import CryptoUtil from &#39;../applib/util/crypto.util&#39;; import {IntentRequestCustomValidator} from &quot;./model/custom-validator/intent-req-validator&quot;; import { ConfigService } from &quot;@nestjs/config&quot;; import {IntentRequestModelV2} from &quot;./model/IntentRequestV2.model&quot;; import {IntentRequestCustomValidatorV2} from &quot;./model/custom-validator/intent-req-validator-v2&quot;; /** * Fulfillment Process Controller */ @Controller(&#39;/microservices/chat-fulfillment/process&#39;) @ApiTags(&#39;process&#39;) export default class ProcessController { /** * Construction * @param processService - Process Service */ private readonly encryptkey: string; constructor(private readonly processService: ProcessService, private readonly cryptoUtil: CryptoUtil, private readonly configService: ConfigService) { this.encryptkey = this.configService.get&lt;string&gt;(&#39;info.app.encrypt-key&#39;); } @HttpCode(200) @Post(&#39;/v1/processFulfillment&#39;) @ApiOperation({ summary: &#39;Process Fulfillment&#39; }) @ApiResponse({ status: 200, description: &#39;Process Fulfillment Successfully&#39;, }) async processFulfillment(@Req() request: Request, @IntentRequestCustomValidator() @Body() intentRequestModel: IntentRequestModel) { const { agentName, intentName } = intentRequestModel; new Logger().log(`starting process fulfillment request for ${intentName} with payload: `, JSON.stringify(intentRequestModel)); let experienceResult = {}; let jsonDataResult = {}; jsonDataResult = await this.processService.processJsonData(intentRequestModel.jsonData, intentName); if (this.requiresExpCall(agentName, intentName)) { experienceResult = await this.processService.callExperienceApi( agentName, intentName, request.headers, jsonDataResult, ); if (experienceResult[&#39;error&#39;]) { throw new HttpException(experienceResult[&#39;error&#39;], experienceResult[&#39;error&#39;].status); } } return { status: &#39;success&#39;, experienceResult , }; } @HttpCode(200) @Post(&#39;/v2/processFulfillment&#39;) @ApiOperation({ summary: &#39;Process Fulfillment&#39; }) @ApiResponse({ status: 200, description: &#39;Process Fulfillment Successfully&#39;, }) async processV2Fulfillment(@Req() request: Request, @IntentRequestCustomValidatorV2() @Body() intentRequestModel: IntentRequestModelV2) { const { agentName,intentName,jsonData,conversationId } = intentRequestModel; new Logger().log(`starting process fulfillment request for ${intentName} with payload: `, JSON.stringify(intentRequestModel)); let experienceResult = {}; let jsonDataResult = {}; await this.processService.handleCacheLogic(agentName,intentName,conversationId,jsonData); jsonDataResult = await this.processService.processJsonData(intentRequestModel.jsonData, intentName); if (this.requiresExpCall(agentName, intentName)) { experienceResult = await this.processService.callExperienceApi( agentName, intentName, request.headers, jsonDataResult, ); if (experienceResult[&#39;error&#39;]) { throw new HttpException(experienceResult[&#39;error&#39;], experienceResult[&#39;error&#39;].status); } } return { status: &#39;success&#39;, experienceResult , }; } private requiresExpCall(agentName: string, intentName: string): boolean { const agentConfig = this.processService.getAgentConfig(agentName); return Boolean(agentConfig.Intents[intentName].serviceUrl); } } </pre> <p>Here is my service clsaa</p> <pre> import { HttpException, HttpStatus, Injectable, Logger, NotFoundException } from &#39;@nestjs/common&#39;; import { HttpService } from &#39;@nestjs/axios&#39;; import UtilService from &#39;src/common/utility/common.util&#39;; import { ConfigService } from &#39;@nestjs/config&#39;; import AxiosUtil from &#39;../applib/util/axios.util&#39;; import CryptoUtil from &#39;../applib/util/crypto.util&#39;; @Injectable() export default class ProcessService { private agentsConfig: any; private readonly encryptkey: string; private readonly getCacheUrl: string; private readonly setCacheUrl: string; private readonly purgeCacheUrl: string; constructor( private readonly axiosUtil: AxiosUtil, private readonly cryptoUtil: CryptoUtil, private http: HttpService, private utilService: UtilService, private readonly configService: ConfigService, ) { this.agentsConfig = this.configService.get&lt;any[]&gt;(&#39;Agents&#39;); this.encryptkey = this.configService.get&lt;string&gt;(&#39;info.app.encrypt-key&#39;); this.getCacheUrl = this.configService.get&lt;string&gt;(&#39;info.app.services.cacheservice.get.url&#39;); this.setCacheUrl = this.configService.get&lt;string&gt;(&#39;info.app.services.cacheservice.set.url&#39;); this.purgeCacheUrl = this.configService.get&lt;string&gt;(&#39;info.app.services.cacheservice.purge.url&#39;); } private deepCopy(obj:any) { return JSON.parse(JSON.stringify(obj)); } getAgentConfig(agentName: string): any { return this.agentsConfig.find((agent) =&gt; agent.name === agentName); } getStartEndDate(numberofdays: number): any { let startDate = this.utilService.getFormatedData(new Date().setDate(new Date().getDate() - numberofdays)); let endDate = this.utilService.getFormatedData(new Date()); return {startDate,endDate}; } getIntentPayload(agentName: string, intentName: string) : any{ const agentConfig = this.getAgentConfig(agentName); const intentConfig = agentConfig.Intents[intentName]; return this.deepCopy({ ...intentConfig.request }); } getIntentConfig(agentName: string, intentName: string) : any{ const agentConfig = this.getAgentConfig(agentName); const intentConfig = agentConfig.Intents[intentName]; return this.deepCopy({ ...intentConfig }); } async callExperienceApi(agentName: string, intentName: string, headers: any, processedData: any): Promise&lt;any&gt; { new Logger().log(&quot;start calling experience API&quot;); const agentConfig = this.getAgentConfig(agentName); const intentConfig = agentConfig.Intents[intentName]; const apiUrl = intentConfig.serviceUrl; const intentHeaders = intentConfig.headers || {}; headers = { ...intentHeaders, ...headers }; const headersToExclude = [&#39;content-length&#39;, &#39;host&#39;]; for (const header of headersToExclude) { delete headers[header]; } let payload = this.deepCopy({ ...intentConfig.request }); const replacePlaceholders = (obj: any, parent: any = null, keyInParent: any = null, actionData: any = null) =&gt; { for (const key in obj) { if (obj.hasOwnProperty(key)) { const value = obj[key]; if (key === &#39;fillMethod&#39;) continue; if (key === &#39;items&#39;) { let allItems = []; // Extract intent from placeholder and get actionDataArray value.forEach((v)=&gt;{ const intent = extractIntent(v); const actionDataArray = getActionData(intent, intentName); // Check the fillMethod of the parent object const fillMethod = obj.fillMethod || &#39;latest&#39;; if (fillMethod === &#39;all&#39;) { const newItems= actionDataArray.map((actionData) =&gt; { let newItem = JSON.parse(JSON.stringify(v)); replacePlaceholders(newItem, null, null, actionData); return newItem; }); allItems = allItems.concat(newItems) } else { const latestActionData = getLatestActionData(intent, intentName); const newItem = JSON.parse(JSON.stringify(v)); replacePlaceholders(newItem, null, null, latestActionData); allItems.push(newItem) } }); parent[keyInParent] = allItems; continue; } if (typeof value === &#39;string&#39; &amp;&amp; value.startsWith(&#39;$&#39;)) { const [intent, field] = value.substr(1).split(&#39;.&#39;); if(actionData &amp;&amp; actionData[&#39;IntentName&#39;] === intent) { const fieldValue = actionData[field]; obj[key] = (fieldValue!== undefined &amp;&amp; fieldValue!==null) ? fieldValue : null; } else { const latestActionData = getLatestActionData(intent, intentName); const fieldValue = latestActionData[field]; obj[key] = (fieldValue!== undefined &amp;&amp; fieldValue!==null) ? fieldValue : null; } } else if (Array.isArray(value) || typeof value === &#39;object&#39;) { replacePlaceholders(value, obj, key, actionData); } if(obj.enableStartEndDate === &#39;true&#39;){ Object.assign(obj.data,this.getStartEndDate(intentConfig.numberOfDays)) delete obj.enableStartEndDate; } } } }; const extractIntent = (item: any) =&gt; { for (const key in item) { if (typeof item[key] === &quot;string&quot; &amp;&amp; item[key].startsWith(&quot;$&quot;)) { return item[key].substr(1).split(&quot;.&quot;)[0]; } else if (Array.isArray(item[key]) || typeof item[key] === &quot;object&quot;) { return extractIntent(item[key]); } } }; const getActionData = (intent: string,intentName: string) =&gt; { return processedData[intentName]?.userActions[intent] || processedData[intent]?.userActions[intent] || []; }; const getLatestActionData = (intent: string, intentName: string) =&gt; { const actionsData = getActionData(intent, intentName); if (actionsData.length === 0) { return {}; } return actionsData.reduce( (prev, current) =&gt; (parseInt(prev.seqNum) &gt; parseInt(current.seqNum) ? prev : current), {}, ); }; // Replace Placeholders replacePlaceholders(payload); new Logger().log(payload); new Logger().log(headers); const response = await this.postService(headers, apiUrl, payload); const processElements = async (elements: any) =&gt; { for (const element of elements) { if (element.encParams &amp;&amp; typeof element.encParams === &#39;object&#39;) { // Convert the encParams object to a JSON string and encrypt it const encryptedData = await this.encrypt(element.encParams); // Replace the encData value in the action URL with the encrypted string if(element.objectType === &#39;form&#39;) { if (element.submitButton &amp;&amp; typeof element.submitButton === &#39;object&#39;) { element.submitButton.action = element.submitButton.action.replace(/metadata=/, `metadata=${encodeURIComponent(encryptedData)}`); } } if(element.action) { element.action = element.action.replace(/metadata=/, `metadata=${encodeURIComponent(encryptedData)}`); } // Remove the encParams object delete element.encParams; } if (element.elements &amp;&amp; element.elements.length &gt; 0) { await processElements(element.elements) } } }; // Encrypt the response if (response &amp;&amp; response.contents &amp;&amp; response.contents.intent &amp;&amp; response.contents.intent.content &amp;&amp; response.contents.intent.content.elements) { const elements = response.contents.intent.content.elements; await processElements(elements); } return response; } public async postService(headers: any, URI: string, payload: any): Promise&lt;any&gt; { console.log(&#39;url&#39;, URI); new Logger().log(&#39;url&#39;, URI); let response = null; try { response = await this.axiosUtil.getInstance().post(URI, payload, { headers }); new Logger().log(&quot;executed post service with response: &quot;, JSON.stringify(response)); return response; } catch (error) { new Logger().log(error.message); return {error: {...error, noModifyError: true}}; } } async cacheActions(actions, agentName, conversationID) { const cacheKey = `${agentName}-${conversationID}-actions`; const cacheValue = JSON.stringify(actions); // Construct the payload for the cache service const cachePayload = { requestMetaData: { appName: &quot;CVS_APP&quot;, lineOfBusiness: &quot;Retail&quot;, conversationID: conversationID }, requestPayloadData: { data: { context: &quot;chatfulfillment&quot;, data: [{ key: cacheKey, value: cacheValue }] } } }; const cacheHeaders = { &#39;Content-Type&#39;: &#39;application/json&#39;, }; await this.postService(cacheHeaders, this.setCacheUrl, cachePayload); } async retrieveCachedActions(agentName, conversationID) { const cacheKey = `${agentName}-${conversationID}-actions`; const cachePayload = { requestMetaData: { appName: &quot;CVS_APP&quot;, lineOfBusiness: &quot;Retail&quot;, conversationID: conversationID }, requestPayloadData: { data: { context: &quot;chatfulfillment&quot;, data: [{ key: cacheKey }] } } }; const cacheHeaders = { &#39;Content-Type&#39;: &#39;application/json&#39;, }; try { const response = await this.postService(cacheHeaders, this.getCacheUrl, cachePayload) if (response.responseMetaData &amp;&amp; response.responseMetaData.statusCode==&#39;0000&#39;) { return JSON.parse(response.responsePayloadData.data.map(item =&gt; item.value).filter(v =&gt; v)); } else { return []; } } catch (error) { new Logger().error(`Error retrieving cached actions: ${error}`); return []; // Return an empty array if there&#39;s an error } } async purgeCache(agentName, conversationId) { // Construct the key for cache purging const cacheKey = `${agentName}-${conversationId}-actions`; const headers = { }; const purgeUrl = `${this.purgeCacheUrl}${encodeURIComponent(cacheKey)}`; try { await this.axiosUtil.getInstance().get(purgeUrl, { headers }); new Logger().log(&#39;Cache successfully purged&#39;); } catch (error) { new Logger().error(`Error purging cache: ${error}`); } } public async encrypt(data: string): Promise&lt;string&gt; { const dataToEncryptString = JSON.stringify(data); const encryptedData = await this.cryptoUtil.encrypt(dataToEncryptString,this.encryptkey); new Logger().log(encryptedData); //TODO Revist the decrypt logic const decryptedData = await this.cryptoUtil.decrypt( encryptedData,this.encryptkey); new Logger().log(decryptedData); new Logger().log(&#39;Decrypted Data:&#39;); if (typeof decryptedData === &#39;string&#39;) { const parsedData = JSON.parse(decryptedData); if (typeof parsedData === &#39;object&#39;) { new Logger().log(&#39;Decrypted Data:&#39;); for (const prop in parsedData) { if (parsedData.hasOwnProperty(prop)) { new Logger().log(`${prop}: ${parsedData[prop]}`); } } } else { new Logger().log(&#39;Decrypted Data is not an object.&#39;); } } else { new Logger().log(&#39;Decrypted Data is not a string.&#39;); } return encryptedData; } public async processJsonData(jsonData: any[], intent: string): Promise&lt;any&gt; { new Logger().log(&quot;start processing jsondata: &quot;, JSON.stringify(jsonData)); const resultMap = {}; for (const data of jsonData) { const index: number = jsonData.indexOf(data); const messagesDisplayed: string[] = []; const optionsDisplayed: string[] = []; const userActions = data.actions || []; for (let actionIndex = 0; actionIndex &lt; userActions.length; actionIndex++) { const action = userActions[actionIndex]; if (action.metadata) { try { let decryptedData = await this.cryptoUtil.decrypt(action.metadata, this.encryptkey); if (typeof decryptedData === &#39;string&#39;) { const parsedData = JSON.parse(decryptedData); if (typeof parsedData === &#39;object&#39;) { // Merge parsedData into the original action object data.actions[actionIndex] = {...action, ...parsedData}; } else { new Logger().log(&#39;Decrypted Data is not an object.&#39;); } } else { new Logger().log(&#39;Decrypted Data is not a string.&#39;); } } catch (error) { console.error(&#39;Decryption error:&#39;, error); } } } // Grouping actions by IntentName const actionsByIntent = data.actions.reduce((acc: any, action: any) =&gt; { const intentName = action.IntentName; if (!acc[intentName]) acc[intentName] = []; acc[intentName].push(action); return acc; }, {}); const key = `${intent}`; resultMap[key] = { intent, messagesDisplayed, optionsDisplayed, userActions: actionsByIntent, }; } return resultMap; } async handleCacheLogic(agentName, intentName, conversationId, jsonData) { const payload = this.getIntentConfig(agentName, intentName); // Purge the cache if the resetcache is true if (payload &amp;&amp; payload.resetcache) { await this.purgeCache(agentName, conversationId); } // Retrieve and prepend cached actions if resetcache is not true if (payload &amp;&amp; !payload.resetcache &amp;&amp; jsonData &amp;&amp; jsonData[0] &amp;&amp; jsonData[0].actions) { const cachedActions = await this.retrieveCachedActions(agentName, conversationId); if (cachedActions.length &gt; 0) { jsonData[0].actions = [...cachedActions, ...jsonData[0].actions]; } } if (jsonData &amp;&amp; jsonData[0] &amp;&amp; jsonData[0].actions) { if (jsonData[0].actions.length &gt; 0) await this.cacheActions(jsonData[0].actions, agentName, conversationId); } } } </pre> <p>&nbsp;</p> <p>What changes needs to be done to fix&nbsp;</p> <p>&nbsp; ● Chat fulfillment &rsaquo; get process fullfillment for question intent</p> <p>&nbsp; &nbsp; TypeError: this.processService.processJsonData is not a function</p> <p>&nbsp;</p>