@cognigy/rest-api-client 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (189) hide show
  1. package/.snyk +1 -1
  2. package/build/GenericUploadFn.js +1 -1
  3. package/build/RestAPIClient.js +14 -0
  4. package/build/apigroups/AdministrationAPIGroup_2_0.js +25 -3
  5. package/build/apigroups/AnalyticsAPIGroup_2_0.js +12 -0
  6. package/build/apigroups/InsightsAPIGroup_2_0.js +53 -0
  7. package/build/apigroups/ResourcesAPIGroup_2_0.js +23 -2
  8. package/build/apigroups/index.js +5 -1
  9. package/build/authentication/BasicAuthentication/BasicAuthentication.js +8 -1
  10. package/build/authentication/OAuth2/ILoginByClientCredentialsParameters.js +3 -0
  11. package/build/authentication/OAuth2/IOAuth2ClientCredentialsGrantAccessTokenRequest.js +11 -0
  12. package/build/authentication/OAuth2/OAuth2Authentication.js +41 -15
  13. package/build/shared/charts/createNodeDescriptor.js +1 -1
  14. package/build/shared/charts/descriptors/apps/index.js +8 -0
  15. package/build/shared/charts/descriptors/apps/initAppSession.js +33 -0
  16. package/build/shared/charts/descriptors/apps/setAppState.js +46 -0
  17. package/build/shared/charts/descriptors/connectionNodes/smtp/emailNotification.js +6 -4
  18. package/build/shared/charts/descriptors/connectionNodes/smtp/sendEmail.js +2 -2
  19. package/build/shared/charts/descriptors/end.js +1 -0
  20. package/build/shared/charts/descriptors/index.js +86 -67
  21. package/build/shared/charts/descriptors/logic/goTo.js +1 -0
  22. package/build/shared/charts/descriptors/logic/if/else.js +2 -0
  23. package/build/shared/charts/descriptors/logic/if/if.js +2 -1
  24. package/build/shared/charts/descriptors/logic/if/then.js +2 -0
  25. package/build/shared/charts/descriptors/logic/index.js +5 -3
  26. package/build/shared/charts/descriptors/logic/interval/elseInterval.js +1 -0
  27. package/build/shared/charts/descriptors/logic/interval/onInterval.js +1 -0
  28. package/build/shared/charts/descriptors/logic/once/afterwards.js +1 -0
  29. package/build/shared/charts/descriptors/logic/once/onFirstExecution.js +1 -0
  30. package/build/shared/charts/descriptors/logic/setTranslation.js +88 -0
  31. package/build/shared/charts/descriptors/logic/switch/case.js +2 -0
  32. package/build/shared/charts/descriptors/logic/switch/default.js +2 -0
  33. package/build/shared/charts/descriptors/logic/switch/switch.js +52 -4
  34. package/build/shared/charts/descriptors/logic/switchLocale.js +30 -2
  35. package/build/shared/charts/descriptors/logic/think.js +7 -3
  36. package/build/shared/charts/descriptors/logic/thinkV2.js +104 -0
  37. package/build/shared/charts/descriptors/logic/wait.js +2 -9
  38. package/build/shared/charts/descriptors/message/checkChannelChange/checkChannelChange.js +1 -0
  39. package/build/shared/charts/descriptors/message/checkChannelChange/onNo.js +3 -1
  40. package/build/shared/charts/descriptors/message/checkChannelChange/onYes.js +3 -1
  41. package/build/shared/charts/descriptors/message/checkChannelChange/unchanged.js +3 -1
  42. package/build/shared/charts/descriptors/message/question/onAnswer.js +3 -1
  43. package/build/shared/charts/descriptors/message/question/onQuestion.js +3 -1
  44. package/build/shared/charts/descriptors/message/question/question.js +474 -56
  45. package/build/shared/charts/descriptors/message/question/utils/datepickerUtils.js +1 -0
  46. package/build/shared/charts/descriptors/message/question/utils/evaluateQuestionAnswer.js +9 -3
  47. package/build/shared/charts/descriptors/message/question/utils/generateAnswerShortForm.js +37 -0
  48. package/build/shared/charts/descriptors/message/question/utils/getQuestionText.js +36 -0
  49. package/build/shared/charts/descriptors/message/question/utils/resetNodeState.js +12 -0
  50. package/build/shared/charts/descriptors/message/question/utils/storeQuestionAnswer.js +30 -0
  51. package/build/shared/charts/descriptors/message/question/utils/validateQuestionAnswer.js +22 -0
  52. package/build/shared/charts/descriptors/microsoft/getToken.js +34 -0
  53. package/build/shared/charts/descriptors/microsoft/index.js +22 -0
  54. package/build/shared/charts/descriptors/microsoft/invalidateToken.js +29 -0
  55. package/build/shared/charts/descriptors/microsoft/tokenStatus/index.js +51 -0
  56. package/build/shared/charts/descriptors/microsoft/tokenStatus/tokenGranted.js +24 -0
  57. package/build/shared/charts/descriptors/microsoft/tokenStatus/tokenNotGranted.js +24 -0
  58. package/build/shared/charts/descriptors/microsoft/utils/design.js +5 -0
  59. package/build/shared/charts/descriptors/nlu/executeCognigyNLU.js +5 -0
  60. package/build/shared/charts/descriptors/nlu/extractAnswer.js +115 -0
  61. package/build/shared/charts/descriptors/nlu/fuzzySearch.js +270 -0
  62. package/build/shared/charts/descriptors/nlu/index.js +7 -1
  63. package/build/shared/charts/descriptors/nlu/matchPattern.js +104 -0
  64. package/build/shared/charts/descriptors/nlu/utils/patternMatcher.js +197 -0
  65. package/build/shared/charts/descriptors/profile/index.js +5 -1
  66. package/build/shared/charts/descriptors/profile/overwriteAnalytics.js +54 -2
  67. package/build/shared/charts/descriptors/profile/requestRating.js +57 -0
  68. package/build/shared/charts/descriptors/profile/setRating.js +39 -0
  69. package/build/shared/charts/descriptors/service/handover.js +29 -2
  70. package/build/shared/charts/descriptors/service/handoverV2.js +129 -0
  71. package/build/shared/charts/descriptors/service/httpRequest.js +26 -7
  72. package/build/shared/charts/descriptors/service/index.js +3 -1
  73. package/build/shared/charts/descriptors/service/triggerFunction/onScheduled.js +2 -0
  74. package/build/shared/charts/descriptors/service/triggerFunction/onSchedulingError.js +2 -0
  75. package/build/shared/charts/descriptors/start.js +1 -0
  76. package/build/shared/charts/descriptors/voicegateway/nodes/callRecording.js +36 -16
  77. package/build/shared/charts/descriptors/voicegateway/nodes/handover.js +2 -2
  78. package/build/shared/charts/descriptors/voicegateway/nodes/playURL.js +9 -0
  79. package/build/shared/charts/descriptors/voicegateway/nodes/sendMessage.js +1 -1
  80. package/build/shared/charts/descriptors/voicegateway/utils/paramUtils.js +9 -1
  81. package/build/shared/charts/descriptors/voicegateway2/index.js +21 -0
  82. package/build/shared/charts/descriptors/voicegateway2/nodes/dtmf.js +56 -0
  83. package/build/shared/charts/descriptors/voicegateway2/nodes/hangup.js +48 -0
  84. package/build/shared/charts/descriptors/voicegateway2/nodes/play.js +199 -0
  85. package/build/shared/charts/descriptors/voicegateway2/nodes/refer.js +44 -0
  86. package/build/shared/charts/descriptors/voicegateway2/nodes/setSessionConfig.js +584 -0
  87. package/build/shared/charts/descriptors/voicegateway2/utils/design.js +5 -0
  88. package/build/shared/charts/descriptors/voicegateway2/utils/strip-nulls.js +19 -0
  89. package/build/shared/constants.js +9 -1
  90. package/build/shared/errors/baseError.js +34 -1
  91. package/build/shared/helper/rest/array.js +19 -0
  92. package/build/shared/helper/rest/boolean.js +5 -1
  93. package/build/shared/helper/rest/index.js +4 -1
  94. package/build/shared/interfaces/IEndpointTranslationSettings.js +32 -0
  95. package/build/shared/interfaces/IHandoverRequestStatus.js +3 -0
  96. package/build/shared/interfaces/{restAPI/administration/user/v2.0/IDeleteUserMeRest_2_0.js → IHttpRequest.js} +1 -1
  97. package/build/shared/interfaces/IOrganisation.js +1 -1
  98. package/build/shared/interfaces/TEntrypointType.js +2 -0
  99. package/build/shared/interfaces/amqpInterface.js +3 -0
  100. package/build/shared/interfaces/analytics/IAnalyticsFlowHistoryData.js +3 -0
  101. package/build/shared/interfaces/analytics/IAnalyticsSourceData.js +196 -45
  102. package/build/shared/interfaces/analytics/IStepEvent.js +2 -1
  103. package/build/shared/interfaces/analytics/TAnalyticsMode.js +10 -0
  104. package/build/shared/interfaces/analytics/TAnalyticsType.js +5 -0
  105. package/build/shared/interfaces/debugEvents/IErrorEventPayload.js +3 -0
  106. package/build/shared/interfaces/debugEvents/TDebugEndpointEvent.js +1 -0
  107. package/build/shared/interfaces/debugEvents/TDebugEventType.js +2 -1
  108. package/build/shared/interfaces/debugEvents/TSessionStateEmitParams.js +3 -0
  109. package/build/shared/interfaces/handover.js +81 -3
  110. package/build/shared/interfaces/license.js +34 -0
  111. package/build/shared/interfaces/license.js.map +1 -0
  112. package/build/shared/interfaces/messageAPI/ai.js +15 -1
  113. package/build/shared/interfaces/messageAPI/endpoints.js +273 -9
  114. package/build/shared/interfaces/resources/IAuditEvent.js +15 -2
  115. package/build/shared/interfaces/resources/IChartNode.js +56 -10
  116. package/build/shared/interfaces/resources/IEndpoint.js +5 -2
  117. package/build/shared/interfaces/resources/IFlow.js +1 -1
  118. package/build/shared/interfaces/resources/ILexicon.js +8 -2
  119. package/build/shared/interfaces/resources/INLUConnector.js +15 -2
  120. package/build/shared/interfaces/resources/INodeDescriptorSet.js +164 -52
  121. package/build/shared/interfaces/resources/IOptionsResolverFunction.js +18 -0
  122. package/build/shared/interfaces/resources/IPlaybookRun.js +61 -0
  123. package/build/shared/interfaces/resources/IProject.js +7 -1
  124. package/build/shared/interfaces/resources/ISlotFiller.js +38 -21
  125. package/build/shared/interfaces/resources/ISnapshot.js +1 -1
  126. package/build/shared/interfaces/resources/ITrackAnalyticsStepsArguments.js +3 -0
  127. package/build/shared/interfaces/resources/TNLUConnectorType.js +2 -1
  128. package/build/shared/interfaces/resources/TResourceType.js +1 -0
  129. package/build/shared/interfaces/resources/TRestChannelType.js +5 -0
  130. package/build/shared/interfaces/resources/TSocketChannelType.js +5 -1
  131. package/build/shared/interfaces/resources/chart/IChartExecutable.js +3 -2
  132. package/build/shared/interfaces/resources/chart/IChartExecutableNode.js +1 -0
  133. package/build/shared/interfaces/resources/intent/IIntent.js +4 -2
  134. package/build/shared/interfaces/resources/intent/IIntentTrainGroup.js +3 -1
  135. package/build/shared/interfaces/resources/intent/ISentence.js +32 -8
  136. package/build/shared/interfaces/resources/settings/IAgentSettings.js +40 -2
  137. package/build/shared/interfaces/resources/settings/IFlowSettings.js +1 -1
  138. package/build/shared/interfaces/restAPI/administration/liveAgent/v2.0/IReadLiveAgentAccountRest_2_0.js +3 -0
  139. package/build/shared/interfaces/restAPI/administration/liveAgent/v2.0/IReadProjectInboxRest_2_0.js +3 -0
  140. package/build/shared/interfaces/restAPI/administration/liveAgent/v2.0/ISetupCognigyLiveAgentInboxRest_2_0.js +3 -0
  141. package/build/shared/interfaces/restAPI/administration/liveAgent/v2.0/ISetupCognigyLiveAgentRest_2_0.js +3 -0
  142. package/build/shared/interfaces/restAPI/administration/liveAgent/v2.0/index.js +3 -0
  143. package/build/shared/interfaces/restAPI/analytics/IDeleteAnalyticsRecordsRest_2_0.js +3 -0
  144. package/build/shared/interfaces/restAPI/analytics/IUpdateAnalyticsRecordProperties_2_0.js +3 -0
  145. package/build/shared/interfaces/restAPI/analytics/IUpdateAnalyticsRecordsRest_2_0.js +3 -0
  146. package/build/shared/interfaces/restAPI/insights/IAnalyticsQueryFilter_2_0.js +3 -0
  147. package/build/shared/interfaces/restAPI/insights/TAnalyticsQueryFilterOperator_2_0.js +3 -0
  148. package/build/shared/interfaces/restAPI/insights/messages/IGenerateMessagesRest_2_0.js +5 -0
  149. package/build/shared/interfaces/restAPI/insights/messages/ILoadMessagesReportByQueryHashResponse_2_0.js +3 -0
  150. package/build/shared/interfaces/restAPI/insights/messages/ILoadMessagesReportByQueryHashRestData_2_0.js +3 -0
  151. package/build/shared/interfaces/restAPI/insights/messages/ITopNMessages_2_0.js +3 -0
  152. package/build/shared/interfaces/restAPI/insights/reports/IGenerateReportResponse_2_0.js +3 -0
  153. package/build/shared/interfaces/restAPI/insights/reports/IGenerateReportRest_2_0.js +41 -0
  154. package/build/shared/interfaces/restAPI/insights/reports/ILoadReportByQueryHashResponse_2_0.js +3 -0
  155. package/build/shared/interfaces/restAPI/insights/reports/ILoadReportByQueryHashRest_2_0.js +3 -0
  156. package/build/shared/interfaces/restAPI/insights/steps/IGenerateStepReportRest_2_0.js +3 -0
  157. package/build/shared/interfaces/restAPI/insights/steps/IIndexStepsRest_2_0.js +3 -0
  158. package/build/shared/interfaces/restAPI/insights/steps/ILoadStepReportByQueryHashResponse_2_0.js +3 -0
  159. package/build/shared/interfaces/restAPI/insights/steps/ILoadStepReportByQueryHashRestData_2_0.js +3 -0
  160. package/build/shared/interfaces/restAPI/insights/steps/IStepIndexItem_2_0.js +3 -0
  161. package/build/shared/interfaces/restAPI/insights/steps/IStepReport_2_0.js +3 -0
  162. package/build/shared/interfaces/restAPI/insights/steps/IStep_2_0.js +3 -0
  163. package/build/shared/interfaces/restAPI/insights/transcripts/IGenerateTranscriptsRest_2_0.js +3 -0
  164. package/build/shared/interfaces/restAPI/insights/transcripts/ILoadTranscriptsReportByQueryHashResponse_2_0.js +3 -0
  165. package/build/shared/interfaces/restAPI/insights/transcripts/ILoadTranscriptsReportByQueryHashRestData_2_0.js +3 -0
  166. package/build/shared/interfaces/restAPI/insights/transcripts/IStepPath_2_0.js +3 -0
  167. package/build/shared/interfaces/restAPI/resources/chart/v2.0/ISearchChartNodesRest_2_0.js +3 -0
  168. package/build/shared/interfaces/restAPI/resources/extension/v2.0/IUpdateExtensionPackageRest_2_0.js +4 -0
  169. package/build/shared/interfaces/restAPI/resources/flow/v2.0/ICreateFlowFromChildrenRest_2_0.js +4 -0
  170. package/build/shared/interfaces/restAPI/resources/flow/v2.0/intent/ITrainYesNoIntentsRest_2_0.js +3 -0
  171. package/build/shared/interfaces/restAPI/resources/lexicon/v2.0/IComposeLexiconDownloadLinkRest_2_0.js +3 -0
  172. package/build/shared/interfaces/restAPI/resources/nluconnector/v2.0/TNLUConnectorType_2_0.js +3 -1
  173. package/build/shared/interfaces/restAPI/resources/nodedescriptorsets/v2.0/IOptionsResolverRest_2_0.js +3 -0
  174. package/build/shared/interfaces/restAPI/resources/playbook/v2.0/IDeletePlaybookRunRest_2_0.js +3 -0
  175. package/build/shared/interfaces/restAPI/resources/playbook/v2.0/IIndexPlaybookRunsRest_2_0.js +3 -0
  176. package/build/shared/interfaces/restAPI/resources/playbook/v2.0/IPlaybookRunIndexItem_2_0.js +3 -0
  177. package/build/shared/interfaces/restAPI/resources/playbook/v2.0/IPlaybookRun_2_0.js +7 -0
  178. package/build/shared/interfaces/restAPI/resources/playbook/v2.0/IReadPlaybookRunRest_2_0.js +3 -0
  179. package/build/shared/interfaces/restAPI/resources/playbook/v2.0/ISchedulePlaybookRunRest_2_0.js +3 -0
  180. package/build/shared/interfaces/security/IACL.js +1 -1
  181. package/build/shared/interfaces/security/IPermission.js +6 -0
  182. package/build/shared/interfaces/security/IRole.js +8 -2
  183. package/build/shared/interfaces/sessionstate/ISessionState.js +3 -0
  184. package/build/shared/interfaces/sessionstate/index.js +3 -0
  185. package/build/shared/interfaces/trainer/ITrainerRecord.js +4 -0
  186. package/build/shared/interfaces/translation.js +11 -0
  187. package/package.json +5 -5
  188. package/types/index.d.ts +3905 -1178
  189. package/build/shared/charts/descriptors/logic/checkFrustration.js +0 -82
