How do I add an action to watson conversation response? - javascript

I've created intent, entity and dialog without a problem. But right now I'm trying to make it so when the user send "goodbye", the application would close. According to the doc, I'll have to name an action that goes along with an intent. How do I do that? Is it through code or through the conversation workspace platform?

You can use context variables or action variables for that.
How to use context variables? Add in your Advance response the "context" and the values, check my example.
I've used the conversation simple for that.
In your Watson Developer Cloud - IBM Bluemix - Watson Conversation, add in the Advanced response this JSON example, Assuming it is in this conversation node that your application will do something:
{
"context": {
"verified": true;
},
"output": {
"text": {
"values": [
"Please wait and I'll verified your request."
],
"selection_policy": "sequential"
}
}
}
Example (app.js):
function updateMessage(input, data, req, res) {
if (data.context.verified === true){
searchRequest(data, req, res);
} else if (data.output && data.output.text) {
return res.json(data);
}
return data;
}
You can use the data for sending something within conversation flow.
function searchRequest(data, req, res){
// something to do and return value
var sendRequest = "Thanks for wait, the request is" + valueRequest;
data.output.text[0] = sendRequest;
return data;
}
EDIT:
You can add one JSON object like "action", and your code will recognize this variable, with the same example that #Mikko said. And you can check this with:
data.output.action === 'close'
See more about Context variables.
See more about Building a dialog.

You need to be careful with context variables as your next dialog node may or may not update them. Another option is to add a custom variable in the output. This is the solution used in conversation-discovery samples available in the GitHub.
"output": {
"text": {
"values": [
"Goodbye..."
],
"selection_policy": "sequential"
},
"action": "close"
}
Please note that this will cause a warning when closing the JSON editor.

Related

Passing information from inquirer prompt to another function? Node.js

Just getting back to coding and doing some practice on some fun code I came across from a friend.
I am using inquirer to ask the user what attack they would like to use. I then want to pass that information into another function.
I am having trouble finding a way to take the option from the array that the user chooses, and use it outside of the attackPrompt function.
Almost anything helps. Thanks.
let attacks = [
"Slap",
"Bite",
"Kick",
]
function attackPrompt() {
let attackChoice = [{
name:"attack",
type:"list",
message:"Choose your attack.",
choices: attacks
}]
inquirer.prompt(attackChoice).then((answer) => {
attackChosen(attackOption);
console.log("MY STRING HERE", answer.attack)
//trying to make a function where I can pass the information to another maybe?
function attackChosen() {
let optionFromChooseAttack = answer
// console.log("I PUT THIS STRING HERE", optionFromChooseAttack)
}
})
}
attackPrompt();

aws personalize putevents does not update recommendations

I'm trying to use AWS Personalize. After creating dataset and batch inference, I am updating the user-item-interactions with personalize.putEvents (using Javascript SDK, docs)
Snippet:
const awsOpts = { apiVersion, accessKeyId, secretAccessKey, region }
const pEvents = new AWS.PersonalizeEvents(awsOpts)
// ...
const params = {
trackingId, userId, sessionId,
eventList: [{
eventId: (+sentAt) + "",
sentAt,
eventType,
properties: { itemId }
}]
}
pEvents.putEvents(params, (err, data) => err ? reject(err) : resolve(data))
The events seem to be registered. No errors. After that when I create another batch-inference, I would expect that the new user-items would not appear in the recommendations anymore. But the recommendations in the next batch-inference are unchanged. Am I doing something wrong or am I misunderstanding the putEvents-API-call?
Schema for reference:
{
"type": "record",
"name": "Interactions",
"namespace": "com.amazonaws.personalize.schema",
"fields": [
{
"name": "USER_ID",
"type": "string"
},
{
"name": "ITEM_ID",
"type": "string"
},
{
"name": "EVENT_TYPE",
"type": "string"
},
{
"name": "TIMESTAMP",
"type": "long"
}
],
"version": "1.0"
}
One thing seems a bit strange: Cloud watch reports that the lambda was executed twice despite no errors nor timeout exceeded (timeout is set to 10s, and the lambda takes less than 2s). Also Retry attempts is set to 2.
#D.J.Duff (sadly I can't comment)
Are you sure the events added using PutEvent API are considered without retraining ? I have been through the AWS Personalize Doc looking for exactly that and it looked to me that you need to retrain to get those events included and for the runtime api to be able to consider them. Could you point to me where you saw that they are considered without having to retrain ? Thanks
User-item recommendations, at least from the runtime API should change without retraining after some events (that is what it is for and that is how we use it), though perhaps (it is something to check) you need to use the runtime API to see the new recommendations.
(edited to clarify that that the API is called the "runtime" API - thanks to PatrykMilewski for seeking the clarification - and that I am by no means certain that the particular API used is the important thing - I do know that when using the runtime API, the events do have an effect though).
I have tried out the very same usecase with personalize using boto3 sdk. Yes!! Put events can be used to update user-item-interactions. No need to retrain the model after put events. Looks like aws personalize solutions are made compatible to handle the data updated with put events. When I run the next batch inference, after updating interactions with put events API, I could see the change in the recommendations. I verified this with personalized ranking recipe. I could see the recent interacted items getting re-ranked according users recent interactions.

