I am making a service Bot. In the intent 'CustomerSatisfaction', I want 'rating' and 'future' as my mandatory entities and 'timetaken' as my optional entity. I have taken the format from internet and modified it according to my use case.
Issue:
I am not able to understand that how should I integrate this with my Bot's code, so that it could be executed. So, when I ask 'How did you like the service?', it goes to 'CustomerSatisfaction', intent and do not proceed further till user answers 'Please provide the rating out of 5 for this bot.', 'Please provide the rating out of 5 for this bot.' and where timetaken entity is optional.
link to which I have referred.
Here is the modified code according to my use case I want to integrate with my Bot's code. :
var CustomerSatisfactionAction = {
intentName: 'CustomerSatisfaction',
friendlyName: 'Customer Satisfaction',
confirmOnContextSwitch: true, // true by default
// Property validation based on schema-inspector -
https://github.com/Atinux/schema-inspector#v_properties
schema: {
rating: {
type: 'any',
rating : rating ,
message: 'Please provide the rating out of 5 for this bot.'
},
future: {
type: 'string',
future : future ,
message: 'Please provide the rating out of 5 for this bot.'
},
timetaken: {
type: 'string',
optional: true
},
},
// Action fulfillment method, recieves parameters as keyed-object
(parameters argument) and a callback function to invoke with the fulfillment
result.fulfill: function (parameters, callback)
{
session.send ('ok');
}
Related
Here is how my application works. A user logs in for the first time using Google Sign in. We get the following data from their Google Account:
Given name
Family name
Email ID
We wish to use this information to call our API (POST request) to create a user profile.
The data we send is
{
firstName: firstName ,
lastName: lastName,
email: email
}
Here is where the issue comes from. The user profile has many fields and one of them is designation. When the user logs in for the first time, we don't know their designation.
We are using MongoDB for our database. So we use Mongoose to set up the connection. In Mongoose model, we have added some validation for our schema. Designation is a required field. It should be at least one character of length and maximum of 40 characters. If we set designation as null, the validation would fail.
Is there any way to allow null in a required field in Mongoose?
Rather than setting required to true or false, you can pass it a function:
const user = new Schema({
designation: {
type: String,
minLength: 1,
maxLength: 40,
required: function() {
// Rather than checking a stored variable, you could check
// static functions on the model, a custom value on the
// instance that isn't persisted, etc.
return this.hasLoggedInAtLeastOnce === true;
// If this function returns true, the field is required.
}
}
hasLoggedInAtLeastOnce: {
type: Boolean,
}
});
Currently using LUIS in a bot that connects to Slack. Right now I'm using interactive messages and trying to respond to user input correctly. When I click an item from the drop down LUIS receives it as a message. I can get the text with session.message.text, however I need to get the callback_id of the attachment as well as the channel it was sent from.
I've used console.log(session) to get an idea of what session looks like. From there I've seen that session.message.sourceEvent contains the data I need, however I can't use indexOf() or contains() to actual extrapolate the data. I've also tried session.message.sourceEvent.Payload but end up getting "[object [Object]]". I've tried searching for documentation on session formatting but to no avail.
Below is a snippet of what is returned when I run console.log(session.message.sourceEvent).
{ Payload:
action_ts: '1513199773.200354',
is_app_unfurl: false,
subtype: 'bot_message',
team: { id: 'T03QR2PHH', domain: 'americanairlines' },
user: { id: 'U6DT58F2T', name: 'john.cerreta' },
message_ts: '1513199760.000073',
attachment_id: '1',
ts: '1513199760.000073' },
actions: [ [Object] ],
callback_id: 'map_selection1',
original_message:
username: 'Rallybot',
response_url: 'https://hooks.slack.com/actions/T03QR2PHH/287444348935/Y6Yye3ijlC6xfmn8qjMK4ttB',
type: 'message',
{ type: 'interactive_message',
channel: { id: 'G6NN0DT88', name: 'privategroup' },
token: 'removed for security',
{ text: 'Please choose the Rally and Slack team you would like to map below.',
bot_id: 'B7WDX03UM',
attachments: [Array],
trigger_id: '285857445393.3841091595.085028141d2b8190b38f1bf0ca47dd88' },
ApiToken: 'removed for security' }
session.message.sourceEvent is a javascript Object, however indexOf or contains are functions of String or Array types.
Any info you required in the object, you should direct use the code <object>.<key> to invoke that value. You can try session.message.sourceEvent.Payload.action_ts for example.
Also, you can use Object.keys(session.message.sourceEvent) to get all the keys in this object.
In a meteor app I've been getting my feet wet with SimpleSchema lately. I've built the below mentioned pretty simple schema :-)
However, when I try to validate an invalidate entry (say one where entry.link.url ist not a valid URL or one where entry.link.project is undefined) against that schema via entrySchema.validate() the validation does not work properly, i.e. the invalid entry passes the validation whereas I would expect it to fail.
let entrySchema = new SimpleSchema({
userId: {
type: String,
optional: true
},
link: {
type: Object
},
'link.project': {
type: String //this validation does not work!
},
'link.url': {
type: SimpleSchema.RegEx.Url //this validation does not work!
}
});
Can anyone please tell me what I am doing wrong or what I am missing here?
I've been playing around with Sails for maybe one day. I'm trying to wrap my head around what would be the best way to do extensive validation in Sails.js.
Here is the scenario:
Registration Form:
Username: _______________
E-Mail: _______________
Password: _______________
Confirm: _______________
User inputs:
a correct e-mail
a username that already exists
two passwords that don't match
Desired outcome:
Username: _______________ x Already taken
E-Mail: _______________ ✓
Password: _______________ ✓
Confirm: _______________ x Does not match
Requirements, a few key points:
The user receives all error messages (not just the first one) for every aspect of his input. They are not vague ("username already taken" or "username must be at least 4 letters long" is better than "invalid username")
The built-in model validation can obviously not be responsible for checking a matched password confirmation (SRP)
What I think I need to do:
UserController:
create: function(req, res) {
try {
// use a UserManager-Service to keep the controller nice and thin
UserManager.create(req.params.all(), function(user) {
res.send(user.toJSON());
});
}
catch (e) {
res.send(e);
}
}
UserManager:
create: function(input, cb) {
UserValidator.validate(input); // this can throw a ValidationException which will then be handled by the controller
User.create(input, cb); // this line should only be reached if the UserValidator did not throw an exception
}
User: (model)
attributes: {
username: {
type: 'string',
required: true,
minLength: 3,
unique: true
},
email: {
type: 'email',
required: true,
unique: true
},
password: {
type: 'string',
required: true
}
}
UserValidator:
This is the tricky part. I need to combine input-specific validation (does the password confirmation match?) with the Model validation (is the username taken and is the e-mail address valid?).
If there was a way to instantiate a User-model and perform validation without saving to the database in Sails/Waterline I think this would be quite straight-forward, but there doesn't seem to be that option.
How would you go about solving this problem? Thank you very much for your help!
You can do this in your model:
module.exports = {
types: {
mycustomtype: function (password) {
return password === this.confirm;
}
},
attributes: {,
password:{
type: 'STRING',
required: true,
mycustomtype: true
}
}
}
There are going to be some validations that you can perform immediately on the client-side without needing to round-trip to the server. Things like comparing the password with the confirmation password, as well as verifying a string matches an email regex can be done with client-side javascript.
For other things like checking whether a username exists or not, you could use an ajax call to sails to directly ask it 'does this username exist' and provide real-time validation on the client-side based on the result, or you can wait until the user submits the form and parse the form submission to display those validations. Since checking ahead of time for things like this aren't 100% reliable (i.e. someone could create a user with that name after the check but prior to the form being posted back), some people choose to forgo the pre-check and only handle the error after post.
Waterline has its own built-in validation mechanism called Anchor, which is built on validator.js (previously called node-validator). For a full list of validations available, see here. I would recommend that instead of defining a separate validation layer, you define a method that parses the sails validation messages and formats them in a way that is user-friendly and consistent.
If you want to perform your own validations outside of what Waterline would do for you, you could do those validations inside a lifecycle callback, for instance the beforeCreate(values, callback) lifecycle callback. If you detect errors, you could pass them into the callback as the first parameter, and they would be passed back as an error to the caller of the create collection method.
An alternative to using a lifecycle callback, would be to create your own collection method that handles the create. Something like this:
Users.validateAndCreate(req.params.all(), function (err, user) {
...
});
More information about how to create a collection method like this can be found in my answer to this question: How can I write sails function on to use in Controller?
I have an idea for how to store the relationships. Each user has a friends Array filled with IDs. However, how should I initiate a friend request in my Express.js app in MongoDB?
I'm thinking about creating a "notifications" collection with:
_id, userId, type, friendId, read
So when the requested friend logs in, they can see all of their own notifications to deal with...
Or is that ridiculous?
For such notifications what I did, is as follows:
var notificationSchema = mongoose.Schema({
to:{
type: mongoose.Schema.Types.ObjectId, ref: 'User'
},
from:{
type: mongoose.Schema.Types.ObjectId, ref: 'User'
},
for: {
type: String
},
status: {
type: String,
default: "Not Seen"
},
description:{
type: String
}
},{ timestamps: { createdAt: 'created_at' }
});
where I have saved _id of to and from (users) where I used for field for notification type like following, liked etc and used description field as optional.
Sounds reasonable enough. But my approach will be a little different. I would store the notifications in the user db itself. Something like
username
dob
...
notifications[[type: 'friend', read: 0, request_from: '22sd300sdf45003425asz'], ...]
...
This way, you don't have to make a db call on every page load. As soon as you initialize a session (I use passport), it will be there, ready already for templates. After a valid action from the user, I can delete it or whatever.
But again, its dependent on the need. Do what suits you best!
If you store it in the user passport session (solution mentioned earlier) you will not be able to receive anymore notifications since it is static information in the header and not connected directly to the document store.
The best way to do it would to have let it have it's own store.
{Id:ObjectId, for_user:String, sent from:String, status:Boolean}
Perhaps you can initially set the status to null then set it to true or false when a user accepts or denies it. After create the user to user friend relationship. That's more or less the way I would go about it.