@@ -1,6 +1,38 @@
1
1
  "use strict";
2
+ /**
3
+ * This Question Node asks the user a question and expects a certain type of answer back.
4
+ * The answer is evaluated by the Node and if it's invalid, the user is guided towards
5
+ * giving a correct answer.
6
+ *
7
+ * The Node executes the following steps, all of which have been marked as #regions in the code below
8
+ *
9
+ * 0. Check if we're currently in a reconfirmation of a valid answer and if yes, handle it
10
+ *
11
+ * 1. Check if answer exists in context and stop if it does
12
+ *
13
+ * 2. Check if this is the first time the node is hit and if yes, ask the question and stop (return); if not
14
+ *
15
+ * 3. - doesnt exist anymore -
16
+ *
17
+ * 4. Run actual evaluation of the answer using evaluateQuestionAnswer
18
+ * 4.1 If result location was specified, try to get the result from there
19
+ *
20
+ * 5. If answer is:
21
+ * 5.1 VALID
22
+ * 5.1.1 If reconfirmation is needed, start reconfirmation process and stop
23
+ * 5.1.2 Store the answer either in Context or Input
24
+ * 5.1.3 Store the answer also in the profile
25
+ * 5.1.4 Reset markers and activeQuestion in system Context and return
26
+ *
27
+ * 5.2 INVALID
28
+ * 5.2.1 Check if we should escalate on intent and if yes, do so
29
+ * 5.2.2 Otherwise (!) check if we should escalate on multiple wrong answers and if yes, do so
30
+ * 5.2.3 Check if we should say the reprompt an if yes, say it, plus the question again
31
+ * 5.2.4 Sets itself as the next Node and stops execution
32
+ */
2
33
  Object.defineProperty(exports, "__esModule", { value: true });
