createWebhookTransformer({ /** * This transformer is executed when receiving a message * from the user, before executing the Flow. * * @param endpoint The configuration object for the used Endpoint. * @param request The Express request object with a JSON parsed body. * @param response The Express response object. * * @returns A valid userId, sessionId, as well as text and/or data, * which has been extracted from the request body. */ handleInput: async ({ endpoint, request, response }) => { console.log(request.body); /** * Extract the userId, sessionId and text * from the request. Example: * * const { userId, sessionId, text, data } = request.body; * * Note that the format of the request body will be different for * every Endpoint, and the example above needs to be adjusted * accordingly. */ const userId = request.body.from.aadObjectId; const sessionId = request.body.from.id; const data = {} console.log('user id = ' + userId) console.log('session id = ' + sessionId) let text = request.body.text const sessionStorage = await getSessionStorage(userId, sessionId); if (sessionStorage.hasOwnProperty("chatHistory")) { console.log(sessionStorage.sessionId) sessionStorage.chatHistory += "\nUser: " + text; } else { console.log(sessionStorage.sessionId) sessionStorage.chatHistory = "User: " + text; } if (sessionStorage.cognigyState == "OPENAGENT" || sessionStorage.cognigyState == "OPENBOT") { console.log("Redirecting to ServiceNow"); let body = { "token": sessionStorage.serviceNowAPIToken, "requestId": sessionStorage.cognigyInputId, "action": null, "enterpriseId": "Cognigy", "clientSessionId": sessionId, "botToBot": true, "clientVariables": { "cognigyState": sessionStorage.cognigyState, "cognigyInputId": sessionStorage.cognigyInputId, "cognigyUserId": sessionStorage.cognigyUserId }, "message": { "text": text, "typed": true, "clientMessageId": sessionStorage.cognigyInputId }, "userId": sessionStorage.userId, "emailId": sessionStorage.emailId, "timezone": sessionStorage.timezone } if (text?.toLowerCase() == sessionStorage.quitPhrase?.toLowerCase()) { body.action = "END_CONVERSATION"; body.message.text = ""; body.clientVariables.cognigyState = "CLOSED"; sessionStorage.cognigyState = "CLOSED"; } try { const result = await httpRequest({ uri: sessionStorage.serviceNowInstanceURL + "/api/sn_va_as_service/bot/integration", method: "POST", headers: { 'Authorization': sessionStorage.authorization, 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: body, json: true }); return null; } catch (e) { text = "Cannot connect to ServiceNow. Check connection details in Start_Conversation node ...\n" + e.message; } } return { userId, sessionId, text, data }; }, /** * This transformer is executed on every output from the Flow. * For Webhook based transformers, the return value of this transformer * will be sent directly to the user. * * @param processedOutput The output from the Flow that has been processed into the final object * that will be sent to the user. It is structured according to the data structure used * on the specific Endpoint channel. * * @param output The raw output from the Flow. * @param endpoint The configuration object for the used Endpoint. * @param userId The unique ID of the user. * @param sessionId The unique ID for this session. Can be used together with the userId * to retrieve the sessionStorage object. * * @returns An object that will be sent to the user, unchanged. It therefore has to have the * correct format according to the documentation of the specific Endpoint channel. */ handleOutput: async ({ processedOutput, output, endpoint, userId, sessionId }) => { const sessionStorage = await getSessionStorage(userId, sessionId); if (sessionStorage.hasOwnProperty("chatHistory")) { sessionStorage.chatHistory += "\nBot: " + output.text; } else { sessionStorage.chatHistory = "Bot: " + output.text; } return processedOutput; }, /** * This transformer is executed when the Flow execution has finished. * Since all outputs have been sent to the user, this transformer does not return anything. * * @param userId The unique ID of the user. * @param sessionId The unique ID for this session. Can be used together with the userId * to retrieve the sessionStorage object. * * @param endpoint The configuration object for the used Endpoint. * * @returns This transformer cannot return anything. */ handleExecutionFinished: async ({ sessionId, userId, endpoint }) => { }, /** * This transformer is executed when receiving an inject event. * The extracted text and data will be injected into the conversation * for the given user in the given session. * * @param request The Express request object with a JSON parsed body. * @param response The Express response object. * @param endpoint The configuration object for the used Endpoint. * * @returns A valid userId, sessionId, as well as text and/or data, * which has been extracted from the request body. The text and data * will be injected into this conversation. */ handleInject: async ({ request, response, endpoint }) => { /** * Extract the userId, sessionId and text * from the request. Example: * * const { userId, sessionId, text, data } = request.body; * * Note that the format of the request body will be different for * every Endpoint, and the example above needs to be adjusted * accordingly. */ const userId = ""; const sessionId = ""; const text = ""; const data = {} return { userId, sessionId, text, data }; }, /** * This transformer is executed when receiving a notify event. * The extracted text and data will be sent directly to the * given user in the given session as a notification. * * @param request The Express request object with a JSON parsed body. * @param response The Express response object. * @param endpoint The configuration object for the used Endpoint. * * @returns A valid userId, sessionId, as well as text and/or data, * which has been extracted from the request body. The text and data * will be sent directly to the user. */ handleNotify: async ({ request, response, endpoint }) => { /** * Extract the userId, sessionId and text * from the request. Example: * * const { userId, sessionId, text, data } = request.body; * * Note that the format of the request body will be different for * every Endpoint, and the example above needs to be adjusted * accordingly. */ if (!request.body.clientVariables.hasOwnProperty('cognigyState')) return null; const state = request.body.clientVariables.cognigyState; if (state != "STARTAGENT" && state != "STARTBOT" && state != "OPENAGENT" && state != "OPENBOT" && state != "CLOSED") return null; let text = ""; let data = {}; const userId = request.body.clientVariables.cognigyUserId; const sessionId = request.body.clientSessionId; const sessionStorage = await getSessionStorage(userId, sessionId); console.log("state=" + state); console.log("request.body.agentChat=" + request.body.agentChat); console.log("request.body.completed=" + request.body.completed); if (state == "STARTAGENT" || state == "STARTBOT" || (state == "OPENAGENT" && request.body.completed) || (state == "OPENBOT" && request.body.completed)) { if (state == "STARTAGENT" || state == "STARTBOT") { sessionStorage.serviceNowInstanceURL = request.body.clientVariables.serviceNowInstanceURL; sessionStorage.serviceNowAPIToken = request.body.clientVariables.serviceNowAPIToken; sessionStorage.authorization = request.body.clientVariables.authorization; console.log("Authorization: " + sessionStorage.authorization); sessionStorage.userId = request.body.clientVariables.userId; sessionStorage.emailId = request.body.clientVariables.emailId; sessionStorage.timezone = request.body.clientVariables.timezone; sessionStorage.quitPhrase = request.body.clientVariables.quitPhrase; sessionStorage.cognigyUserId = userId; sessionStorage.botQuitPhrase = request.body.clientVariables.botQuitPhrase; } const body = { "token": sessionStorage.serviceNowAPIToken, "requestId": sessionStorage.cognigyInputId, "action": "AGENT", "enterpriseId": "Cognigy", "clientSessionId": sessionId, "botToBot": true, "clientVariables": { "cognigyState": "CLOSED", "cognigyInputId": sessionStorage.cognigyInputId, "cognigyUserId": userId, }, "message": { "text": null, "typed": true, "clientMessageId": sessionStorage.cognigyInputId }, "userId": sessionStorage.userId, "emailId": sessionStorage.emailId, "timezone": sessionStorage.timezone } if (state == "STARTAGENT") { const message = sessionStorage.chatHistory; body.requestId = request.body.clientVariables.cognigyInputId + "/H"; body.clientVariables.cognigyState = "OPENAGENT"; body.clientVariables.cognigyInputId = request.body.clientVariables.cognigyInputId + "/H"; body.message.clientMessageId = request.body.clientVariables.cognigyInputId + "/H"; body.message.text = message; sessionStorage.cognigyInputId = request.body.clientVariables.cognigyInputId + "/H"; try { const result = await httpRequest({ uri: request.body.clientVariables.serviceNowInstanceURL + "/api/sn_va_as_service/bot/integration", method: "POST", headers: { 'Authorization': sessionStorage.authorization, 'Content-Type': 'application/json', 'Accept': 'application/json' }, body: body, json: true }); } catch (e) { text = "Cannot connect to ServiceNow to initiate the conversation with Livechat. Check connection details in Start_Conversation node ...\n" + e.message; return { userId, sessionId, text, data }; } sessionStorage.cognigyState = "OPENAGENT"; return null; } if (state == "STARTBOT") { sessionStorage.cognigyState = "OPENBOT"; sessionStorage.cognigyInputId = request.body.clientVariables.cognigyInputId + "/H"; text = request.body.body[request.body.body.length - 1].promptMsg; return { userId, sessionId, text, data }; } if (state == "OPENAGENT" && request.body.completed) { sessionStorage.cognigyState = "CLOSED"; text = request.body.body[request.body.body.length - 1].value; return { userId, sessionId, text, data }; } if (state == "OPENBOT" && request.body.completed) { sessionStorage.cognigyState = "CLOSED"; text = request.body.body[request.body.body.length - 1].value; return { userId, sessionId, text, data }; } } sessionStorage.cognigyInputId = request.body.clientVariables.cognigyInputId + "*"; for (let row in request.body.body) { if (request.body.body[row].uiType == "OutputText") { text += request.body.body[row].value + "\n"; } if (request.body.body[row].uiType == "OutputCard") { let data = JSON.parse(request.body.body[row].data); text += data.title + "\n"; for (let field in data.fields) { console.log("Hello"); text += data.fields[field].fieldLabel + " - " + data.fields[field].fieldValue + "\n"; } } if (request.body.body[row].uiType == "InputText") { text += request.body.body[row].label + "\n"; } } if (sessionStorage.botQuitPhrase != null && sessionStorage.botQuitPhrase != "") { if (text.includes(sessionStorage.botQuitPhrase)) sessionStorage.cognigyState = "CLOSED"; } return { userId, sessionId, text, data }; } })