AWS cognito user pools, custom message lambda

Good day to everyone.
I have a problem with AWS cognito user pools custom message which is created inside lambda function as a trigger (custom message lambda). Message with verification link inside. In particular I'm setting message subject to "Custom subject" (and email has this subject), and message body to "Use this {##Custom link##} instead" (and the message is not appear in the body, but the one from user pools web interface is used).
My code is:
public void handleRequest(InputStream input, OutputStream output, Context context) throws IOException {
JsonNode json = parseJsonFromStream(input);
ObjectNode jsonWithResponse = (ObjectNode) json;
jsonWithResponse.with("response").put("emailMessage", "Use this {##Custom link##} instead");
jsonWithResponse.with("response").put("emailSubject", "Custom subject");
try (Writer w = new OutputStreamWriter(output, "UTF-8")) {
w.write(jsonWithResponse.toString());
}
}
I had tried to set even {####} instead {##Link text##} and still same. I'm almost sure it worked some time ago (and I don't remember I changed anything). Does anyone has any idea where should I take a look (dig). As I spent too much time on that and neither missing something (hopefully) small or they have some changes/issues.
P.S. lambda test success. Lambda output looks fine (I eliminate logger here).
Upd: (logger output with response)
OUTPUT JSON is
{
"version": "1",
"region": "eu-west-1",
"userPoolId": "****",
"userName": "*****",
"callerContext": {
"awsSdkVersion": "aws-sdk-android-2.6.7",
"clientId": "****"
},
"triggerSource": "CustomMessage_SignUp",
"request": {
"userAttributes": {
"sub": "****",
"email_verified": "false",
"cognito:user_status": "UNCONFIRMED",
"nickname": "Yaroslav",
"email": "****"
},
"codeParameter": "{####}",
"usernameParameter": null
},
"response": {
"emailMessage": "Use this {##Custom link##} instead",
"emailSubject": "Custom subject"
}
}
Upd2 (JS trigger):
I added code on js (new trigger for custom email) based on example and that works for custom email when user wants confirmation code, but that doesn't work for confirmation link. Again, I tried {##link##} for the link.
So what I ended up with is to use code confirmation. In this case custom email works as expected.
To prevent the user from typing the password into the app, I sent email with custom link, which include the code parametr. Custom link pointed to API Gateway which had corresponding lambda to handle everything and finish the user registration.

Trying to simplify access to private posts with Express

I'm learning Node.js with MongoDB and Express and it is going quite well.
I have my user registration working fine and every user can create posts.
Now I'm trying something more complicated, I'd like user to create private posts and only user who created it and other allowed users can see the post.
I did something and it seems to work but I think it can be done in some better way.
What I have now to get the post at this address www.mywebsite.com/post-title is this:
Post
.findOne({ permalink: req.params.permalink })
.exec(function(err, post) {
if (!post) {
req.flash('errors', { msg: 'Post not found' });
return res.redirect('/');
} else {
if (post._creator == req.user.id) {
res.render('post/home', {
title: post.name,
post: post
});
} else {
req.flash('errors', { msg: 'You are not allowed to see this post' });
res.redirect('/');
}
}
});
It works fine but if I wish to add few more options to this post and create another link like: www.mywebsite.com/post-title/tags to get that page I have to repeat the whole code posted above...
I wish to find a way to match easily the owner of the post or allowed people and a way to get the post through the permalink without useing fineOne for every get...
Is this possible?
Does it make sense?
Thanks
I might have helped you to "simplify" your question and just explain what you wanted to do. But those who take the time to read all of it would eventually see that you basically want to
" List all posts including private and allowed posts for the current user.. "
Which is basically the simplified version of the question.
So all you basically need are some fields on your "Post" document that allow the access control:
{
"title": "this is the title",
"permalink": "some/sort/of/slug",
"body": "post body here",
"creator": "Bill",
"_private": true,
"_allowed": ["Ted","Fred"]
}
So basically you are not going to care about the "_allowed" list where "private" is false, but you do want to care where this is true. So you want this logic in the query rather than evaluating it per document retrieved:
Post.find(
{
"$or": [
{ "_private": false },
{
"_private": true,
"$or": [
{ "creator": req.user.id },
{ "_allowed": req.user.id }
]
}
}
},
function(err,docs) {
So essentially your logic is based of a nested $or operation which either allows the public posts to display or otherwise where the post is private then only the "creator" $or the "_allowed" users will receive this in any query.
The logic applies to whether you are retrieving a list of posts for paging results or whether recalling an individual post for a single in depth display.

Google tasks update error

I am attempting to update a task with the following code:
function updtsk(task,id)
{
var url = 'https://www.googleapis.com/tasks/v1/lists/#default/tasks/'+id;
var req = {
'method': 'PUT',
'headers': {
'Content-type': 'application/json'
},
'body': JSON.stringify(task)
};
var addDone = function(resp, xhr) {
if (xhr.status != 200) {
notifyFailure('Couldn\'t update task.', xhr.status);
return;
}
//notifySuccess(task['title']);
}
oauth.sendSignedRequest(url, addDone, req);
}
I get the following error however:
"{
"error": {
"errors": [
{
"domain": "global",
"reason": "invalid",
"message": "Invalid Value"
}
],
"code": 400,
"message": "Invalid Value"
}
}
"
The update body is this:
{
'title': $(this).val()
};
I am using the chrome_ex_oauth api and could use some help.
Try passing the 'id' key/value pair together with the title information you are already sending.
I had this same problem, even using the API explorer. There's no documentation to indicate this is a required parameter, especially since it is included in the URL. Once I added id, it worked properly.
It's possible you need to include additional fields in the update.
The documentation here: http://code.google.com/apis/tasks/v1/reference.html#resource_tasks appears to indicate the status property is not optional (the other mutable fields are listed as optional in their descriptions). You may also need to include the kind property with the static value indicated there.
In Google Task API for updating any TaskList Task:
First we have to get task with use of TaskList Id and Task Id
Second step change/update in task and again update that task.
Hope this is helpful for you.
I read these answers several times, but only saw what I thought I already knew, which was wrong. The documentation for insert/update/etc. states
POST https://www.googleapis.com/tasks/v1/lists/tasklist/tasks
It is the id of the tasklist being modified (e.g. something like "MTA1MjEpoqwdNTMzMjAzo349YDA6MDow") and not the title of the tasklist e.g. "My Task List" that needs to be passed in the POST request header, e.g.
POST https://www.googleapis.com/tasks/v1/lists/MTA1MjEpoqwdNTMzMjAzo349YDA6MDow/tasks
You can find the id of the list by doing a tasklists 'list' query.
GET https://www.googleapis.com/tasks/v1/users/#me/lists
which returns, e.g. something like this:
{
"kind": "tasks#taskList",
"id": "MTA1MjEpoqwdNTMzMjAzo349YDA6MDow",
"title": "My Task List",
"updated": "2019-03-15T21:21:03.000Z",
"selfLink": "https://www.googleapis.com/tasks/v1/users/#me/lists/MTA1MjE0Njc5NTMzMjA1NDk0NDA6MDM1NDgwMjIxODgyMjcyODow"
}
You can see the tasklist id in the response, which can then be used in the POST to modify the desired tasklist.
Answers to this question have been posted, but none with explicit examples. Hopefully this example will help someone get past this newbie kind of problem.

Categories

Resources