-
Notifications
You must be signed in to change notification settings - Fork 15
/
djs.js
136 lines (122 loc) · 4.47 KB
/
djs.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
// Dynamic Journey Schema parser
class DJS {
constructor() {
this.arguments = {};
this.activeMenu = {};
this.activeInstructions = {};
this.active = false;
this.end = false;
this.finalConfirmation = {};
this.finalResponse = {};
this.menuIndex = 0;
this.instructions = {}
}
get ready() {
return "options" in this.activeInstructions;
}
start() {
this.end = false;
this.active = true;
}
stop() {
this.active = false;
this.menuIndex = 0;
this.arguments = {};
this.activeInstructions = this.instructions;
}
get next() {
if (this.menuIndex != 0 && 'options' in this.activeInstructions) {
let instructions = this.activeInstructions['options']['optionslist']['option'][this.menuIndex-1]['instructions'];
this.activeInstructions = instructions;
}
this.buildMenus();
console.log("Loading next menu:", this.activeMenu);
return this.activeMenu;
}
setArgument(menuIndex) {
this.menuIndex = menuIndex;
let args = this.activeMenu['options'][this.menuIndex - 1];
this.arguments[args['key'].toLocaleLowerCase()] = args['value'];
console.log(`Argument ${args['key']} set to ${args['value']}`);
}
insertArguments(text) {
let re = /\$\{(?<argument>\w+)\}/g;
let match;
while (match = re.exec(text)) {
let key = match.groups.argument.toLocaleLowerCase();
if(key in this.arguments) {
text = text.replace(match[0], this.arguments[key]);
}
}
return text;
}
loadXML(xml) {
const options = {
attributeNamePrefix : "@_",
attrNodeName: "attr", //default is 'false'
textNodeName : "#text",
ignoreAttributes : false,
ignoreNameSpace : false,
allowBooleanAttributes : false,
parseNodeValue : true,
parseAttributeValue : true,
trimValues: true,
cdataTagName: "__cdata", //default is 'false'
cdataPositionChar: "\\c",
parseTrueNumberOnly: false,
arrayMode: false, //"strict"
attrValueProcessor: (val, attrName) => he.decode(val, {isAttributeValue: true}),//default is a=>a
tagValueProcessor : (val, tagName) => he.decode(val), //default is a=>a
stopNodes: ["parse-me-as-string"]
};
let doc = parser.parse(xml,options);
if (doc["ns0:createjourneyrequest"] === undefined) {
console.error("Error loading xml document: document doesn't contain the ns0:createjourneyrequest node");
throw new Error("The dynamic journey file selected does not contain the expected xml schema.");
}
this.instructions = doc["ns0:createjourneyrequest"]["journeydefinition"]["instructions"];
this.activeInstructions = this.instructions;
console.log("loaded instructions:", this.instructions);
}
buildMenus() {
if ('options' in this.activeInstructions) {
let menu = {'text': '', 'response_type': 'choice', 'options': []};
if ('header' in this.activeInstructions['options']) {
menu['text'] = `${this.activeInstructions['options']['header']['texts']['text']['textmessage']}\n\n`;
}
let options = this.activeInstructions['options']['optionslist']['option'];
for(let i in options) {
let option = options[i];
let optionIndex = parseInt(i) + 1;
menu['text'] = `${menu['text']}${optionIndex}. ${option['display']['texts']['text']['textmessage']}\n`;
menu['options'][i] = option['instructions']['argument'];
}
if('footer' in this.activeInstructions['options']) {
menu['text'] = `${menu['text']}\n${this.activeInstructions['options']['footer']['texts']['text']['textmessage']}`
}
console.log(`Active menu text set to ${menu['text']}`);
console.log("Options set to ", options);
this.activeMenu = menu;
} else if (!this.end && 'question' in this.instructions) {
this.end = true;
let confirmation = { 'text': '' };
confirmation['text'] = this.instructions['question']['display']['texts']['text']['textmessage'];
confirmation['response_type'] = this.instructions['question']['key'];
console.log(`Final confirmation set to ${confirmation['text']}`);
this.activeMenu = confirmation;
} else if ('responsematching' in this.instructions) {
let menu = { 'text': this.instructions['responsematching']['defaultresponse']['texts']['text']['textmessage'], 'response_type': 'info', 'end': true };
console.log(`Final response set to ${menu['text']}`);
this.activeMenu = menu;
} else {
console.log("Missing final response, setting generic response.")
let menu = { 'text': 'Your request has been received!', 'response_type': 'info', 'end': true };
this.activeMenu = menu;
}
}
}
// DJSException
function DJSException(message) {
this.message = message;
this.name = 'DJSException';
}