3
34
  exports.QUESTION = void 0;
35
+ //#region Imports
4
36
  /* Custom modules */
5
37
  const createNodeDescriptor_1 = require("../../../createNodeDescriptor");
6
38
  const evaluateQuestionAnswer_1 = require("./utils/evaluateQuestionAnswer");
@@ -8,8 +40,16 @@ const say_1 = require("../say");
8
40
  const goTo_1 = require("../../logic/goTo");
9
41
  const executeFlow_1 = require("../../logic/executeFlow");
10
42
  const BaseContext_1 = require("../../../../helper/BaseContext");
43
+ const getQuestionText_1 = require("./utils/getQuestionText");
44
+ const storeQuestionAnswer_1 = require("./utils/storeQuestionAnswer");
45
+ const generateAnswerShortForm_1 = require("./utils/generateAnswerShortForm");
46
+ const validateQuestionAnswer_1 = require("./utils/validateQuestionAnswer");
47
+ const service_1 = require("../../service");
11
48
  const datepickerUtils_1 = require("./utils/datepickerUtils");
49
+ const resetNodeState_1 = require("./utils/resetNodeState");
50
+ //#endregion Interfaces
12
51
  exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
52
+ //#region DescriptorFields
13
53
  type: "question",
14
54
  defaultLabel: "Question",
15
55
  summary: "Ask a question and waits for a valid answer",
@@ -114,7 +154,10 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
114
154
  type: "cognigyText",
