forked from guidone/node-red-contrib-chatbot
-
Notifications
You must be signed in to change notification settings - Fork 0
/
chatbot-apiai.html
195 lines (183 loc) · 7.19 KB
/
chatbot-apiai.html
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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<script type="text/javascript">
RED.nodes.registerType('chatbot-apiai', {
category: 'RedBot Flow',
color: '#FFCC66',
defaults: {
apiai: {
value: '',
type: 'chatbot-apiai-token',
required: true
},
rules: {
value: []
},
name: {
value: ''
},
outputs: {
value: 1
}
},
inputs: 1,
outputs: 1,
paletteLabel: 'Api.ai',
icon: 'chatbot-api-ai.png',
label: function() {
return this.name || 'Api.ai';
},
oneditsave: function() {
var rules = $('#node-input-rule-container').editableList('items');
var node = this;
node.rules = [];
rules.each(function(i) {
var rule = $(this);
if (rule.find('input').length !== 0) {
var topic = rule.find('input').val();
if (topic!= null && topic != '') {
node.rules.push({topic: topic});
}
}
});
this.outputs = node.rules.length + 1;
},
oneditprepare: function() {
var node = this;
$("#node-input-rule-container").css('min-height','250px').css('min-width','450px').editableList({
addItem: function (container, i, opt) {
var row = $('<div/>').appendTo(container);
var finalspan
if (i === 0) {
$('<span/>', {style: 'width:80%; margin-left: 5px; text-align: left;'})
.html('Wire this to a text message node')
.appendTo(row);
finalspan = $('<span/>', {style: 'float: right;margin-top:0px;'}).appendTo(row);
finalspan.append(' → <span class="node-input-rule-index">' + (i + 1) + '</span>');
} else {
var rule = opt;
var selectField = $('<input/>', {style: 'width:80%; margin-left: 5px; text-align: left;'})
.attr('placeholder', 'Insert intent')
.attr('type', 'text')
.appendTo(row);
if (rule.topic != null) {
selectField.val(rule.topic);
}
finalspan = $('<span/>', {style: 'float: right;margin-top: 8px;'}).appendTo(row);
finalspan.append(' → <span class="node-input-rule-index">' + (i + 1) + '</span>');
}
},
removeItem: function(opt) {
var rules = $('#node-input-rule-container').editableList('items');
rules.each(function(i) {
$(this).find('.node-input-rule-index').html(i + 1);
});
},
sortItems: function() {
var rules = $('#node-input-rule-container').editableList('items');
rules.each(function(i) {
$(this).find('.node-input-rule-index').html(i + 1);
});
},
sortable: true,
removable: true
});
$('#node-input-rule-container').editableList('addItem', {topic: null});
for (var i=0; i < node.rules.length; i++) {
var rule = this.rules[i];
$('#node-input-rule-container').editableList('addItem', rule);
}
}
});
</script>
<script type="text/x-red" data-template-name="chatbot-apiai">
<div class="form-row">
<label for="node-input-bot"><i class="icon-bookmark"></i> Bot</label>
<input type="text" id="node-input-apiai" placeholder="Api.ai access token">
</div>
<div class="form-row">
<label for="node-input-name"><i class="icon-tag"></i> Name</label>
<input type="text" id="node-input-name" placeholder="Name">
</div>
<div class="form-row">
<label for="node-input-name" style="width:100%;"><i class="fa fa-tag"></i>
Process conversation and forward when the topic matches of:</label>
</div>
<div class="form-row node-input-rule-container-row">
<ol id="node-input-rule-container"></ol>
</div>
<div style="max-width: 460px;font-size: 12px;color: #999999;line-height: 14px;margin-top:5px;">
To match more contexts use a comma separated string (topic_1, topic_2). To match all context use <code>*</code>
</div>
</div>
</script>
<script type="text/x-red" data-help-name="chatbot-apiai">
<p>
Use <b>Api.ai</b> NLP engine to parse user input. With Api.ai it's easy to parse sentences like <em>"I want to switch on the
lights of the living room"</em> and extract key variables.
</p>
<p>
Some <b>Api.ai</b> terminology:
</p>
<ul>
<li>
<b>Context</b>: have the same meaning of <b>topic</b> in <b>RedBot</b> (do not confuse with chat context in <b>RedBot</b>), the purpose
is to restrict the working area of the parsers based on a context of the sentence. For example the words <em>"the email is
[email protected]"</em> can trigger a particular action it the user is signing up with the chat bot (for example topic or
context "signup") and a different one if the user intention is to send an email to someone with the chat bot (for
example topic or context "send_message")
</li>
<li>
<b>Intent</b>: is a set of rules for parsing user's sentences and detect a set of entities in order to consider the sentence
complete. For example in the sentence <em>"I want to switch on the lights in the living room"</em>, the entities are
<em>Furniture</em> (lights), <em>OnOff</em> (on) and <em>Room</em> (living room). By setting these entities as mandatory
to consider the sentence complete, the Api.ai intent is able to parse them and ask question if the sentence is
missing some information (for example after <em>"I want to switch on the lights"</em> it could ask <em>"In which room?"</em>).
When the sentence is complete the Intent changes the context/topic, for example "switch_lights", in this way it's
possible to let <b>RedBot</b> takes action for this context.
</li>
<li>
<b>Entity</b>: are sets of objects of the same class. For example in a sentence like "I want to switch on the lights in the
living room" the entity Room can contain: living room, kitchen, lavatory, etc
</li>
</ul>
<p>
The <code>Api.ai node</code> works like a kind of loop: the first output is always connected to a message node, this
allows the <code>Api.ai node</code> to keep asking question to the user until all the intent requirements are met.
When the sentence is complete and <em>Api.ai</em> transitioned to a new topic (context) the message is forwarded to the proper
output based on the matched topic (just like the <code>Topic node</code>).
</p>
</script>
<script type="text/javascript">
RED.nodes.registerType('chatbot-apiai-token', {
category: 'config',
defaults: {
name: {
value: '',
required: true
}
},
paletteName: 'Api.ai Token',
credentials: {
token: {
type: 'text'
}
},
label: function () {
return this.name;
}
});
</script>
<script type="text/x-red" data-template-name="chatbot-apiai-token">
<div class="form-row">
<label for="node-config-input-botname"><i class="icon-bookmark"></i> Name</label>
<input type="text" id="node-config-input-name">
</div>
<div class="form-row">
<label for="node-config-input-token"><i class="icon-tag"></i> Token</label>
<input type="text" id="node-config-input-token">
</div>
</script>
<script type="text/x-red" data-help-name="chatbot-apiai-token">
<p>
Insert the <b>Api.ai</b> client token. Find it under the <em>agent</em> configuration.
</p>
</script>