andersonba / yve-bot Goto Github PK
View Code? Open in Web Editor NEWSmart rule-based bot. For Browser & Node.
Home Page: http://andersonba.github.io/yve-bot
License: MIT License
Smart rule-based bot. For Browser & Node.
Home Page: http://andersonba.github.io/yve-bot
License: MIT License
Support for add rules dynamically without using session (to avoid replacing all store)
ref #48
Possibilite the user to choose which types will be used, reducing bundle size.
It must be possible to set different replyMessage
for each options from a SingleChoice
field. It should also be possible to do so for MutipleChoice
field but for them is not as simple as to the first one mentioned
One question about using session. I am doing as follows.
I starting both as
bot.session(sid).start();
and i save the bot state as following
bot.on("storechanged",(state,sid)=>{
save_to_database({state,sid})
})
and I pass the state as following
const state = read_from_database(sid)
bot.session(sid,{state}).hear(message);
am I using doing correct? because i am having problem at the previous line, the bot is not responding.
The state is look like this
{ currentIdx: 0, waitingForAnswer: true, output: {} }
Want to know if this is correct way of using yve-bot.
Thanks in advance!
When we start the bot with bot.start()
it executes bot.controller.run
with an auto-inserted promise catch: this.controller.run().catch(this.tryCatch)
. By doing this the bot is handling only the first execution of controller.run and all following executions are ran in background with no possibility to have an error handler :/
Suggestion: Controller.run
should be wrapped in a try/catch and the error should be sent using controller.bot.dispatch('error', error)
Analyze and optimize the bundle sizes
currently, we raise an error inside of transform to make it loopable, it seems bad.
expected: transform a set of user data by multiple steps into single output based on previous answers.
bot asks: what color?
-> user answers: gr
-> bot request api
-> bot asks: gray or green
-> user chooses: green
-> bot store green
Validator fails when the input is an integer, such as 7192689343
.
- message: Type your phone number. (with DDD)
name: phone
type: String
validators:
- regex: ^\(?\d{2}\)?\s?\d{4,5}[\.-\s]?\d{4}$
Expected:
- ...
type: SingleChoice
options:
- value: Yes
synonyms: Yep, All right, Okay
- value: No
synonyms:
- Bye
- Really?
> bot: Yes or no?
> user: yep
// store: { confirmation: "Yes" }
I want to dynamically add rules without loosing the old ones. I need this to use yve-bot with conditional rules that are loaded dynamically based on user's choices on previous rules.
Exceptions thrown by ext/types are being imported based on a different object compared with the expected exceptions in core/controller.ts
;
For example when StringSearch receives an empty result from server it throws a ValidatorError
extracted from YveBot.exceptions and then controller tries to analyse it by checking if it is an instance of ValidatorError
from module ./exceptions
. This check results in a fail and then the bot get stuck :/
Change to UMD format to support import, plus the browser.
Configure it via options
I have two questions.
Currently, I get user inputs when the conversation with the bot is over, as documentations show.
bot.on('end', (output, sessionId) => {
console.log('User inputs:', output);
});
is there a way to get it in the "talk" event? Note that I am using session.
I want the second one to display some data dynamically to users, so wondering how to achieve it.
Thanks in advance!
Expected
// constructor
new YveBot(rules, {
context: { user: 123 },
});
// session
bot.session(sid, {
context: { user: 321 },
});
// how to access
bot.context.user
yvebot-ruleType-SingleChoice
yvebot-ruleType-MultipleChoice
- message: Hello
delay: 1234
replyMessage: Thanks
Types "Thanks" with delay defined in rule: 1234
or gets the default defined in yvebot options.
Group rules using flow concept.
The flow is not mandatory for rule specification.
It's just an optional feature to organize the bot conversations and prepare for next feature: Add new rules at runtime.
- flow: flow_name
rules:
- List of rules
- message: ...
# or
- message: List of rules
flow: flow_name
- message: ...
flow: flow_name
- flow: identification
rules:
- Welcome!
- message: Your name?
name: name
type: String
- message: Thanks!
next: question.help
- Skip
- flow: question
rules:
- message: Can I help you?
name: help
# bot> Welcome!
# bot> Your name?
# usr> Anderson
# bot> Thanks
# bot> Can I help you?
Keeping currently behavior
- flow: default
rules:
- message: Welcome
next: end
- message: Skip
- message: End
name: end
exit: true
- flow: another
rules:
- Skip 2
- message: Skip 3
name: end
# bot> Welcome
# bot> End
I was trying to define an customer validator to check user's answer. If the answer is "yes","sure" ... then jump to one rule. Otherwise, terminate (which part I did not write yet).
Here is my code.
bot.start();
bot.validators.define("agreed", {
validate: (expected, answer) => {
console.log("answer:"answer)
console.log("expected:"expected)
return answer === "yes" || answer === "sure";
},
warning: "You disagree :( sorry!"
});
The rules are as following.
- message: How can I help you?
name: hello
type: String
next: order
- message: would like to order something?!
name: order
type: String
-validators :
- agreed : true
next: food
- message: what do you like to have?
It works without that validator. I tried to print out inside the definition of validator, but nothing is printed.
Am I defining validator incorrectly?
Could you provide an example of validator or tell me what I am doing wrong here?
Thanks in advance!
For testing purpose
Should be possible to limit how many options are shown to users in the list of Single/MultipleChoice fields.
Suggestion:
rule:
- type: MultipleChoice
- maxOptions: 3
- options:
- label: option1
- label: option2
- label: option3
- label: option4
- label: option5
Would show options 1,2 and the third one would be More options
that would show the other options 3, 4 and 5.
When using node-fetch or any other package that have custom behavior for differents JS environment the compilation of core
and ui
files should be handled differently, each one using their own particularities.
- name: colors
options:
- label: Black
value: '#000'
- label: White
value: '#FFF'
- message: {{colors}} are colors
Result:
#000,#FFF are colors
Expected:
Black,White are colors
Generic type to simulate an autocomplete on chat.
Look these LOCs:
YveBot.prototype.types = new Types;
YveBot.prototype.actions = new Actions;
YveBot.prototype.executors = new Executors;
YveBot.prototype.validators = new Validators;
It means no matter how many times you create new instances (new YveBot()
) all of them will have the same types
, actions
, executors
, validators
properties they are NOT an instance property but a class/static property.
Example:
> var a = new YveBot([{ message: 'Olá!', name: 'test' }], 'ttt');
undefined
> var b = new YveBot([{ message: 'Olá!', name: 'test' }], 'ttt2');
undefined
> a.types === b.types
true
> b.types.xxx
undefined
> a.types.xxx = 123
123
> b.types.xxx
123
> var c = new YveBot([{ message: 'Olá!', name: 'test' }], 'ttt3');
undefined
> c.types.xxx
123
> c.types === a.types
true
If rule
option is passed, reindex.
If rule
option is not passed, do nothing.
If store
option is passed, replace store.
If store
option is not passed, reset store.
Currently
- type: name
actions:
- action1: true
- action2: true
Suggested
- type: name
actions:
- action1 # assumes true
- action2
- action3:
prop1: value
...
Method validateAnswer
in controller.ts
use utils.ensureArray
to make sure that user's answer is an array to then iterate this resulted list in all rule's validators.
When a Type implements multiple executors with custom validator to each one of them it could face a "skip validation" of some executor depending on what transformation you do.
In the case of StringSearch type the first transformation get the server result and transforms it to a list of objects in the following shape: { label, value }
. When server response is an empty array, the controller tries to iterate an empty string between the registered validators and them it doesn't behaves like expected because an empty array isn't iterated at all.
Suggested solution: each executor's transformation shall validate their own output if you're manipulating user's input into array
Extend class from Core to avoid replication code and ensure the correct behavior with split modules (#28) and node/browser code sharing
found using transform
into a custom type
- ...
options:
- label: Empty value
value: null
See https://github.com/andersonba/yve-bot/blob/master/src/ui/ui.ts#L47
Result: "Empty value"
Expected: null
It will be better if YveBot could re-define those objects BUT if user's force it!
My suggestion:
console.warn
override = true
parameterpostActions
to be executed right after the user answeractions
to before exit
Expected:
preActions: before bot message
actions: after bot message
postActions: after user answer
It would be great if you provide an example of restifying the bot.
Support to jump at any time between the rules using keywords or messages.
Example:
A user sends "help" in anytime during the conversation, then the conversation jumps to a specific rule.
(asked that question earlier, but still the custom validator is not invoking).
I am trying to define a validator, so could do somewhat complex checking.
I am using your example to test the custom validator "agreed" as shown below.
- message: What's your name?
name: name
type: String
replyMessage: Thanks for the answer, {name}!
- message: What city do you live in?
name: city
type: String
-validators :
- agreed: true
next: choice
- message: Make your choice
name: choice
type: SingleChoice
options:
- label: 1
- label: 2
The program is the same as your "cli" example, I just added the validator "agreed".
bot.validators.define("agreed", {
validate: (expected, answer) => {
console.log('agreed is invoked!!!!!!!!!!!!!!!!!!!!!')
console.log("EXPECTED", expected);
console.log("ANSWER", answer);
return true;
},
warning: "You disagree :( sorry!"
});
I should be able to see these logs are printed, but it is not happening. The bot is going through all these messages, but never invoked the validator "agreed".
am I missing something here? Please, help!
Thanks in advance.
Currently, to jump to specific flow you need to enter the rule name: next: flow_name.rule_name
, but it would be nice jump to the first rule of flow without having to type it.
Suggestion to how to jump to "identification" flow:
next: "flow:identification"
next: identification.
next: identification
considering the flow as priority rather than the ruleHow can I pass data through session?
For example,
bot.session(channelId,{ somedata }).hear(text);
Then, how can I get it in "talk event"
bot.on("talk", (text, data, sid) => {
//how to get "somedata" here?
})
I logged these "data" and could not figure out how to get "somedata"?
Thanks in advance!
avoid scroll down when current scroll position isn't bottom
+------------------+
| YveBot
| Hi, I am YveBot!
+------------------+
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.