115
155
  label: "Reprompt Message",
116
156
  description: "Message to output if the given answer is invalid",
117
- defaultValue: "Not sure I understood this correctly."
157
+ defaultValue: "Not sure I understood this correctly.",
158
+ params: {
159
+ multiline: true
160
+ }
118
161
  },
119
162
  {
120
163
  key: "repromptCondition",
@@ -208,6 +251,17 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
208
251
  value: true
209
252
  }
210
253
  },
254
+ {
255
+ key: "onlyAcceptEscalationIntents",
256
+ type: "toggle",
257
+ label: "Only Accept Escalation Intents",
258
+ description: "Ignore all Intents on Answer, except Escalation Intents",
259
+ condition: {
260
+ key: "type",
261
+ value: "intent",
262
+ negate: true
263
+ }
264
+ },
211
265
  {
212
266
  key: "parseResultOnEntry",
213
267
  type: "toggle",
@@ -274,6 +328,10 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
274
328
  label: "Execute Flow and return",
275
329
  value: "execute"
276
330
  },
331
+ {
332
+ label: "Handover to Human Agent",
333
+ value: "handover"
334
+ }
277
335
  ],
278
336
  },
279
337
  defaultValue: 'none'
@@ -386,13 +444,86 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
386
444
  }
387
445
  },
388
446
  {
389
- key: "escalateAnswersExecuteRepromptPrevention",
447
+ key: "escalateAnswersHandoverText",
448
+ type: "cognigyText",
449
+ label: "Handover Accepted Message",
450
+ description: "The message to display to the user once the handover request was accepted by the live chat provider",
451
+ condition: {
452
+ key: "escalateAnswersAction",
453
+ value: "handover"
454
+ }
455
+ },
456
+ {
457
+ key: "escalateAnswersRepeatHandoverMessage",
390
458
  type: "toggle",
391
- label: "Prevent Reprompt on Escalation",
392
- defaultValue: true,
459
+ label: "Repeat Handover Accepted Message",
460
+ description: "Repeatedly respond with Handover Accepted Message for each user input until human agent responds",
461
+ defaultValue: false,
393
462
  condition: {
394
463
  key: "escalateAnswersAction",
395
- value: "execute"
464
+ value: "handover"
465
+ }
466
+ },
467
+ {
468
+ key: "escalateAnswersHandoverCancelIntent",
469
+ type: "cognigyText",
470
+ label: "Cancel Intent",
471
+ description: "Name of the intent which will cancel the handover",
472
+ condition: {
473
+ key: "escalateAnswersAction",
474
+ value: "handover"
475
+ }
476
+ },
477
+ {
478
+ key: "escalateAnswersHandoverQuickReply",
479
+ type: "cognigyText",
480
+ label: "Cancel Button Text",
481
+ description: "Text of the Quick Reply Button which sends the user back to the Virtual Agent",
482
+ condition: {
483
+ key: "escalateAnswersAction",
484
+ value: "handover"
485
+ }
486
+ },
487
+ process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && {
488
+ key: "escalateAnswersHandoverLiveAgentInboxId",
489
+ type: "cognigyText",
490
+ label: "Live Agent Inbox Id",
491
+ description: "Inbox Id in Live Agent",
492
+ condition: {
493
+ key: "escalateAnswersAction",
494
+ value: "handover"
495
+ }
496
+ },
497
+ {
498
+ key: "escalateAnswersHandoverChatwootInboxId",
499
+ type: "cognigyText",
500
+ label: "Chatwoot Inbox Id",
501
+ description: "Inbox Id in Chatwoot",
502
+ condition: {
503
+ key: "escalateAnswersAction",
504
+ value: "handover"
505
+ }
506
+ },
507
+ {
508
+ key: "escalateAnswersHandoverSalesforcePrechatEntities",
509
+ type: "json",
510
+ label: "Salesforce Prechat Entities",
511
+ description: "The Salesforce entity that should be used.",
512
+ defaultValue: "[]",
513
+ condition: {
514
+ key: "escalateAnswersAction",
515
+ value: "handover"
516
+ }
517
+ },
518
+ {
519
+ key: "escalateAnswersHandoverSalesforcePrechatDetails",
520
+ type: "json",
521
+ label: "Salesforce Prechat Details",
522
+ description: "The details that should be displayed to the Live Chat Agent.",
523
+ defaultValue: "[]",
524
+ condition: {
525
+ key: "escalateAnswersAction",
526
+ value: "handover"
396
527
  }
397
528
  },
398
529
  {
@@ -434,6 +565,10 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
434
565
  label: "Execute Flow and return",
435
566
  value: "execute"
436
567
  },
568
+ {
569
+ label: "Handover to Human Agent",
570
+ value: "handover"
571
+ }
437
572
  ],
438
573
  },
439
574
  defaultValue: 'none'
@@ -546,6 +681,89 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
546
681
  value: "text"
547
682
  }
548
683
  },
684
+ {
685
+ key: "escalateIntentsHandoverText",
686
+ type: "cognigyText",
687
+ label: "Handover Accepted Message",
688
+ description: "The message to display to the user once the handover request was accepted by the live chat provider",
689
+ condition: {
690
+ key: "escalateIntentsAction",
691
+ value: "handover"
692
+ }
693
+ },
694
+ {
695
+ key: "escalateIntentsRepeatHandoverMessage",
696
+ type: "toggle",
697
+ label: "Repeat Handover Accepted Message",
698
+ description: "Repeatedly respond with Handover Accepted Message for each user input until human agent responds",
699
+ defaultValue: false,
700
+ condition: {
701
+ key: "escalateIntentsAction",
702
+ value: "handover"
703
+ }
704
+ },
705
+ {
706
+ key: "escalateIntentsHandoverCancelIntent",
707
+ type: "cognigyText",
708
+ label: "Cancel Intent",
709
+ description: "Name of the intent which will cancel the handover",
710
+ condition: {
711
+ key: "escalateIntentsAction",
712
+ value: "handover"
713
+ }
714
+ },
715
+ {
716
+ key: "escalateIntentsHandoverQuickReply",
717
+ type: "cognigyText",
718
+ label: "Cancel Button Text",
719
+ description: "Text of the Quick Reply Button which sends the user back to the Virtual Agent",
720
+ condition: {
721
+ key: "escalateIntentsAction",
722
+ value: "handover"
723
+ }
724
+ },
725
+ process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && {
726
+ key: "escalateIntentsHandoverLiveAgentInboxId",
727
+ type: "cognigyText",
728
+ label: "Live Agent Inbox Id",
729
+ description: "Inbox Id in Live Agent",
730
+ condition: {
731
+ key: "escalateIntentsAction",
732
+ value: "handover"
733
+ }
734
+ },
735
+ {
736
+ key: "escalateIntentsHandoverChatwootInboxId",
737
+ type: "cognigyText",
738
+ label: "Chatwoot Inbox Id",
739
+ description: "Inbox Id in Chatwoot",
740
+ condition: {
741
+ key: "escalateIntentsAction",
742
+ value: "handover"
743
+ }
744
+ },
745
+ {
746
+ key: "escalateIntentsHandoverSalesforcePrechatEntities",
747
+ type: "json",
748
+ label: "Salesforce Prechat Entities",
749
+ description: "The Salesforce entity that should be used.",
750
+ defaultValue: "[]",
751
+ condition: {
752
+ key: "escalateIntentsAction",
753
+ value: "handover"
754
+ }
755
+ },
756
+ {
757
+ key: "escalateIntentsHandoverSalesforcePrechatDetails",
758
+ type: "json",
759
+ label: "Salesforce Prechat Details",
760
+ description: "The details that should be displayed to the Live Chat Agent.",
761
+ defaultValue: "[]",
762
+ condition: {
763
+ key: "escalateIntentsAction",
764
+ value: "handover"
765
+ }
766
+ },
549
767
  {
550
768
  key: "escalateIntentsRepromptPrevention",
551
769
  type: "toggle",
@@ -557,20 +775,51 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
557
775
  }
