@tiledesk/tiledesk-tybot-connector 0.1.47 → 0.1.48
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.
- package/.env +1 -7
- package/CHANGELOG.md +4 -0
- package/TiledeskExpression.js +23 -5
- package/index.js +94 -72
- package/models/MockTdCache.js +1 -1
- package/models/MongodbIntentsMachine.js +2 -2
- package/models/TiledeskChatbot.js +40 -1
- package/package.json +4 -3
- package/test/anomaly-detection-test.js_ +173 -0
- package/test/check_steps_test.js +26 -0
- package/test/conversation-actions_bot.js +18 -7
- package/test/conversation-locked-intent-test.js +242 -0
- package/tiledeskChatbotPlugs/DirectivesChatbotPlug.js +19 -94
- package/tiledeskChatbotPlugs/FillParamsChatbotPlug.js +1 -1
- package/tiledeskChatbotPlugs/Filler.js +1 -1
- package/tiledeskChatbotPlugs/directives/DirMessage.js +7 -11
- package/tiledeskChatbotPlugs/directives/DirReplaceBot.js +13 -3
- package/tiledeskChatbotPlugs/directives/DirReply.js +89 -0
- package/tiledeskChatbotPlugs/directives/DirWait.js +2 -6
- package/tiledeskChatbotPlugs/directives/Directives.js +5 -1
package/.env
CHANGED
|
@@ -6,10 +6,4 @@ TYBOT_ENDPOINT=http://localhost:10001
|
|
|
6
6
|
_TYBOT_ENDPOINT=http://localhost:3000
|
|
7
7
|
CHATBOT_TOKEN=JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3ZWJob29rX2VuYWJsZWQiOmZhbHNlLCJ0eXBlIjoiZXh0ZXJuYWwiLCJsYW5ndWFnZSI6ImVuIiwicHVibGljIjpmYWxzZSwiX2lkIjoiNjM4Yzc5MDQxZGI0NDkwMDM1MTEwMjYwIiwibmFtZSI6IlRoZSBGb3JtIHYyIC0gZXh0IiwidXJsIjoiaHR0cHM6Ly90aWxlYm90LWRldi5oZXJva3VhcHAuY29tL2V4dC82MzhjNzhkNzFkYjQ0OTAwMzUxMTAxYzIiLCJpZF9wcm9qZWN0IjoiNjM4Yzc4YTYxZGI0NDkwMDM1MTBmZjkxIiwidHJhc2hlZCI6ZmFsc2UsImNyZWF0ZWRCeSI6IjVlMDlkMTZkNGQzNjExMDAxNzUwNmQ3ZiIsImNyZWF0ZWRBdCI6IjIwMjItMTItMDRUMTA6NDA6MDQuMjA3WiIsInVwZGF0ZWRBdCI6IjIwMjItMTItMDVUMDc6MjE6MDIuOTIxWiIsIl9fdiI6MCwiZGVzY3JpcHRpb24iOiJPbiBIZXJva3UiLCJpYXQiOjE2NzA2NzE4ODksImF1ZCI6Imh0dHBzOi8vdGlsZWRlc2suY29tL2JvdHMvNjM4Yzc5MDQxZGI0NDkwMDM1MTEwMjYwIiwiaXNzIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJzdWIiOiJib3QiLCJqdGkiOiJmNDVlZGIwYS0zNzVhLTQ0NjMtYjFhZi1jM2ZiZDg4YmE3ZGQifQ.FbW3csHl1sQgSyRz5Jg0qaTvvpXWXgWHlJ1JWoVbv3s
|
|
8
8
|
_CHATBOT_ENDPOINT=http://localhost:10001
|
|
9
|
-
|
|
10
|
-
TEST_PROJECT_ID=638c78a61db449003510ff91
|
|
11
|
-
TEST_BOT_ID=638c78d71db44900351101c2
|
|
12
|
-
|
|
13
|
-
TEST_ACTIONS_PROJECT_ID=63b2ab8fd0029e0035252df5
|
|
14
|
-
TEST_ACTIONS_BOT_ID=63b2aba4d0029e0035252ebb
|
|
15
|
-
ACTIONS_CHATBOT_TOKEN=JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ3ZWJob29rX2VuYWJsZWQiOmZhbHNlLCJ0eXBlIjoiZXh0ZXJuYWwiLCJsYW5ndWFnZSI6ImVuIiwicHVibGljIjpmYWxzZSwiY2VydGlmaWVkIjpmYWxzZSwiaW50ZW50c0VuZ2luZSI6Im5vbmUiLCJfaWQiOiI2M2IyYWJkY2QwMDI5ZTAwMzUyNTMyNGIiLCJuYW1lIjoiQWN0aW9ucyBCb3QgLSBleHQiLCJ1cmwiOiJodHRwczovL3RpbGVib3QtZGV2Lmhlcm9rdWFwcC5jb20vZXh0LzYzYjJhYmE0ZDAwMjllMDAzNTI1MmViYiIsImlkX3Byb2plY3QiOiI2M2IyYWI4ZmQwMDI5ZTAwMzUyNTJkZjUiLCJ0cmFzaGVkIjpmYWxzZSwiY3JlYXRlZEJ5IjoiNWUwOWQxNmQ0ZDM2MTEwMDE3NTA2ZDdmIiwiY3JlYXRlZEF0IjoiMjAyMy0wMS0wMlQxMDowMzowOC43NTVaIiwidXBkYXRlZEF0IjoiMjAyMy0wMS0wMlQxMDowMzo1MS4yOTZaIiwiX192IjowLCJpYXQiOjE2NzMzNzA5NzksImF1ZCI6Imh0dHBzOi8vdGlsZWRlc2suY29tL2JvdHMvNjNiMmFiZGNkMDAyOWUwMDM1MjUzMjRiIiwiaXNzIjoiaHR0cHM6Ly90aWxlZGVzay5jb20iLCJzdWIiOiJib3QiLCJqdGkiOiJjMTI2ZTk1Yi1lMGY2LTRmNDQtOTQ3NS0xN2IxNDMzYmY0MjEifQ.TWfVy7frEA98o596xCa-8hNnBAzBVhpYTz9p_zmNA4M
|
|
9
|
+
API_LOG=1
|
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,10 @@
|
|
|
5
5
|
available on:
|
|
6
6
|
▶️ https://www.npmjs.com/package/@tiledesk/tiledesk-tybot-connector
|
|
7
7
|
|
|
8
|
+
### 0.1.48
|
|
9
|
+
- fixed ReplaceBot "log" bug
|
|
10
|
+
- ReplaceBot fill-variables botName
|
|
11
|
+
|
|
8
12
|
### 0.1.47
|
|
9
13
|
- Introduced _tdIfOnlineAgents --trueIntent -- falseIntent
|
|
10
14
|
- Refactored _tdIfOpenHours --trueIntent -- falseIntent
|
package/TiledeskExpression.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const {VM} = require('vm2');
|
|
2
|
+
|
|
1
3
|
class TiledeskExpression {
|
|
2
4
|
// rules:
|
|
3
5
|
// check valid operators (only those in operators are allowed)
|
|
@@ -45,17 +47,33 @@ class TiledeskExpression {
|
|
|
45
47
|
}
|
|
46
48
|
|
|
47
49
|
// private
|
|
50
|
+
// evaluate(expression, context) {
|
|
51
|
+
// let fn;
|
|
52
|
+
// let res
|
|
53
|
+
// try {
|
|
54
|
+
// fn = Function(`let $data = this;return (${expression})`);
|
|
55
|
+
// res = fn.bind(context)()
|
|
56
|
+
// }
|
|
57
|
+
// catch (err) {
|
|
58
|
+
// console.error("TiledeskExpression.evaluate() error:", err.message, "evaluating expression: '" + expression + "'");
|
|
59
|
+
// }
|
|
60
|
+
// // let fn = Function(`let $data = this;console.log('data', $data);return (${conditionExpression})`);
|
|
61
|
+
// return res;
|
|
62
|
+
// }
|
|
63
|
+
|
|
48
64
|
evaluate(expression, context) {
|
|
49
|
-
let
|
|
50
|
-
let res
|
|
65
|
+
let res;
|
|
51
66
|
try {
|
|
52
|
-
|
|
53
|
-
|
|
67
|
+
const vm = new VM({
|
|
68
|
+
timeout: 200,
|
|
69
|
+
allowAsync: false,
|
|
70
|
+
sandbox: context
|
|
71
|
+
});
|
|
72
|
+
res = vm.run(`let $data = this;${expression}`);
|
|
54
73
|
}
|
|
55
74
|
catch (err) {
|
|
56
75
|
console.error("TiledeskExpression.evaluate() error:", err.message, "evaluating expression: '" + expression + "'");
|
|
57
76
|
}
|
|
58
|
-
// let fn = Function(`let $data = this;console.log('data', $data);return (${conditionExpression})`);
|
|
59
77
|
return res;
|
|
60
78
|
}
|
|
61
79
|
|
package/index.js
CHANGED
|
@@ -27,30 +27,31 @@ let log = false;
|
|
|
27
27
|
let tdcache = null;
|
|
28
28
|
|
|
29
29
|
// DEV
|
|
30
|
-
const { MessagePipeline } = require('./tiledeskChatbotPlugs/MessagePipeline');
|
|
30
|
+
// const { MessagePipeline } = require('./tiledeskChatbotPlugs/MessagePipeline');
|
|
31
31
|
const { DirectivesChatbotPlug } = require('./tiledeskChatbotPlugs/DirectivesChatbotPlug');
|
|
32
|
-
|
|
33
|
-
const { MarkbotChatbotPlug } = require('./tiledeskChatbotPlugs/MarkbotChatbotPlug')
|
|
34
|
-
const { WebhookChatbotPlug } = require('./tiledeskChatbotPlugs/WebhookChatbotPlug');
|
|
32
|
+
// const { SplitsChatbotPlug } = require('./tiledeskChatbotPlugs/SplitsChatbotPlug');
|
|
33
|
+
// const { MarkbotChatbotPlug } = require('./tiledeskChatbotPlugs/MarkbotChatbotPlug');
|
|
34
|
+
// const { WebhookChatbotPlug } = require('./tiledeskChatbotPlugs/WebhookChatbotPlug');
|
|
35
35
|
|
|
36
36
|
// PROD
|
|
37
|
-
|
|
38
|
-
const { DirectivesChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/DirectivesChatbotPlug');
|
|
39
|
-
const { SplitsChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/SplitsChatbotPlug');
|
|
40
|
-
const { MarkbotChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/MarkbotChatbotPlug');
|
|
41
|
-
const { WebhookChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/WebhookChatbotPlug')
|
|
37
|
+
// const { MessagePipeline } = require('@tiledesk/tiledesk-chatbot-plugs/MessagePipeline');
|
|
38
|
+
// const { DirectivesChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/DirectivesChatbotPlug');
|
|
39
|
+
// const { SplitsChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/SplitsChatbotPlug');
|
|
40
|
+
// const { MarkbotChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/MarkbotChatbotPlug');
|
|
41
|
+
// const { WebhookChatbotPlug } = require('@tiledesk/tiledesk-chatbot-plugs/WebhookChatbotPlug');
|
|
42
42
|
|
|
43
43
|
// THE IMPORT
|
|
44
44
|
let mongoose = require('mongoose');
|
|
45
|
-
const { DirSendEmail } = require('./tiledeskChatbotPlugs/directives/DirSendEmail.js');
|
|
45
|
+
// const { DirSendEmail } = require('./tiledeskChatbotPlugs/directives/DirSendEmail.js');
|
|
46
46
|
const { Directives } = require('./tiledeskChatbotPlugs/directives/Directives.js');
|
|
47
|
-
//let Faq = require('./models/faq');
|
|
48
|
-
//let Faq_kb = require('./models/faq_kb');
|
|
49
|
-
// let connection;
|
|
50
47
|
let APIURL = null;
|
|
51
48
|
let staticBots;
|
|
52
49
|
|
|
53
50
|
router.post('/ext/:botid', async (req, res) => {
|
|
51
|
+
if (req && req.body && req.body.payload && req.body.payload.request && req.body.payload.request.snapshot) {
|
|
52
|
+
delete req.body.payload.request.snapshot;
|
|
53
|
+
console.log("Removed req.body.payload.request.snapshot field");
|
|
54
|
+
}
|
|
54
55
|
if (log) {console.log("REQUEST BODY:", JSON.stringify(req.body));}
|
|
55
56
|
res.status(200).send({"success":true});
|
|
56
57
|
|
|
@@ -68,16 +69,6 @@ router.post('/ext/:botid', async (req, res) => {
|
|
|
68
69
|
if (message.request.id_project === null || message.request.id_project === undefined) {
|
|
69
70
|
message.request.id_project = projectId;
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
-
let requestSourcePage = null;
|
|
73
|
-
let requestLanguage = null;
|
|
74
|
-
let requestUserAgent = null;
|
|
75
|
-
|
|
76
|
-
if (message.payload) {
|
|
77
|
-
requestSourcePage = message.payload.sourcePage;
|
|
78
|
-
requestLanguage = message.payload.language;
|
|
79
|
-
requestUserAgent = message.payload.userAgent;
|
|
80
|
-
}
|
|
81
72
|
|
|
82
73
|
// NEXTTTTTTT
|
|
83
74
|
// const message_context = {
|
|
@@ -117,8 +108,10 @@ router.post('/ext/:botid', async (req, res) => {
|
|
|
117
108
|
|
|
118
109
|
let intentsMachine;
|
|
119
110
|
if (!staticBots) {
|
|
120
|
-
|
|
111
|
+
if (log) {console.log("intentsMachine to MongoDB");}
|
|
112
|
+
intentsMachine = new MongodbIntentsMachine({projectId: projectId, language: bot.language, log});
|
|
121
113
|
if (bot.intentsEngine === "tiledesk-ai") {
|
|
114
|
+
if (log) {console.log("intentsMachine to tiledesk-ai");}
|
|
122
115
|
intentsMachine = new TiledeskIntentsMachine(
|
|
123
116
|
{
|
|
124
117
|
//projectId: projectId,
|
|
@@ -146,60 +139,14 @@ router.post('/ext/:botid', async (req, res) => {
|
|
|
146
139
|
log: log
|
|
147
140
|
});
|
|
148
141
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
await chatbot.addParameter("_tdProjectId", projectId);
|
|
152
|
-
await chatbot.addParameter("_tdRequestId", requestId);
|
|
153
|
-
if (message.request && message.request.location && message.request.location.country) {
|
|
154
|
-
await chatbot.addParameter("_tdCountry", message.request.location.country);
|
|
155
|
-
}
|
|
156
|
-
if (message.request && message.request.location && message.request.location.city) {
|
|
157
|
-
await chatbot.addParameter("_tdCity", message.request.location.city);
|
|
158
|
-
}
|
|
159
|
-
if (message.text) {
|
|
160
|
-
await chatbot.addParameter("_tdUserText", message.text);
|
|
161
|
-
}
|
|
162
|
-
if (requestSourcePage) {
|
|
163
|
-
await chatbot.addParameter("_tdRequestSourcePage", sourcePage);
|
|
164
|
-
}
|
|
165
|
-
if (requestLanguage) {
|
|
166
|
-
await chatbot.addParameter("_tdRequestLanguage", language);
|
|
167
|
-
}
|
|
168
|
-
if (requestUserAgent) {
|
|
169
|
-
await chatbot.addParameter("_tdRequestUserAgent", userAgent);
|
|
170
|
-
}
|
|
142
|
+
await updateRequestVariables(chatbot, message, projectId, requestId);
|
|
143
|
+
|
|
171
144
|
let reply = await chatbot.replyToMessage(message);
|
|
172
145
|
if (!reply) {
|
|
173
146
|
reply = {
|
|
174
147
|
"text": "No messages found. Is 'defaultFallback' intent missing?"
|
|
175
148
|
}
|
|
176
149
|
}
|
|
177
|
-
// console.log("reply back:", JSON.stringify(reply));
|
|
178
|
-
|
|
179
|
-
// TEMP
|
|
180
|
-
// if (reply.attributes && reply.attributes.intent_info) {
|
|
181
|
-
// switch (reply.attributes.intent_info.intent_name) {
|
|
182
|
-
// case "MessageActions":
|
|
183
|
-
// reply.actions = MockActions.MessageActions()
|
|
184
|
-
// break;
|
|
185
|
-
// case "Message_plus_Agent":
|
|
186
|
-
// reply.actions = MockActions.Message_plus_Agent();
|
|
187
|
-
// break;
|
|
188
|
-
// case "Message_plus_AgentWhenOnline":
|
|
189
|
-
// reply.actions = MockActions.Message_plus_AgentWhenOnline();
|
|
190
|
-
// break;
|
|
191
|
-
// case "Message_plus_Close":
|
|
192
|
-
// reply.actions = MockActions.Message_plus_Close();
|
|
193
|
-
// break;
|
|
194
|
-
// case "ChangeDepartment":
|
|
195
|
-
// reply.actions = MockActions.ChangeDepartment();
|
|
196
|
-
// break;
|
|
197
|
-
// case "Intent":
|
|
198
|
-
// reply.actions = MockActions.Intent();
|
|
199
|
-
// break;
|
|
200
|
-
// }
|
|
201
|
-
// }
|
|
202
|
-
|
|
203
150
|
|
|
204
151
|
// console.log("reply.actions:", reply.actions);
|
|
205
152
|
if (reply.actions && reply.actions.length > 0) { // structured actions (coming from chatbot designer)
|
|
@@ -250,6 +197,81 @@ router.post('/ext/:botid', async (req, res) => {
|
|
|
250
197
|
|
|
251
198
|
});
|
|
252
199
|
|
|
200
|
+
async function updateRequestVariables(chatbot, message, projectId, requestId) {
|
|
201
|
+
// update request context
|
|
202
|
+
const messageId = message._id;
|
|
203
|
+
await chatbot.addParameter("_tdProjectId", projectId);
|
|
204
|
+
await chatbot.addParameter("_tdRequestId", requestId);
|
|
205
|
+
if (message.text) {
|
|
206
|
+
await chatbot.addParameter("_tdLastUserText", message.text);
|
|
207
|
+
}
|
|
208
|
+
await chatbot.addParameter("_tdLastMessageId", messageId);
|
|
209
|
+
if (message.request && message.request.location && message.request.location.country) {
|
|
210
|
+
await chatbot.addParameter("_tdCountry", message.request.location.country);
|
|
211
|
+
}
|
|
212
|
+
if (message.request && message.request.location && message.request.location.city) {
|
|
213
|
+
await chatbot.addParameter("_tdCity", message.request.location.city);
|
|
214
|
+
}
|
|
215
|
+
await chatbot.addParameter("_tdRequestSourcePage", message.sourcePage);
|
|
216
|
+
await chatbot.addParameter("_tdRequestLanguage", message.language);
|
|
217
|
+
await chatbot.addParameter("_tdRequestUserAgent", message.userAgent);
|
|
218
|
+
|
|
219
|
+
if (message.attributes) {
|
|
220
|
+
await chatbot.addParameter("_tdRequestDepartmentId", message.attributes.departmentId);
|
|
221
|
+
await chatbot.addParameter("_tdRequestDepartmentName", message.attributes.departmentName);
|
|
222
|
+
await chatbot.addParameter("_tdRequestRequesterId", message.attributes.requester_id);
|
|
223
|
+
await chatbot.addParameter("_tdRequestIpAddress", message.attributes.ipAddress);
|
|
224
|
+
if (message.attributes.payload) {
|
|
225
|
+
try {
|
|
226
|
+
for (const [key, value] of Object.entries(message.attributes.payload)) {
|
|
227
|
+
// const value = all_parameters[key];
|
|
228
|
+
const value_type = typeof value;
|
|
229
|
+
if (chatbot.log) {console.log("importing payload parameter:", key, "value:", value, "type:", value_type)}
|
|
230
|
+
await chatbot.addParameter(key, String(value));
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
catch(err) {
|
|
234
|
+
console.error("Error importing message payload in request variables:", err);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
if (chatbot.log) {
|
|
239
|
+
const all_parameters = await TiledeskChatbot.allParametersStatic(chatbot.tdcache, requestId);
|
|
240
|
+
for (const [key, value] of Object.entries(all_parameters)) {
|
|
241
|
+
// const value = all_parameters[key];
|
|
242
|
+
const value_type = typeof value;
|
|
243
|
+
if (chatbot.log) {console.log("request parameter:", key, "value:", value, "type:", value_type)}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
// message["attributes"]: {
|
|
247
|
+
// "departmentId": "63c980054f857c00350535bc",
|
|
248
|
+
// "departmentName": "Default Department",
|
|
249
|
+
// "client": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36",
|
|
250
|
+
// "sourcePage": "https://tiledesk-html-site.tiledesk.repl.co/custom-attributes.html",
|
|
251
|
+
// "projectId": "63c980054f857c00350535b8",
|
|
252
|
+
// "payload": {
|
|
253
|
+
// "user_country": "Italy",
|
|
254
|
+
// "user_code": "E001"
|
|
255
|
+
// },
|
|
256
|
+
// "userFullname": "guest#7216 ",
|
|
257
|
+
// "requester_id": "7216926a-84c3-4bd5-aa79-8bd763094dc0",
|
|
258
|
+
// "ipAddress": "79.8.190.172",
|
|
259
|
+
// "sourceTitle": "Custom attributes",
|
|
260
|
+
// "widgetVer": "v.5.0.53-rc.4",
|
|
261
|
+
// "subtype": "info",
|
|
262
|
+
// "decoded_jwt": {
|
|
263
|
+
// "_id": "7216926a-84c3-4bd5-aa79-8bd763094dc0",
|
|
264
|
+
// "firstname": "guest#7216",
|
|
265
|
+
// "id": "7216926a-84c3-4bd5-aa79-8bd763094dc0",
|
|
266
|
+
// "fullName": "guest#7216 ",
|
|
267
|
+
// "iat": 1674201892,
|
|
268
|
+
// "aud": "https://tiledesk.com",
|
|
269
|
+
// "iss": "https://tiledesk.com",
|
|
270
|
+
// "sub": "guest",
|
|
271
|
+
// "jti": "f053af3d-14ca-411b-9903-78bd74e24218"
|
|
272
|
+
// }
|
|
273
|
+
}
|
|
274
|
+
|
|
253
275
|
function actionsToDirectives(actions) {
|
|
254
276
|
let directives = [];
|
|
255
277
|
if (actions && actions.length > 0) {
|
package/models/MockTdCache.js
CHANGED
|
@@ -19,7 +19,7 @@ class MongodbIntentsMachine {
|
|
|
19
19
|
*/
|
|
20
20
|
async decode(botId, text) {
|
|
21
21
|
return new Promise( (resolve, reject) => {
|
|
22
|
-
if (this.log) {console.log("NLP decode intent...");}
|
|
22
|
+
if (this.log) {console.log("Mongodb NLP decode intent...");}
|
|
23
23
|
let query = { "id_project": this.projectId, "id_faq_kb": botId };
|
|
24
24
|
var mongoproject = undefined;
|
|
25
25
|
var sort = undefined;
|
|
@@ -37,7 +37,7 @@ class MongodbIntentsMachine {
|
|
|
37
37
|
if (err) {
|
|
38
38
|
console.error("Error:", err);
|
|
39
39
|
}
|
|
40
|
-
if (faqs && faqs.length > 0
|
|
40
|
+
if (faqs && faqs.length > 0) {
|
|
41
41
|
resolve(faqs);
|
|
42
42
|
}
|
|
43
43
|
else {
|
|
@@ -12,6 +12,8 @@ const { DirUnlockIntent } = require('../tiledeskChatbotPlugs/directives/DirUnloc
|
|
|
12
12
|
|
|
13
13
|
class TiledeskChatbot {
|
|
14
14
|
|
|
15
|
+
static MAX_STEPS = 20;
|
|
16
|
+
|
|
15
17
|
constructor(config) {
|
|
16
18
|
if (!config.botsDataSource) {
|
|
17
19
|
throw new Error("config.botsDataSource is mandatory");
|
|
@@ -61,6 +63,11 @@ class TiledeskChatbot {
|
|
|
61
63
|
console.log("replyToMessage() > lead found:", JSON.stringify(lead));
|
|
62
64
|
}
|
|
63
65
|
|
|
66
|
+
// any external invocation restarts the steps counter
|
|
67
|
+
// if (message.sender != "_tdinternal") {
|
|
68
|
+
// await TiledeskChatbot.resetStep(this.tdcache, this.requestId);
|
|
69
|
+
// }
|
|
70
|
+
|
|
64
71
|
// Checking locked intent (for non-internal intents)
|
|
65
72
|
// internal intents always "skip" the locked intent
|
|
66
73
|
// if (message.text.startsWith("/") && message.sender != "_tdinternal") {
|
|
@@ -184,7 +191,7 @@ class TiledeskChatbot {
|
|
|
184
191
|
return;
|
|
185
192
|
}
|
|
186
193
|
else { // NLP
|
|
187
|
-
if (this.log) {console.log("NLP decode intent...");}
|
|
194
|
+
if (this.log) {console.log("Chatbot NLP decode intent...");}
|
|
188
195
|
let intents;
|
|
189
196
|
try {
|
|
190
197
|
intents = await this.intentsFinder.decode(this.botId, message.text);
|
|
@@ -210,7 +217,9 @@ class TiledeskChatbot {
|
|
|
210
217
|
else {
|
|
211
218
|
// fallback
|
|
212
219
|
let fallbackIntent = await this.botsDataSource.getByIntentDisplayName(this.botId, "defaultFallback");
|
|
220
|
+
console.log("fallbackIntent found", fallbackIntent);
|
|
213
221
|
if (!fallbackIntent) {
|
|
222
|
+
console.log("No defaultFallback found!");
|
|
214
223
|
resolve(null);
|
|
215
224
|
return;
|
|
216
225
|
}
|
|
@@ -449,6 +458,36 @@ class TiledeskChatbot {
|
|
|
449
458
|
await _tdcache.hset(parameter_key, parameter_name, parameter_value);
|
|
450
459
|
}
|
|
451
460
|
|
|
461
|
+
static async checkStep(_tdcache, requestId, max_steps) {
|
|
462
|
+
let go_on = true;
|
|
463
|
+
const parameter_key = TiledeskChatbot.requestCacheKey(requestId) + ":step";
|
|
464
|
+
console.log("parameter_key:", parameter_key);
|
|
465
|
+
let _current_step = await _tdcache.get(parameter_key);
|
|
466
|
+
if (!_current_step) { // this shouldn't be happening
|
|
467
|
+
_current_step = 0;
|
|
468
|
+
}
|
|
469
|
+
console.log("_current_step:", _current_step);
|
|
470
|
+
let current_step = Number(_current_step);
|
|
471
|
+
console.log("current_step:", current_step);
|
|
472
|
+
if (current_step > max_steps) {
|
|
473
|
+
console.log("current_step > max_steps!", current_step);
|
|
474
|
+
await TiledeskChatbot.resetStep(_tdcache, requestId);
|
|
475
|
+
go_on = false;
|
|
476
|
+
}
|
|
477
|
+
else {
|
|
478
|
+
console.log("current_step < max_steps :)", current_step);
|
|
479
|
+
current_step += 1;
|
|
480
|
+
await _tdcache.set(parameter_key, current_step); // increment step
|
|
481
|
+
console.log("current_step from cache:", await _tdcache.get(parameter_key));
|
|
482
|
+
}
|
|
483
|
+
return go_on;
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
static async resetStep(_tdcache, requestId) {
|
|
487
|
+
const parameter_key = TiledeskChatbot.requestCacheKey(requestId) + ":step";
|
|
488
|
+
await _tdcache.set(parameter_key, 0);
|
|
489
|
+
}
|
|
490
|
+
|
|
452
491
|
async allParameters() {
|
|
453
492
|
return await TiledeskChatbot.allParametersStatic(this.tdcache, this.requestId);
|
|
454
493
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tiledesk/tiledesk-tybot-connector",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.48",
|
|
4
4
|
"description": "Tiledesk Tybot connector",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"@tiledesk/helpcenter-query-client": "^0.1.8",
|
|
15
15
|
"@tiledesk/tiledesk-chatbot-client": "^0.5.30",
|
|
16
16
|
"@tiledesk/tiledesk-chatbot-util": "^0.8.39",
|
|
17
|
-
"@tiledesk/tiledesk-client": "^0.9.
|
|
17
|
+
"@tiledesk/tiledesk-client": "^0.9.6",
|
|
18
18
|
"axios": "^0.27.2",
|
|
19
19
|
"body-parser": "^1.19.0",
|
|
20
20
|
"cors": "^2.8.5",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"mongoose": "^6.3.5",
|
|
27
27
|
"nanoid": "^3.1.25",
|
|
28
28
|
"redis": "^3.1.2",
|
|
29
|
-
"uuid": "^3.3.3"
|
|
29
|
+
"uuid": "^3.3.3",
|
|
30
|
+
"vm2": "^3.9.13"
|
|
30
31
|
}
|
|
31
32
|
}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
var assert = require('assert');
|
|
2
|
+
let axios = require('axios');
|
|
3
|
+
const tybot = require("../");
|
|
4
|
+
const tybotRoute = tybot.router;
|
|
5
|
+
var express = require('express');
|
|
6
|
+
var app = express();
|
|
7
|
+
app.use("/", tybotRoute);
|
|
8
|
+
app.use((err, req, res, next) => {
|
|
9
|
+
console.error("General error", err);
|
|
10
|
+
});
|
|
11
|
+
require('dotenv').config();
|
|
12
|
+
const bodyParser = require('body-parser');
|
|
13
|
+
const { v4: uuidv4 } = require('uuid');
|
|
14
|
+
const bots_data = require('./conversation-actions_bot.js').bots_data;
|
|
15
|
+
|
|
16
|
+
const PROJECT_ID = "projectID"; //process.env.TEST_ACTIONS_PROJECT_ID;
|
|
17
|
+
const REQUEST_ID = "support-group-" + PROJECT_ID + "-" + uuidv4().replace(/-/g, "");
|
|
18
|
+
const BOT_ID = "botID"; //process.env.TEST_ACTIONS_BOT_ID;
|
|
19
|
+
const CHATBOT_TOKEN = "XXX"; //process.env.ACTIONS_CHATBOT_TOKEN;
|
|
20
|
+
|
|
21
|
+
describe('Conversation for anomaly detection test', async () => {
|
|
22
|
+
|
|
23
|
+
let app_listener;
|
|
24
|
+
|
|
25
|
+
before(() => {
|
|
26
|
+
return new Promise(async (resolve, reject) => {
|
|
27
|
+
console.log("Starting tilebot server...");
|
|
28
|
+
tybot.startApp(
|
|
29
|
+
{
|
|
30
|
+
// MONGODB_URI: process.env.mongoUrl,
|
|
31
|
+
bots: bots_data,
|
|
32
|
+
API_ENDPOINT: process.env.API_ENDPOINT,
|
|
33
|
+
REDIS_HOST: process.env.REDIS_HOST,
|
|
34
|
+
REDIS_PORT: process.env.REDIS_PORT,
|
|
35
|
+
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
|
36
|
+
log: process.env.API_LOG
|
|
37
|
+
}, () => {
|
|
38
|
+
console.log("ACTIONS Tilebot route successfully started.");
|
|
39
|
+
var port = process.env.PORT || 10001;
|
|
40
|
+
app_listener = app.listen(port, () => {
|
|
41
|
+
console.log('Tilebot connector listening on port ', port);
|
|
42
|
+
resolve();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
after(function (done) {
|
|
49
|
+
app_listener.close(() => {
|
|
50
|
+
// console.log('ACTIONS app_listener closed.');
|
|
51
|
+
done();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('/anomaly', (done) => {
|
|
56
|
+
console.log("/anomaly story...");
|
|
57
|
+
let message_id = uuidv4();
|
|
58
|
+
let listener;
|
|
59
|
+
let endpointServer = express();
|
|
60
|
+
endpointServer.use(bodyParser.json());
|
|
61
|
+
endpointServer.post('/:projectId/requests/:requestId/messages', function (req, res) {
|
|
62
|
+
console.log("...req.body:", JSON.stringify(req.body));
|
|
63
|
+
res.send({ success: true });
|
|
64
|
+
const message = req.body;
|
|
65
|
+
assert(message.attributes.error !== null);
|
|
66
|
+
assert(message.attributes.error.message !== null);
|
|
67
|
+
assert(message.attributes.error.message === "Request anomaly detection");
|
|
68
|
+
listener.close(() => {
|
|
69
|
+
done();
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
listener = endpointServer.listen(10002, '0.0.0.0', () => {
|
|
74
|
+
// console.log('endpointServer started', listener.address());
|
|
75
|
+
let request = {
|
|
76
|
+
"payload": {
|
|
77
|
+
"_id": message_id,
|
|
78
|
+
"senderFullname": "guest#367e",
|
|
79
|
+
"type": "text",
|
|
80
|
+
"sender": "A-SENDER",
|
|
81
|
+
"recipient": REQUEST_ID,
|
|
82
|
+
"text": "/anomaly",
|
|
83
|
+
"id_project": PROJECT_ID,
|
|
84
|
+
"metadata": "",
|
|
85
|
+
"request": {
|
|
86
|
+
"request_id": REQUEST_ID
|
|
87
|
+
}
|
|
88
|
+
},
|
|
89
|
+
"token": CHATBOT_TOKEN
|
|
90
|
+
}
|
|
91
|
+
sendMessageToBot(request, BOT_ID, () => {
|
|
92
|
+
console.log("Message sent:\n", request);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* A stub to send message to the "ext/botId" endpoint, hosted by tilebot on:
|
|
102
|
+
* /${TILEBOT_ROUTE}/ext/${botId}
|
|
103
|
+
*
|
|
104
|
+
* @param {Object} message. The message to send
|
|
105
|
+
* @param {string} botId. Tiledesk botId
|
|
106
|
+
* @param {string} token. User token
|
|
107
|
+
*/
|
|
108
|
+
function sendMessageToBot(message, botId, callback) {
|
|
109
|
+
// const jwt_token = this.fixToken(token);
|
|
110
|
+
const url = `${process.env.TYBOT_ENDPOINT}/ext/${botId}`;
|
|
111
|
+
// console.log("sendMessageToBot URL", url);
|
|
112
|
+
const HTTPREQUEST = {
|
|
113
|
+
url: url,
|
|
114
|
+
headers: {
|
|
115
|
+
'Content-Type': 'application/json'
|
|
116
|
+
},
|
|
117
|
+
json: message,
|
|
118
|
+
method: 'POST'
|
|
119
|
+
};
|
|
120
|
+
myrequest(
|
|
121
|
+
HTTPREQUEST,
|
|
122
|
+
function (err, resbody) {
|
|
123
|
+
if (err) {
|
|
124
|
+
if (callback) {
|
|
125
|
+
callback(err);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
if (callback) {
|
|
130
|
+
callback(null, resbody);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
}, false
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
function myrequest(options, callback, log) {
|
|
138
|
+
if (log) {
|
|
139
|
+
console.log("API URL:", options.url);
|
|
140
|
+
console.log("** Options:", JSON.stringify(options));
|
|
141
|
+
}
|
|
142
|
+
axios(
|
|
143
|
+
{
|
|
144
|
+
url: options.url,
|
|
145
|
+
method: options.method,
|
|
146
|
+
data: options.json,
|
|
147
|
+
params: options.params,
|
|
148
|
+
headers: options.headers
|
|
149
|
+
})
|
|
150
|
+
.then((res) => {
|
|
151
|
+
if (log) {
|
|
152
|
+
console.log("Response for url:", options.url);
|
|
153
|
+
console.log("Response headers:\n", JSON.stringify(res.headers));
|
|
154
|
+
//console.log("******** Response for url:", res);
|
|
155
|
+
}
|
|
156
|
+
if (res && res.status == 200 && res.data) {
|
|
157
|
+
if (callback) {
|
|
158
|
+
callback(null, res.data);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
if (callback) {
|
|
163
|
+
callback(TiledeskClient.getErr({ message: "Response status not 200" }, options, res), null, null);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
})
|
|
167
|
+
.catch((error) => {
|
|
168
|
+
console.error("An error occurred:", error);
|
|
169
|
+
if (callback) {
|
|
170
|
+
callback(error, null, null);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
var assert = require('assert');
|
|
2
|
+
const { TiledeskChatbot } = require('../models/TiledeskChatbot.js');
|
|
3
|
+
const { MockTdCache } = require('../models/MockTdCache');
|
|
4
|
+
const { v4: uuidv4 } = require('uuid');
|
|
5
|
+
|
|
6
|
+
describe('checkStep()', function() {
|
|
7
|
+
|
|
8
|
+
it('checkStep() function', async () => {
|
|
9
|
+
const MAX_STEPS = 20;
|
|
10
|
+
const requestId = uuidv4();
|
|
11
|
+
const tdcache = new MockTdCache();
|
|
12
|
+
let i;
|
|
13
|
+
// trying to brute-pass MAX_STEPS limit by doubling it
|
|
14
|
+
for (i = 0; i < MAX_STEPS * 2; i++) {
|
|
15
|
+
console.log("i: " + i);
|
|
16
|
+
let go_on = await TiledeskChatbot.checkStep(tdcache, requestId, MAX_STEPS);
|
|
17
|
+
console.log("go on?", go_on);
|
|
18
|
+
if (!go_on) {
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
console.log("last i: " + i);
|
|
23
|
+
assert(i === MAX_STEPS + 1);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
});
|
|
@@ -21,7 +21,7 @@ const bot = {
|
|
|
21
21
|
"enabled": true,
|
|
22
22
|
"question": "***",
|
|
23
23
|
"actions": [{
|
|
24
|
-
"
|
|
24
|
+
"_tdActionType": "message",
|
|
25
25
|
"attributes": {
|
|
26
26
|
"commands": [{
|
|
27
27
|
"type": "message",
|
|
@@ -58,7 +58,7 @@ const bot = {
|
|
|
58
58
|
"question": "***",
|
|
59
59
|
"answer": "***",
|
|
60
60
|
"actions": [{
|
|
61
|
-
"
|
|
61
|
+
"_tdActionType": "message",
|
|
62
62
|
"attributes": {
|
|
63
63
|
"commands": [{
|
|
64
64
|
"type": "message",
|
|
@@ -79,7 +79,7 @@ const bot = {
|
|
|
79
79
|
"question": "***",
|
|
80
80
|
"answer": "***",
|
|
81
81
|
"actions": [{
|
|
82
|
-
"
|
|
82
|
+
"_tdActionType": "message",
|
|
83
83
|
"attributes": {
|
|
84
84
|
"commands": [{
|
|
85
85
|
"type": "message",
|
|
@@ -100,7 +100,7 @@ const bot = {
|
|
|
100
100
|
"question": "***",
|
|
101
101
|
"answer": "***",
|
|
102
102
|
"actions": [{
|
|
103
|
-
"
|
|
103
|
+
"_tdActionType": "message",
|
|
104
104
|
"attributes": {
|
|
105
105
|
"commands": [{
|
|
106
106
|
"type": "message",
|
|
@@ -122,10 +122,10 @@ const bot = {
|
|
|
122
122
|
"answer": "***",
|
|
123
123
|
"actions": [
|
|
124
124
|
{
|
|
125
|
-
"
|
|
125
|
+
"_tdActionType": "department",
|
|
126
126
|
"depName": "Support"
|
|
127
127
|
}, {
|
|
128
|
-
"
|
|
128
|
+
"_tdActionType": "message",
|
|
129
129
|
"text": "/start",
|
|
130
130
|
"attributes": {
|
|
131
131
|
"subtype": "info"
|
|
@@ -139,7 +139,7 @@ const bot = {
|
|
|
139
139
|
"question": "***",
|
|
140
140
|
"answer": "***",
|
|
141
141
|
"actions": [{
|
|
142
|
-
"
|
|
142
|
+
"_tdActionType": "intent",
|
|
143
143
|
"intentName": "intentAction"
|
|
144
144
|
}],
|
|
145
145
|
"language": "en",
|
|
@@ -202,6 +202,17 @@ const bot = {
|
|
|
202
202
|
"answer": "Eureka!\nThis is the reply for **intentAction4**\n* /start",
|
|
203
203
|
"language": "en",
|
|
204
204
|
"intent_display_name": "intentAction4"
|
|
205
|
+
}, {
|
|
206
|
+
"webhook_enabled": false,
|
|
207
|
+
"enabled": true,
|
|
208
|
+
"question": "***",
|
|
209
|
+
"answer": "***",
|
|
210
|
+
"actions": [{
|
|
211
|
+
"_tdActionType": "intent",
|
|
212
|
+
"intentName": "anomaly"
|
|
213
|
+
}],
|
|
214
|
+
"language": "en",
|
|
215
|
+
"intent_display_name": "anomaly"
|
|
205
216
|
}]
|
|
206
217
|
}
|
|
207
218
|
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
var assert = require('assert');
|
|
2
|
+
let axios = require('axios');
|
|
3
|
+
const tybot = require("../");
|
|
4
|
+
const tybotRoute = tybot.router;
|
|
5
|
+
var express = require('express');
|
|
6
|
+
var app = express();
|
|
7
|
+
app.use("/", tybotRoute);
|
|
8
|
+
app.use((err, req, res, next) => {
|
|
9
|
+
console.error("General error", err);
|
|
10
|
+
});
|
|
11
|
+
require('dotenv').config();
|
|
12
|
+
const bodyParser = require('body-parser');
|
|
13
|
+
const { v4: uuidv4 } = require('uuid');
|
|
14
|
+
const bots_data = require('./conversation-form_bot.js').bots_data;
|
|
15
|
+
|
|
16
|
+
const PROJECT_ID = "projectID"; //const PROJECT_ID = process.env.TEST_PROJECT_ID;
|
|
17
|
+
const REQUEST_ID = "support-group-" + PROJECT_ID + "-" + uuidv4().replace(/-/g, "");
|
|
18
|
+
const BOT_ID = "botID";
|
|
19
|
+
const CHATBOT_TOKEN = process.env.CHATBOT_TOKEN;
|
|
20
|
+
|
|
21
|
+
let app_listener;
|
|
22
|
+
|
|
23
|
+
describe('Conversation1 - Form filling', async () => {
|
|
24
|
+
|
|
25
|
+
before(() => {
|
|
26
|
+
return new Promise(async (resolve, reject) => {
|
|
27
|
+
console.log("Starting tilebot server...");
|
|
28
|
+
tybot.startApp(
|
|
29
|
+
{
|
|
30
|
+
// MONGODB_URI: process.env.mongoUrl,
|
|
31
|
+
bots: bots_data,
|
|
32
|
+
API_ENDPOINT: process.env.API_ENDPOINT,
|
|
33
|
+
REDIS_HOST: process.env.REDIS_HOST,
|
|
34
|
+
REDIS_PORT: process.env.REDIS_PORT,
|
|
35
|
+
REDIS_PASSWORD: process.env.REDIS_PASSWORD,
|
|
36
|
+
log: process.env.API_LOG
|
|
37
|
+
}, () => {
|
|
38
|
+
console.log("Tilebot route successfully started.");
|
|
39
|
+
var port = process.env.PORT || 10001;
|
|
40
|
+
app_listener = app.listen(port, () => {
|
|
41
|
+
console.log('Tilebot connector listening on port ', port);
|
|
42
|
+
resolve();
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
})
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
after(function (done) {
|
|
49
|
+
app_listener.close(() => {
|
|
50
|
+
// console.log('CONVERSATION FORM app_listener closed.');
|
|
51
|
+
done();
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
it('/locked', (done) => {
|
|
56
|
+
// console.log("/locked...");
|
|
57
|
+
let request0_uuid = uuidv4();
|
|
58
|
+
let request1_uuid = uuidv4();
|
|
59
|
+
let request2_uuid = uuidv4();
|
|
60
|
+
let request3_uuid = uuidv4();
|
|
61
|
+
let listener;
|
|
62
|
+
let endpointServer = express();
|
|
63
|
+
endpointServer.use(bodyParser.json());
|
|
64
|
+
endpointServer.post('/:projectId/requests/:requestId/messages', function (req, res) {
|
|
65
|
+
res.send({ success: true });
|
|
66
|
+
const message = req.body;
|
|
67
|
+
if (message.text.startsWith("Hi welcome to this dialog.")) {
|
|
68
|
+
console.log("got #0 sending #1", message.text);
|
|
69
|
+
let request = {
|
|
70
|
+
"payload": {
|
|
71
|
+
"_id": request1_uuid,
|
|
72
|
+
"senderFullname": "guest#367e",
|
|
73
|
+
"type": "text",
|
|
74
|
+
"sender": "A-SENDER",
|
|
75
|
+
"recipient": REQUEST_ID,
|
|
76
|
+
"text": "/dialog_question2",
|
|
77
|
+
"id_project": PROJECT_ID,
|
|
78
|
+
"request": {
|
|
79
|
+
"request_id": REQUEST_ID,
|
|
80
|
+
"id_project": PROJECT_ID
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
"token": CHATBOT_TOKEN
|
|
84
|
+
}
|
|
85
|
+
sendMessageToBot(request, BOT_ID, CHATBOT_TOKEN, () => {
|
|
86
|
+
// console.log("Message sent.", request);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
else if (message.text.startsWith("As I told you,")) {
|
|
90
|
+
console.log("got #1 sending #2", message.text);
|
|
91
|
+
let request = {
|
|
92
|
+
"payload": {
|
|
93
|
+
"_id": request2_uuid,
|
|
94
|
+
"senderFullname": "guest#367e",
|
|
95
|
+
"type": "text",
|
|
96
|
+
"sender": "A-SENDER",
|
|
97
|
+
"recipient": REQUEST_ID,
|
|
98
|
+
"text": "/dialog_question3",
|
|
99
|
+
"id_project": PROJECT_ID,
|
|
100
|
+
"request": {
|
|
101
|
+
"request_id": REQUEST_ID,
|
|
102
|
+
"id_project": PROJECT_ID
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"token": CHATBOT_TOKEN
|
|
106
|
+
}
|
|
107
|
+
sendMessageToBot(request, BOT_ID, CHATBOT_TOKEN, () => {
|
|
108
|
+
// console.log("Message sent4.", request);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
else if (message.text.startsWith("And now tell me,")) {
|
|
112
|
+
console.log("got #2 sending #3", message.text);
|
|
113
|
+
let request = {
|
|
114
|
+
"payload": {
|
|
115
|
+
"_id": request3_uuid,
|
|
116
|
+
"senderFullname": "guest#367e",
|
|
117
|
+
"type": "text",
|
|
118
|
+
"sender": "A-SENDER",
|
|
119
|
+
"recipient": REQUEST_ID,
|
|
120
|
+
"text": "/dialog_question4",
|
|
121
|
+
"id_project": PROJECT_ID,
|
|
122
|
+
"request": {
|
|
123
|
+
"request_id": REQUEST_ID,
|
|
124
|
+
"id_project": PROJECT_ID
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"token": CHATBOT_TOKEN
|
|
128
|
+
}
|
|
129
|
+
sendMessageToBot(request, BOT_ID, CHATBOT_TOKEN, () => {
|
|
130
|
+
// console.log("Message sent5.", request);
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
else if (message.text.startsWith("Well, survey completed!")) {
|
|
134
|
+
// console.log("got #4. End.", message.text);
|
|
135
|
+
listener.close(() => {
|
|
136
|
+
done();
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
listener = endpointServer.listen(10002, '0.0.0.0', function () {
|
|
143
|
+
// console.log('endpointServer started', listener.address());
|
|
144
|
+
// console.log("REQUEST_ID:", REQUEST_ID);
|
|
145
|
+
let request = {
|
|
146
|
+
"payload": {
|
|
147
|
+
"_id": request0_uuid,
|
|
148
|
+
"senderFullname": "guest#367e",
|
|
149
|
+
"type": "text",
|
|
150
|
+
"sender": "A-SENDER",
|
|
151
|
+
"recipient": REQUEST_ID,
|
|
152
|
+
"text": "/dialog_start",
|
|
153
|
+
"id_project": PROJECT_ID,
|
|
154
|
+
"request": {
|
|
155
|
+
"request_id": REQUEST_ID,
|
|
156
|
+
"id_project": PROJECT_ID
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
"token": CHATBOT_TOKEN
|
|
160
|
+
}
|
|
161
|
+
// console.log("sending message:", request);
|
|
162
|
+
sendMessageToBot(request, BOT_ID, CHATBOT_TOKEN, () => {
|
|
163
|
+
// console.log("Message sent.");
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* A stub to send message to the "ext/botId" endpoint, hosted by tilebot on:
|
|
171
|
+
* /${TILEBOT_ROUTE}/ext/${botId}
|
|
172
|
+
*
|
|
173
|
+
* @param {Object} message. The message to send
|
|
174
|
+
* @param {string} botId. Tiledesk botId
|
|
175
|
+
* @param {string} token. User token
|
|
176
|
+
*/
|
|
177
|
+
function sendMessageToBot(message, botId, token, callback) {
|
|
178
|
+
// const jwt_token = this.fixToken(token);
|
|
179
|
+
const url = `${process.env.TYBOT_ENDPOINT}/ext/${botId}`;
|
|
180
|
+
// console.log("sendMessageToBot URL", url);
|
|
181
|
+
const HTTPREQUEST = {
|
|
182
|
+
url: url,
|
|
183
|
+
headers: {
|
|
184
|
+
'Content-Type': 'application/json'
|
|
185
|
+
},
|
|
186
|
+
json: message,
|
|
187
|
+
method: 'POST'
|
|
188
|
+
};
|
|
189
|
+
myrequest(
|
|
190
|
+
HTTPREQUEST,
|
|
191
|
+
function (err, resbody) {
|
|
192
|
+
if (err) {
|
|
193
|
+
if (callback) {
|
|
194
|
+
callback(err);
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
if (callback) {
|
|
199
|
+
callback(null, resbody);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}, false
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function myrequest(options, callback, log) {
|
|
207
|
+
if (log) {
|
|
208
|
+
console.log("API URL:", options.url);
|
|
209
|
+
console.log("** Options:", JSON.stringify(options));
|
|
210
|
+
}
|
|
211
|
+
axios(
|
|
212
|
+
{
|
|
213
|
+
url: options.url,
|
|
214
|
+
method: options.method,
|
|
215
|
+
data: options.json,
|
|
216
|
+
params: options.params,
|
|
217
|
+
headers: options.headers
|
|
218
|
+
})
|
|
219
|
+
.then((res) => {
|
|
220
|
+
if (log) {
|
|
221
|
+
console.log("Response for url:", options.url);
|
|
222
|
+
console.log("Response headers:\n", JSON.stringify(res.headers));
|
|
223
|
+
//console.log("******** Response for url:", res);
|
|
224
|
+
}
|
|
225
|
+
if (res && res.status == 200 && res.data) {
|
|
226
|
+
if (callback) {
|
|
227
|
+
callback(null, res.data);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
if (callback) {
|
|
232
|
+
callback(TiledeskClient.getErr({ message: "Response status not 200" }, options, res), null, null);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
})
|
|
236
|
+
.catch((error) => {
|
|
237
|
+
console.error("An error occurred:", error);
|
|
238
|
+
if (callback) {
|
|
239
|
+
callback(error, null, null);
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
}
|
|
@@ -27,6 +27,7 @@ const { DirAssign } = require('./directives/DirAssign');
|
|
|
27
27
|
|
|
28
28
|
const { TiledeskChatbot } = require('../models/TiledeskChatbot');
|
|
29
29
|
const { DirIfOnlineAgents } = require('./directives/DirIfOnlineAgents');
|
|
30
|
+
const { DirReply } = require('./directives/DirReply');
|
|
30
31
|
|
|
31
32
|
class DirectivesChatbotPlug {
|
|
32
33
|
|
|
@@ -194,52 +195,23 @@ class DirectivesChatbotPlug {
|
|
|
194
195
|
});
|
|
195
196
|
}
|
|
196
197
|
else if (directive_name === Directives.MESSAGE) {
|
|
197
|
-
const messageDir = new DirMessage(
|
|
198
|
-
{
|
|
199
|
-
API_ENDPOINT: API_URL,
|
|
200
|
-
TILEBOT_ENDPOINT:TILEBOT_ENDPOINT,
|
|
201
|
-
log: false,
|
|
202
|
-
projectId: projectId,
|
|
203
|
-
requestId: requestId,
|
|
204
|
-
token: token
|
|
205
|
-
}
|
|
206
|
-
);
|
|
198
|
+
const messageDir = new DirMessage(context);
|
|
207
199
|
messageDir.execute(directive, async () => {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
200
|
+
process(nextDirective());
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
else if (directive_name === Directives.REPLY) {
|
|
204
|
+
console.log("...DirReply");
|
|
205
|
+
new DirReply(context).execute(directive, async () => {
|
|
213
206
|
process(nextDirective());
|
|
214
207
|
});
|
|
215
208
|
}
|
|
216
209
|
else if (directive_name === Directives.IF_OPEN_HOURS) {
|
|
217
|
-
// const intentDir = new DirIntent(
|
|
218
|
-
// {
|
|
219
|
-
// API_ENDPOINT: API_URL,
|
|
220
|
-
// TILEBOT_ENDPOINT:TILEBOT_ENDPOINT,
|
|
221
|
-
// log: false,
|
|
222
|
-
// supportRequest: supportRequest,
|
|
223
|
-
// token: token
|
|
224
|
-
// }
|
|
225
|
-
// );
|
|
226
|
-
|
|
227
210
|
const ifOpenHours = new DirIfOpenHours(context);
|
|
228
|
-
// {
|
|
229
|
-
// tdclient: tdclient,
|
|
230
|
-
// intentDir: intentDir,
|
|
231
|
-
// log: false
|
|
232
|
-
// });
|
|
233
211
|
ifOpenHours.execute(directive, () => {
|
|
234
212
|
process(nextDirective());
|
|
235
213
|
});
|
|
236
214
|
}
|
|
237
|
-
// else if (directive_name === Directives.IF_NOT_OPEN_HOURS) {
|
|
238
|
-
// const ifNotOpenHours = new DirIfNotOpenHours(context);
|
|
239
|
-
// ifNotOpenHours.execute(directive, () => {
|
|
240
|
-
// process(nextDirective());
|
|
241
|
-
// });
|
|
242
|
-
// }
|
|
243
215
|
else if (directive_name === Directives.IF_ONLINE_AGENTS) {
|
|
244
216
|
const ifOnlineAgents = new DirIfOnlineAgents(context);
|
|
245
217
|
// {
|
|
@@ -325,30 +297,8 @@ class DirectivesChatbotPlug {
|
|
|
325
297
|
agentDir.execute(directive, () => {
|
|
326
298
|
process(nextDirective());
|
|
327
299
|
});
|
|
328
|
-
// if (depId) {
|
|
329
|
-
// const agentDir = new DirMoveToAgent(
|
|
330
|
-
// {
|
|
331
|
-
// tdclient: tdclient,
|
|
332
|
-
// requestId: requestId,
|
|
333
|
-
// depId: depId
|
|
334
|
-
// }
|
|
335
|
-
// );
|
|
336
|
-
// if (!directive.body) {
|
|
337
|
-
// directive.action = {}
|
|
338
|
-
// directive.action.body = {
|
|
339
|
-
// whenOnlineOnly: false
|
|
340
|
-
// }
|
|
341
|
-
// }
|
|
342
|
-
// agentDir.execute(directive, () => {
|
|
343
|
-
// process(nextDirective());
|
|
344
|
-
// });
|
|
345
|
-
// }
|
|
346
|
-
// else {
|
|
347
|
-
// console.log("Warning. DepId null while calling 'AGENT' directive")
|
|
348
|
-
// process(nextDirective());
|
|
349
|
-
// }
|
|
350
300
|
}
|
|
351
|
-
else if (directive_name === Directives.WHEN_ONLINE_MOVE_TO_AGENT) {
|
|
301
|
+
else if (directive_name === Directives.WHEN_ONLINE_MOVE_TO_AGENT) { // DEPRECATED?
|
|
352
302
|
if (depId) {
|
|
353
303
|
const agentDir = new DirMoveToAgent(
|
|
354
304
|
{
|
|
@@ -374,24 +324,17 @@ class DirectivesChatbotPlug {
|
|
|
374
324
|
}
|
|
375
325
|
else if (directive_name === Directives.CLOSE) {
|
|
376
326
|
// console.log("Exec close()")
|
|
377
|
-
|
|
378
|
-
closeDir.execute(directive, () => {
|
|
327
|
+
new DirClose(context).execute(directive, () => {
|
|
379
328
|
process(nextDirective());
|
|
380
329
|
});
|
|
381
330
|
}
|
|
382
331
|
else if (directive_name === Directives.REMOVE_CURRENT_BOT) {
|
|
383
|
-
new DirRemoveCurrentBot({
|
|
384
|
-
tdclient: tdclient,
|
|
385
|
-
requestId: requestId
|
|
386
|
-
}).execute(directive, () => {
|
|
332
|
+
new DirRemoveCurrentBot(context).execute(directive, () => {
|
|
387
333
|
process(nextDirective());
|
|
388
334
|
});
|
|
389
335
|
}
|
|
390
336
|
else if (directive_name === Directives.REPLACE_BOT) {
|
|
391
|
-
new DirReplaceBot({
|
|
392
|
-
tdclient: tdclient,
|
|
393
|
-
requestId: requestId
|
|
394
|
-
}).execute(directive, () => {
|
|
337
|
+
new DirReplaceBot(context).execute(directive, () => {
|
|
395
338
|
process(nextDirective());
|
|
396
339
|
});
|
|
397
340
|
}
|
|
@@ -411,41 +354,23 @@ class DirectivesChatbotPlug {
|
|
|
411
354
|
});
|
|
412
355
|
}
|
|
413
356
|
else if (directive_name === Directives.FIRE_TILEDESK_EVENT) {
|
|
414
|
-
new DirFireTiledeskEvent(
|
|
415
|
-
{
|
|
416
|
-
tdclient: tdclient
|
|
417
|
-
}).execute(directive, () => {
|
|
357
|
+
new DirFireTiledeskEvent(context).execute(directive, () => {
|
|
418
358
|
process(nextDirective());
|
|
419
359
|
});
|
|
420
360
|
}
|
|
421
361
|
else if (directive_name === Directives.SEND_EMAIL) {
|
|
422
362
|
// console.log("...DirSendEmail");
|
|
423
|
-
|
|
424
|
-
email_dir.execute(directive, () => {
|
|
363
|
+
new DirSendEmail(context).execute(directive, () => {
|
|
425
364
|
process(nextDirective());
|
|
426
365
|
});
|
|
427
|
-
|
|
428
|
-
// new DirSendEmail(
|
|
429
|
-
// {
|
|
430
|
-
// tdclient: tdclient,
|
|
431
|
-
// tdcache: tdcache,
|
|
432
|
-
// requestId: requestId
|
|
433
|
-
// }).execute(directive, () => {
|
|
434
|
-
// process(nextDirective());
|
|
435
|
-
// });
|
|
436
366
|
}
|
|
437
367
|
else if (directive_name === Directives.DELETE) {
|
|
438
368
|
// console.log("got delete dir...")
|
|
439
|
-
new DirDeleteVariable(
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
tdcache
|
|
443
|
-
|
|
444
|
-
}).execute(directive, async () => {
|
|
445
|
-
const requestVariables =
|
|
446
|
-
await TiledeskChatbot.allParametersStatic(
|
|
447
|
-
tdcache, requestId
|
|
448
|
-
);
|
|
369
|
+
new DirDeleteVariable(context).execute(directive, async () => {
|
|
370
|
+
// const requestVariables =
|
|
371
|
+
// await TiledeskChatbot.allParametersStatic(
|
|
372
|
+
// tdcache, requestId
|
|
373
|
+
// );
|
|
449
374
|
// console.log("delete executed.",directive, requestVariables);
|
|
450
375
|
process(nextDirective());
|
|
451
376
|
});
|
|
@@ -77,7 +77,7 @@ class FillParamsChatbotPlug {
|
|
|
77
77
|
}
|
|
78
78
|
if (all_parameters) {
|
|
79
79
|
for (const [key, value] of Object.entries(all_parameters)) {
|
|
80
|
-
const value = all_parameters[key];
|
|
80
|
+
// const value = all_parameters[key];
|
|
81
81
|
const value_type = typeof value;
|
|
82
82
|
if (this.log) {console.log("checking parameter:", key, "value:", value, "type:", value_type)}
|
|
83
83
|
message_text = message_text.replace(new RegExp("(\\$\\{" + key + "\\})", 'i'), value);
|
|
@@ -3,7 +3,7 @@ class Filler {
|
|
|
3
3
|
fill(text, parameters) {
|
|
4
4
|
if (parameters) {
|
|
5
5
|
for (const [key, value] of Object.entries(parameters)) {
|
|
6
|
-
text = text.replace(new RegExp("(\\$\\{" + key + "\\})", 'i'), parameters[key]);
|
|
6
|
+
text = text.replace(new RegExp("(\\$\\{" + key + "\\})", 'i'), value); //parameters[key]);
|
|
7
7
|
}
|
|
8
8
|
}
|
|
9
9
|
return text;
|
|
@@ -58,17 +58,13 @@ class DirMessage {
|
|
|
58
58
|
else if (directive.parameter) {
|
|
59
59
|
let text = directive.parameter.trim();
|
|
60
60
|
action = {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
fillParams: true
|
|
69
|
-
}
|
|
70
|
-
// }
|
|
71
|
-
// }
|
|
61
|
+
text: text,
|
|
62
|
+
attributes: {
|
|
63
|
+
directives: false,
|
|
64
|
+
splits: true,
|
|
65
|
+
markbot: true,
|
|
66
|
+
fillParams: true
|
|
67
|
+
}
|
|
72
68
|
}
|
|
73
69
|
if (directive.name === Directives.HMESSAGE) {
|
|
74
70
|
action.attributes.subtype = "info";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
|
|
2
|
+
const { Filler } = require('../Filler');
|
|
1
3
|
|
|
2
4
|
class DirReplaceBot {
|
|
3
5
|
|
|
@@ -8,7 +10,7 @@ class DirReplaceBot {
|
|
|
8
10
|
this.context = context;
|
|
9
11
|
this.tdclient = context.tdclient;
|
|
10
12
|
this.requestId = context.requestId;
|
|
11
|
-
this.log = log;
|
|
13
|
+
this.log = context.log;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
execute(directive, callback) {
|
|
@@ -33,8 +35,16 @@ class DirReplaceBot {
|
|
|
33
35
|
})
|
|
34
36
|
}
|
|
35
37
|
|
|
36
|
-
go(action, callback) {
|
|
37
|
-
|
|
38
|
+
async go(action, callback) {
|
|
39
|
+
let botName = action.botName;
|
|
40
|
+
let variables = null;
|
|
41
|
+
variables =
|
|
42
|
+
await TiledeskChatbot.allParametersStatic(
|
|
43
|
+
this.context.tdcache, this.context.requestId
|
|
44
|
+
);
|
|
45
|
+
const filler = new Filler();
|
|
46
|
+
botName = filler.fill(botName, variables);
|
|
47
|
+
this.tdclient.replaceBotByName(this.requestId, botName, () => {
|
|
38
48
|
callback();
|
|
39
49
|
});
|
|
40
50
|
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
const { Filler } = require('../Filler');
|
|
2
|
+
const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
|
|
3
|
+
|
|
4
|
+
class DirReply {
|
|
5
|
+
|
|
6
|
+
constructor(context) {
|
|
7
|
+
if (!context) {
|
|
8
|
+
throw new Error('context object is mandatory.');
|
|
9
|
+
}
|
|
10
|
+
this.context = context;
|
|
11
|
+
this.projectId = context.projectId;
|
|
12
|
+
this.requestId = context.requestId;
|
|
13
|
+
this.token = context.token;
|
|
14
|
+
this.tdcache = context.tdcache;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
execute(directive, callback) {
|
|
18
|
+
console.log("Reply directive:", directive);
|
|
19
|
+
let action;
|
|
20
|
+
if (directive.action) {
|
|
21
|
+
action = directive.action;
|
|
22
|
+
console.log("got action:", JSON.stringify(action));
|
|
23
|
+
if (!action.attributes) {
|
|
24
|
+
action.attributes = {}
|
|
25
|
+
}
|
|
26
|
+
action.attributes.fillParams = true;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
console.error("Incorrect directive (no action provided):", directive);
|
|
30
|
+
callback();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
this.go(action, () => {
|
|
34
|
+
callback();
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async go(action, callback) {
|
|
39
|
+
const message = action;
|
|
40
|
+
// fill
|
|
41
|
+
let requestVariables = null;
|
|
42
|
+
if (this.tdcache) {
|
|
43
|
+
requestVariables =
|
|
44
|
+
await TiledeskChatbot.allParametersStatic(
|
|
45
|
+
this.tdcache, this.requestId
|
|
46
|
+
);
|
|
47
|
+
const filler = new Filler();
|
|
48
|
+
// fill text attribute
|
|
49
|
+
message.text = filler.fill(message.text, requestVariables);
|
|
50
|
+
// fill commands' text attribute
|
|
51
|
+
if (message.attributes && message.attributes.commands) {
|
|
52
|
+
let commands = message.attributes.commands;
|
|
53
|
+
if (commands.length > 1) {
|
|
54
|
+
for (let i = 0; i < commands.length; i++) {
|
|
55
|
+
if (commands[i].type === 'message' && commands[i].message && commands[i].message.text) {
|
|
56
|
+
commands[i].message.text = this.fillWithRequestParams(commands[i].message.text, requestVariables);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// temporary send back of reserved attributes
|
|
62
|
+
if (!message.attributes) {
|
|
63
|
+
message.attributes = {}
|
|
64
|
+
}
|
|
65
|
+
// Reserved names: userEmail, userFullname
|
|
66
|
+
if (requestVariables['userEmail']) {
|
|
67
|
+
message.attributes.updateUserEmail = requestVariables['userEmail'];
|
|
68
|
+
}
|
|
69
|
+
if (requestVariables['userFullname']) {
|
|
70
|
+
message.attributes.updateUserFullname = requestVariables['userFullname'];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// send!
|
|
74
|
+
if (this.log) {console.log("Message to extEndpoint:", message)};
|
|
75
|
+
this.context.tdclient.sendSupportMessage(
|
|
76
|
+
this.requestId,
|
|
77
|
+
message,
|
|
78
|
+
(err) => {
|
|
79
|
+
if (err) {
|
|
80
|
+
console.error("Error sending reply:", err.message);
|
|
81
|
+
}
|
|
82
|
+
if (this.log) {console.log("Message sent.");}
|
|
83
|
+
callback();
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
module.exports = { DirReply };
|
|
@@ -33,12 +33,16 @@ class Directives {
|
|
|
33
33
|
static ASSIGN = "assign";
|
|
34
34
|
static IF_AVAILABLE_AGENTS = "ifavailableagents"; // TODO
|
|
35
35
|
static IF_NO_AVAILABLE_AGENTS = "ifnotavailableagents"; // TODO
|
|
36
|
+
static REPLY = 'reply';
|
|
36
37
|
|
|
37
38
|
static actionToDirective(action) {
|
|
39
|
+
console.log("actionToDirective:", action);
|
|
38
40
|
let directive = {
|
|
39
|
-
name: action
|
|
41
|
+
name: action["_tdActionType"],//.type, //_tdActionType
|
|
40
42
|
action: action
|
|
41
43
|
}
|
|
44
|
+
// delete directive.action["_tdActionType"];
|
|
45
|
+
console.log("Directive out:", directive);
|
|
42
46
|
return directive;
|
|
43
47
|
}
|
|
44
48
|
}
|