558
776
  },
559
777
  {
560
- key: "escalateIntentsExecuteRepromptPrevention",
561
- type: "toggle",
562
- label: "Prevent Reprompt on Escalation",
563
- defaultValue: true,
778
+ key: "reconfirmationBehaviour",
779
+ type: "select",
780
+ description: "How and if to reconfirm question answers",
781
+ label: "Reconfirmation Behaviour",
782
+ defaultValue: "none",
783
+ params: {
784
+ options: [
785
+ {
786
+ label: "Do not reconfirm answer",
787
+ value: "none"
788
+ },
789
+ {
790
+ label: "Reconfirm answer",
791
+ value: "reconfirm"
792
+ },
793
+ ]
794
+ }
795
+ },
796
+ {
797
+ key: "reconfirmationQuestion",
798
+ type: "cognigyText",
799
+ label: "Reconfirmation Question",
800
+ description: "The question to ask to reconfirm the answer",
801
+ defaultValue: "I heard you say [ANSWER]. Is that correct?",
564
802
  condition: {
565
- key: "escalateIntentsAction",
566
- value: "execute"
803
+ key: "reconfirmationBehaviour",
804
+ value: "reconfirm"
805
+ }
806
+ },
807
+ {
808
+ key: "reconfirmationQuestionReprompt",
809
+ type: "cognigyText",
810
+ label: "Reconfirmation Reprompt",
811
+ description: "What to say if the reconfirmation question wasn't answered with yes or no",
812
+ defaultValue: "I'm not sure I got that right.",
813
+ condition: {
814
+ key: "reconfirmationBehaviour",
815
+ value: "reconfirm"
567
816
  }
568
817
  },
569
818
  ...datepickerUtils_1.getDatePickerFields({
570
819
  "key": "type",
571
820
  "value": "date"
572
821
  })
573
- ],
822
+ ].filter(field => !!field),
574
823
  sections: [
575
824
  {
576
825
  key: "context",
@@ -595,6 +844,16 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
595
844
  "skipRepromptOnIntent"
596
845
  ]
597
846
  },
847
+ {
848
+ key: "reconfirmation",
849
+ label: "Reconfirmation Options",
850
+ defaultCollapsed: true,
851
+ fields: [
852
+ "reconfirmationBehaviour",
853
+ "reconfirmationQuestion",
854
+ "reconfirmationQuestionReprompt"
855
+ ]
856
+ },
598
857
  {
599
858
  key: "escalateIntents",
600
859
  label: "Escalation - Intents",
@@ -609,8 +868,16 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
609
868
  "escalateIntentsInjectedText",
610
869
  "escalateIntentsInjectedData",
611
870
  "escalateIntentsMessage",
871
+ "escalateIntentsHandoverText",
872
+ "escalateIntentsRepeatHandoverMessage",
873
+ "escalateIntentsHandoverCancelIntent",
874
+ "escalateIntentsHandoverQuickReply",
875
+ process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && "escalateIntentsHandoverLiveAgentInboxId",
876
+ "escalateIntentsHandoverChatwootInboxId",
877
+ "escalateIntentsHandoverSalesforcePrechatEntities",
878
+ "escalateIntentsHandoverSalesforcePrechatDetails",
612
879
  "escalateIntentsRepromptPrevention"
613
- ]
880
+ ].filter(field => !!field)
614
881
  },
615
882
  {
616
883
  key: "escalateAnswers",
@@ -625,9 +892,17 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
625
892
  "escalateAnswersInjectedText",
626
893
  "escalateAnswersInjectedData",
627
894
  "escalateAnswersMessage",
895
+ "escalateAnswersHandoverText",
896
+ "escalateAnswersRepeatHandoverMessage",
897
+ "escalateAnswersHandoverCancelIntent",
898
+ "escalateAnswersHandoverQuickReply",
899
+ process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && "escalateAnswersHandoverLiveAgentInboxId",
900
+ "escalateAnswersHandoverChatwootInboxId",
901
+ "escalateAnswersHandoverSalesforcePrechatEntities",
902
+ "escalateAnswersHandoverSalesforcePrechatDetails",
628
903
  "escalateAnswersRepromptPrevention",
629
- "escalateAnswersOnce"
630
- ]
904
+ "escalateAnswersOnce",
905
+ ].filter(field => !!field)
631
906
  },
632
907
  {
633
908
  key: "advanced",
@@ -636,6 +911,7 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
636
911
  fields: [
637
912
  "storeDetailedResults",
638
913
  "parseResultOnEntry",
914
+ "onlyAcceptEscalationIntents",
639
915
  "additionalValidation",
640
916
  "resultLocation",
641
917
  "maxExecutionDiff",
@@ -654,6 +930,7 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
654
930
  { type: "field", key: "say" },
655
931
  { type: "section", key: "context" },
656
932
  { type: "section", key: "reprompt" },
933
+ { type: "section", key: "reconfirmation" },
657
934
  { type: "section", key: "escalateIntents" },
658
935
  { type: "section", key: "escalateAnswers" },
659
936
  { type: "section", key: "advanced" },
@@ -670,19 +947,23 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
670
947
  type: "sayNode",
671
948
  },
672
949
  tags: ["basic", "message", "nlu"],
673
- function: async ({ cognigy, nodeId, config }) => {
674
- var _a;
675
- const { say, type, validationMessage, validationRepeat, storeResultInContext, contextKey, storeInContactProfile, profileKey, storeDetailedResults, parseResultOnEntry, additionalValidation, repromptCondition, maxExecutionDiff, resultLocation, skipRepromptOnIntent, escalateAnswersAction, escalateAnswersThreshold, escalateAnswersGotoTarget, escalateAnswersExecuteTarget, escalateAnswersGotoExecutionMode, escalateAnswersInjectedText, escalateAnswersInjectedData, escalateAnswersMessage, escalateAnswersRepromptPrevention, escalateAnswersOnce, escalateIntentsAction, escalateIntentsValidIntents, escalateIntentsThreshold, escalateIntentsGotoTarget, escalateIntentsExecuteTarget, escalateIntentsGotoExecutionMode, escalateIntentsInjectedText, escalateIntentsInjectedData, escalateIntentsMessage, escalateIntentsRepromptPrevention } = config;
950
+ //#endregion DescriptorFields
951
+ function: async ({ cognigy, nodeId, config, inputOptions }) => {
952
+ const { say, type, validationMessage, validationRepeat, storeResultInContext, contextKey, storeInContactProfile, profileKey, storeDetailedResults, parseResultOnEntry, repromptCondition, maxExecutionDiff, resultLocation, skipRepromptOnIntent, onlyAcceptEscalationIntents, escalateAnswersAction, escalateAnswersThreshold, escalateAnswersGotoTarget, escalateAnswersExecuteTarget, escalateAnswersGotoExecutionMode, escalateAnswersInjectedText, escalateAnswersInjectedData, escalateAnswersMessage, escalateAnswersRepromptPrevention, escalateAnswersOnce, escalateAnswersHandoverText, escalateAnswersRepeatHandoverMessage, escalateAnswersHandoverCancelIntent, escalateAnswersHandoverQuickReply, escalateAnswersHandoverChatwootInboxId, escalateAnswersHandoverLiveAgentInboxId, escalateAnswersHandoverSalesforcePrechatEntities, escalateAnswersHandoverSalesforcePrechatDetails, escalateIntentsAction, escalateIntentsValidIntents, escalateIntentsThreshold, escalateIntentsGotoTarget, escalateIntentsExecuteTarget, escalateIntentsGotoExecutionMode, escalateIntentsInjectedText, escalateIntentsInjectedData, escalateIntentsMessage, escalateIntentsHandoverText, escalateIntentsRepeatHandoverMessage, escalateIntentsHandoverCancelIntent, escalateIntentsHandoverQuickReply, escalateIntentsHandoverChatwootInboxId, escalateIntentsHandoverLiveAgentInboxId, escalateIntentsHandoverSalesforcePrechatEntities, escalateIntentsHandoverSalesforcePrechatDetails, escalateIntentsRepromptPrevention, reconfirmationBehaviour, reconfirmationQuestion, reconfirmationQuestionReprompt } = config;
676
953
  const { input, context, profile, api } = cognigy;
677
954
  // compute how often this node was hit
678
955
  const executionAmount = api.getExecutionAmount(nodeId);
679
956
  // compute how long ago this node was hit
680
957
  const lastExecutionMarker = api.getLastExecutionMarker(nodeId);
681
- const executionDiff = cognigy.input.execution - lastExecutionMarker;
958
+ let executionDiff = cognigy.input.execution - lastExecutionMarker;
959
+ // the intent reconfirmation message should not count for the executionDiff
960
+ if (inputOptions === null || inputOptions === void 0 ? void 0 : inputOptions.handledIntentReconfirmation) {
961
+ executionDiff -= 1;
962
+ }
682
963
  // if this is the very first time the Node gets executed
683
964
  // or if we have been "away" from the Node for too long (maxExecutionDiff)
684
965
  // we consider it a first execution and show the question
685
- const isFirstExecution = executionAmount === 1 || executionDiff > (maxExecutionDiff || 1);
966
+ let isFirstExecution = executionAmount === 1 || executionDiff > (maxExecutionDiff || 1);
686
967
  // remember the current question in systemContext to later fill Input with it
687
968
  let activeQuestion = api.getSystemContext('activeQuestion');
688
969
  if (!activeQuestion || activeQuestion.nodeId !== nodeId) {
@@ -692,13 +973,82 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
692
973
  lastExecutedAt: input.execution,
693
974
  forgetQuestionThreshold: maxExecutionDiff,
694
975
  repromptCount: 0,
695
- escalationCount: 0
976
+ escalationCount: 0,
696
977
  };
978
+ if (onlyAcceptEscalationIntents && config.type !== "intent") {
979
+ activeQuestion.onlyAcceptEscalationIntents = onlyAcceptEscalationIntents;
980
+ activeQuestion.escalationIntents = escalateIntentsValidIntents;
981
+ }
697
982
  api.setSystemContext('activeQuestion', activeQuestion);
698
983
  }
699
984
  else {
700
985
  activeQuestion.lastExecutedAt = input.execution;
701
986
  }
987
+ // #region 0 CheckIfReconfirmationInProgress
988
+ if (api.getSystemContext("reconfirmationQuestionInProgress")) {
989
+ // if this is the case, we are now a YN question
990
+ let res = evaluateQuestionAnswer_1.evaluateQuestionAnswer({
991
+ cognigy, config: {
992
+ "type": "yesNo"
993
+ }
994
+ });
995
+ const restoredInput = api.getSystemContext("reconfirmationQuestionInput");
996
+ input.intent = restoredInput.intent;
997
+ input.intentScore = restoredInput.intentScore;
998
+ input.intentFlow = restoredInput.intentFlow;
999
+ input.nlu = restoredInput.nlu;
1000
+ input.intentLevel = restoredInput.intentLevel;
1001
+ if (res === true) { // the reconfirmation answer was yes-like
1002
+ // get the tentative answer that was given and store it
1003
+ const result = activeQuestion === null || activeQuestion === void 0 ? void 0 : activeQuestion.tentativeAnswer;
1004
+ storeQuestionAnswer_1.storeQuestionAnswer({ context, contextKey, input, result, storeResultInContext });
1005
+ // reset everything and continue to the next node
1006
+ resetNodeState_1.resetNodeState(api, nodeId);
1007
+ return;
1008
+ }
1009
+ else if (res !== false) { // the reconfirmation answer was invalid (e.g. no yes-like or no-like answer)
1010
+ // output reconfirmation reprompt
1011
+ if (reconfirmationQuestionReprompt) {
1012
+ say_1.SAY.function({ cognigy, childConfigs: [], nodeId, config: { say: { type: "text", text: [reconfirmationQuestionReprompt] } } });
1013
+ }
1014
+ // output reconfirmationQuestion
1015
+ const tentativeAnswerShortform = (activeQuestion === null || activeQuestion === void 0 ? void 0 : activeQuestion.tentativeAnswerShortform) || "";
1016
+ say_1.SAY.function({ cognigy, childConfigs: [], nodeId, config: { say: { type: "text", text: [reconfirmationQuestion.replace("[ANSWER]", tentativeAnswerShortform)] } } });
1017
+ // set myself as next node and stop
1018
+ api.setNextNode(nodeId);
1019
+ api.stopExecution();
1020
+ return;
1021
+ }
1022
+ else { // the reconfirmation answer was no-like
1023
+ // delete all remnants of this reconfirmation
1024
+ api.deleteSystemContext('activeQuestion');
1025
+ api.deleteSystemContext('reconfirmationQuestionInProgress');
1026
+ api.deleteSystemContext("reconfirmationQuestionInput");
1027
+ // pretend the question was never asked and continue
1028
+ isFirstExecution = true;
1029
+ api.setExecutionAmount(nodeId, 1);
1030
+ }
1031
+ }
1032
+ // #endregion 0 CheckIfReconfirmationInProgress
1033
+ let currentNodeExecutionAmount = api.getExecutionAmount(nodeId) - 1;
1034
+ // Only validate if the forget question threshold is defined (gt 0)
1035
+ if (maxExecutionDiff > 0) {
1036
+ // Check if the same question node was executed before, if yes
1037
+ // calculate the question diff. last step - recent step
1038
+ let questionDiff = 0;
1039
+ if (executionAmount > 1) {
1040
+ // Calculate the question diff from the first lastExecutedAt
1041
+ questionDiff = executionDiff - lastExecutionMarker;
1042
+ }
1043
+ let validateAnswer = questionDiff <= maxExecutionDiff;
1044
+ // If we don't want to validate due to an exceeded forget question
1045
+ // threshold, we set setLastExecutionMarker to 0
1046
+ if (!validateAnswer) {
1047
+ currentNodeExecutionAmount = 0;
1048
+ api.setExecutionAmount(nodeId, 1);
1049
+ }
1050
+ }
1051
+ // #region 1 AnswerExistsInContext
702
1052
  // if the user has chose to skip the question in case the context already
703
1053
  // exists, we will just skip the question
704
1054
  if (config.storeResultInContext && config.skipIfResultInContext) {
@@ -710,13 +1060,15 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
710
1060
  location = BaseContext_1.BaseContext.findLocationPathStateless(splits, true, location);
711
1061
  target = splits[splits.length - 1];
712
1062
  }
713
- if (location[target]) {
1063
+ if (location[target] !== null && location[target] !== undefined) {
714
1064
  api.setLastExecutionMarker(nodeId, -1);
715
1065
  api.resetExecutionAmount(nodeId);
716
1066
  api.deleteSystemContext('activeQuestion');
717
1067
  return;
718
1068
  }
719
1069
  }
1070
+ // #endregion 1 AnswerExistsInContext
1071
+ // #region 2 FirstTimeNodeIsHit
720
1072
  // if it's the first execution and you don't force evaluation on first execution, ask the question
721
1073
  if (isFirstExecution && !parseResultOnEntry) {
722
1074
  say_1.SAY.function({ cognigy, childConfigs: [], nodeId, config: { say } });
@@ -728,14 +1080,12 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
728
1080
  api.stopExecution();
729
1081
  return;
730
1082
  }
731
- let valid = true;
732
- // check if there is an extra condition defined and check whether it was truthy
733
- if (additionalValidation) {
734
- valid = !!api.parseCognigyScriptCondition(additionalValidation);
735
- }
1083
+ // #endregion 2 FirstTimeNodeIsHit
736
1084
  // if we're in a subsequent execution or we want to parse results
737
1085
  // immediately on entry, continue with evaluation
738
1086
  let result = evaluateQuestionAnswer_1.evaluateQuestionAnswer({ cognigy, config });
1087
+ // #endregion 4 RunQuestionAnswerValidation
1088
+ // #region 4.1 ResultLocationHandling
739
1089
  // if a result location was specified, try to get the result from that location
740
1090
  // if the location returns a falsey value, the answer is invalid
741
1091
  if (resultLocation && result) {
@@ -744,46 +1094,59 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
744
1094
  if (storeDetailedResults && result !== null && result !== undefined) {
745
1095
  result = {
746
1096
  "value": result,
747
- "question": (_a = config === null || config === void 0 ? void 0 : config.say) === null || _a === void 0 ? void 0 : _a.text,
1097
+ "question": getQuestionText_1.getQuestionText(config),
748
1098
  "timestamp": cognigy.input.currentTime.ISODate,
749
1099
  "answer": cognigy.input.text,
750
1100
  "answerData": cognigy.input.data
751
1101
  };
752
1102
  }
753
1103
  }
1104
+ // #endregion 4.1 ResultLocationHandling
1105
+ const isValid = validateQuestionAnswer_1.validateQuestionAnswer(cognigy, config);
754
1106
  // hard check against null & undefined, because result can be 0 or false
755
- if (result !== null && result !== undefined && valid) {
756
- // Answer was VALID
757
- if (storeResultInContext && contextKey) {
758
- // check whether contextKey or inputKey is a deep query and set
759
- // storage location accordingly
760
- let location = context;
761
- let target = contextKey;
762
- // this is a deep query
763
- if (target.indexOf(".") > -1) {
764
- const splits = target.split(".");
765
- location = BaseContext_1.BaseContext.findLocationPathStateless(splits, true, location);
766
- target = splits[splits.length - 1];
767
- }
768
- location[target] = result;
769
- // always store result also in input to allow for
770
- // easy handling in conditions etc.
771
- input.result = result;
1107
+ if (result !== null && result !== undefined && isValid) {
1108
+ // #region 5.1 AnswerIsValid
1109
+ if (reconfirmationBehaviour === "reconfirm" && reconfirmationQuestion) {
1110
+ // #region 5.1.1 ReconfirmationQuestion
1111
+ // remember the given answer in the activeQuestion object
1112
+ activeQuestion.tentativeAnswer = result;
1113
+ // remember a shortform of the given answer in the activeQuestion object
1114
+ activeQuestion.tentativeAnswerShortform = generateAnswerShortForm_1.generateAnswerShortForm(type, result, cognigy.input.text);
1115
+ // Output reconfirmationQuestion
1116
+ say_1.SAY.function({ cognigy, childConfigs: [], nodeId, config: { say: { type: "text", text: [reconfirmationQuestion.replace("[ANSWER]", activeQuestion.tentativeAnswerShortform)] } } });
1117
+ // remember that we are in reconfirmation mode and stop
1118
+ api.setSystemContext("reconfirmationQuestionInProgress", true);
1119
+ // we need to store the input, to be able to restore it afterwards
1120
+ // since we need information like intentLevel.
1121
+ api.setSystemContext("reconfirmationQuestionInput", input);
1122
+ api.setNextNode(nodeId);
1123
+ api.stopExecution();
1124
+ // #endregion 5.1.1 ReconfirmationQuestion
772
1125
  }
773
1126
  else {
774
- input.result = result;
775
- }
776
- // if profile storage is requested, also store in contact profile
777
- if (storeInContactProfile && profile && profileKey)
778
- profile[profileKey] = (storeDetailedResults) ? result.value : result;
779
- api.setLastExecutionMarker(nodeId, -1);
780
- api.resetExecutionAmount(nodeId);
781
- api.deleteSystemContext('activeQuestion');
1127
+ // #region 5.1.2 StoreAnswerInContextOrInput
1128
+ storeQuestionAnswer_1.storeQuestionAnswer({ context, contextKey, input, result, storeResultInContext });
1129
+ // #endregion 5.1.2 StoreAnswerInContextOrInput
1130
+ // #region 5.1.3 StoreAnswerInProfile
1131
+ // if profile storage is requested, also store in contact profile
1132
+ if (storeInContactProfile && profile && profileKey) {
1133
+ profile[profileKey] = (storeDetailedResults) ? result.value : result;
1134
+ }
1135
+ // #endregion 5.1.3 StoreAnswerInProfile
1136
+ // #region 5.1.4 SetMarkersAndContinue
1137
+ api.setLastExecutionMarker(nodeId, -1);
1138
+ api.resetExecutionAmount(nodeId);
1139
+ api.deleteSystemContext('activeQuestion');
1140
+ // #endregion 5.1.4 SetMarkersAndContinue
1141
+ }
782
1142
  return;
1143
+ // #endregion 5.1 AnswerIsValid
783
1144
  }
784
1145
  else { // Answer was INVALID
1146
+ // #region 5.2 AnswerIsInvalid
785
1147
  let sayReprompt = true;
786
1148
  let escalatedInIntent = false;
1149
+ // #region 5.2.1 EscalationOnIntent
787
1150
  // Process escalation on intents
788
1151
  if (escalateIntentsAction && escalateIntentsAction !== "none") {
789
1152
  const lastEscalation = api.getSystemContext(`lastEscalation-${nodeId}`);
@@ -792,7 +1155,7 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
792
1155
  sayReprompt = false;
793
1156
  }
794
1157
  else if (input.intent && input.intentScore >= escalateIntentsThreshold && escalateIntentsValidIntents.indexOf(input.intent) > -1) {
795
- // User has triggered intent escalation
1158
+ // User has triggered intent escalation
796
1159
  escalatedInIntent = true;
797
1160
  activeQuestion.escalationCount++;
798
1161
  switch (escalateIntentsAction) {
@@ -800,6 +1163,8 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
800
1163
  if (!escalateIntentsGotoTarget) {
801
1164
  throw new Error("GoTo Target is required");
802
1165
  }
1166
+ // remember when this escalation happened
1167
+ api.setSystemContext(`lastEscalation-${nodeId}`, cognigy.input.execution);
803
1168
  await goTo_1.GO_TO.function({
804
1169
  cognigy,
805
1170
  childConfigs: [],
@@ -874,19 +1239,46 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
874
1239
  sayReprompt = false;
875
1240
  }
876
1241
  break;
1242
+ case "handover":
1243
+ resetNodeState_1.resetNodeState(api, nodeId);
1244
+ await service_1.HANDOVER_V2.function({
1245
+ cognigy,
1246
+ childConfigs: [],
1247
+ nodeId,
1248
+ config: {
1249
+ text: escalateIntentsHandoverText,
1250
+ repeatHandoverMessage: escalateIntentsRepeatHandoverMessage,
1251
+ cancelIntent: escalateIntentsHandoverCancelIntent,
1252
+ quickReply: escalateIntentsHandoverQuickReply,
1253
+ chatwootInboxId: escalateIntentsHandoverChatwootInboxId,
1254
+ liveAgentInboxId: escalateIntentsHandoverLiveAgentInboxId,
1255
+ salesforcePrechatEntities: escalateIntentsHandoverSalesforcePrechatEntities,
1256
+ salesforcePrechatDetails: escalateIntentsHandoverSalesforcePrechatDetails
1257
+ }
1258
+ });
1259
+ return;
877
1260
  }
878
1261
  }
879
1262
  }
880
- if (!escalatedInIntent && escalateAnswersAction && escalateAnswersAction !== "none") {
1263
+ // #endregion 5.2.1 EscalationOnIntent
1264
+ // #region 5.2.2 EscalationOnAnswers
1265
+ if ((!escalatedInIntent && escalatedInIntent != undefined) && escalateAnswersAction && escalateAnswersAction !== "none") {
881
1266
  // the user set special escalation handling in case multiple wrong answers were provided
882
1267
  // this is only done if intent escalation didnt happen
883
1268
  const lastEscalation = api.getSystemContext(`lastEscalation-${nodeId}`);
1269
+ let addEscalationText = false;
1270
+ if (escalateAnswersOnce) {
1271
+ addEscalationText = currentNodeExecutionAmount === escalateAnswersThreshold;
1272
+ }
1273
+ else {
1274
+ addEscalationText = currentNodeExecutionAmount >= escalateAnswersThreshold;
1275
+ }
884
1276
  // either we escalate only once on the threshold or always from the threshold on, depending on what was set
885
1277
  if (lastEscalation && lastEscalation === cognigy.input.execution) {
886
1278
  // escalation already happened on this execution - don't escalate again
887
1279
  sayReprompt = false;
888
1280
  }
889
- else if ((escalateAnswersOnce && (api.getExecutionAmount(nodeId) - 1 === escalateAnswersThreshold)) || (!escalateAnswersOnce && (api.getExecutionAmount(nodeId) - 1 >= escalateAnswersThreshold))) {
1281
+ else if (addEscalationText) {
890
1282
  // User has given enough wrong answers to trigger the threshold
891
1283
  activeQuestion.escalationCount++;
892
1284
  switch (escalateAnswersAction) {
@@ -894,6 +1286,8 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
894
1286
  if (!escalateAnswersGotoTarget) {
895
1287
  throw new Error("GoTo Target is required");
896
1288
  }
1289
+ // remember when this escalation happened
1290
+ api.setSystemContext(`lastEscalation-${nodeId}`, cognigy.input.execution);
897
1291
  await goTo_1.GO_TO.function({
898
1292
  cognigy,
899
1293
  childConfigs: [],
@@ -966,9 +1360,29 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
966
1360
  sayReprompt = false;
967
1361
  }
968
1362
  break;
1363
+ case "handover":
1364
+ resetNodeState_1.resetNodeState(api, nodeId);
1365
+ await service_1.HANDOVER_V2.function({
1366
+ cognigy,
1367
+ childConfigs: [],
1368
+ nodeId,
1369
+ config: {
1370
+ text: escalateAnswersHandoverText,
1371
+ cancelIntent: escalateAnswersHandoverCancelIntent,
1372
+ repeatHandoverMessage: escalateAnswersRepeatHandoverMessage,
1373
+ quickReply: escalateAnswersHandoverQuickReply,
1374
+ chatwootInboxId: escalateAnswersHandoverChatwootInboxId,
1375
+ liveAgentInboxId: escalateAnswersHandoverLiveAgentInboxId,
1376
+ salesforcePrechatEntities: escalateAnswersHandoverSalesforcePrechatEntities,
1377
+ salesforcePrechatDetails: escalateAnswersHandoverSalesforcePrechatDetails
1378
+ }
1379
+ });
1380
+ return;
969
1381
  }
970
1382
  }
971
1383
  }
1384
+ // #endregion 5.2.2 EscalationOnAnswers
1385
+ // #region 5.2.3 Reprompt
972
1386
  // check if there is an extra condition defined for reprompts and check whether it was truthy
973
1387
  if (sayReprompt && repromptCondition) {
974
1388
  sayReprompt = !!api.parseCognigyScriptCondition(repromptCondition);
@@ -1007,9 +1421,13 @@ exports.QUESTION = createNodeDescriptor_1.createNodeDescriptor({
1007
1421
  datepickerUtils_1.showDatePicker(cognigy, config);
1008
1422
  }
1009
1423
  }
1424
+ // #endregion 5.2.3 Reprompt
1425
+ // #region 5.2.4 SetNextNodeAndStop
1010
1426
  api.setLastExecutionMarker(nodeId, cognigy.input.execution);
1011
1427
  api.setNextNode(nodeId);
1012
1428
  api.stopExecution();
1429
+ // #endregion 5.2.4 SetNextNodeAndStop
1430
+ // #endregion 5.2 AnswerIsInvalid
1013
1431
  }
1014
1432
  }
1015
1433
  });