coding watson conversation for complex inputs? - javascript

I would like to know how can I integrate some coding (python or javascript) in my dialog, in order to avoid the very limited bluemix interface for example for loops, or text mining.
EX : I am creating a pizza chatbot and I need to be able to process this kind of request :
I would like 2 margarita whose one with extra cheese and the other with pepperoni and a regina, with 3 diet cokes and two beers
It is just impossible to do it with bluemix.
If anyone has a solution I would be very grateful.
Thanks

So the first thing to understand is that Conversation has good and bad use cases.
If your user can enter in structured data, then it is better to use a form. Be that in the conversation window (like Watson Virtual Agent), or a form on your site/app.
So your example doesn't look like a good use case.
That said...
With your example it's possible if your main items are entities, and you haver #sys-number system entity enabled. You can then check the entities array to see distance from each other.
Example
Created the following entities.
#PizzaType
#PizzaTopping
#Drinks
When I ask your question, the entities object returns the following:
[
{
"entity": "Drinks",
"location": [
104,
114
],
"value": "diet coke",
"confidence": 1
},
{
"entity": "PizzaType",
"location": [
72,
81
],
"value": "Pepperoni",
"confidence": 1
},
{
"entity": "Drinks",
"location": [
123,
128
],
"value": "beer",
"confidence": 1
},
{
"entity": "PizzaType",
"location": [
88,
94
],
"value": "Regina",
"confidence": 1
},
{
"entity": "PizzaTopping",
"location": [
46,
52
],
"value": "cheese",
"confidence": 1
},
{
"entity": "PizzaType",
"location": [
15,
24
],
"value": "Margarita",
"confidence": 1
},
{
"entity": "sys-number",
"location": [
13,
14
],
"value": "2",
"confidence": 1,
"metadata": {
"numeric_value": 2
}
},
{
"entity": "sys-number",
"location": [
31,
34
],
"value": "1",
"confidence": 1,
"metadata": {
"numeric_value": 1
}
},
{
"entity": "sys-number",
"location": [
101,
102
],
"value": "3",
"confidence": 1,
"metadata": {
"numeric_value": 3
}
},
{
"entity": "sys-number",
"location": [
119,
122
],
"value": "2",
"confidence": 1,
"metadata": {
"numeric_value": 2
}
}
]
A summary of that is:
You can see straight away there are some issues there. If the user doesn't mention a number, you have to account for that. Also something like this question would break it as well (unless you cater for it).
I would like margarita pizzas (two).
But the important point is to build your system with representative questions. Your example question may never be asked by an end user, or you can even shape the conversation to prevent such an input.

Related

Google Sheets not receiving json data properly from Woocommerce Webhook

I hope you guys are having a wonderful day.
I have set up a webhook in my woocommerce that sends JSON data to Google sheets. The webhook has been working great for months now, just today, I am having some trouble with it. I have tracked the issue to be in google sheets receiving the JSON data, but I don't know why this is happening.
Let me explain.
https://docs.google.com/spreadsheets/d/18G-yVDjYeccl6kznpZgSuRTysRMAu57pwY2oGf6-KWI/edit?usp=sharing
This is the google sheet, when it gets Woocommerce JSON data, it populates a new row.
The problem
Sometimes google sheets doesn't populate the row upon receiving a new order. The problem doesn't lie with woocommerce, because I have checked woocommerce with reqbin and the webhook fires with every order.
Furthermore, when I send requests from reqbin.com to my sheet, the sheet performs the operation successfully 5-6 out of 10 times. Other times it shows an error.
The Error
The error is due to google sheets not being able to parse JSON data, because the JSON data it receives 5 out of 10 times is not proper JSON data. Other 5 times, it is just as it should be. I have put a catch statement if the sheet is unable to parse JSON. Instead of appending new row with the parsed data, it appends the raw received data to the sheet.
It is clear now that there is some issue with google sheets handling that JSON data because when the same data is sent from reqbin.com to webhook.site, it is perfectly as it should be 10/10 times.
How to reproduce the issue
Open this google sheet. https://docs.google.com/spreadsheets/d/18G-yVDjYeccl6kznpZgSuRTysRMAu57pwY2oGf6-KWI/edit?usp=sharing
Open reqbin.com and webhook.site, and send the following JSON from reqbin.com to webhook.site 10 times to see if any kind of error occurs.
{ "id": 47222, "parent_id": 0, "status": "processing", "currency": "PKR", "version": "5.1.0","prices_include_tax": false, "date_created": "2021-06-10T01:23:46", "date_modified": "2021-06-10T01:23:46", "discount_total": "0", "discount_tax": "0", "shipping_total": "150", "shipping_tax": "0", "cart_tax": "0", "total": "1850", "total_tax": "0", "customer_id": 0, "order_key": "wc_order_7gIuR7px6MX9C", "billing": { "first_name": "Name", "last_name": "", "company": "", "address_1": "Address", "address_2": "", "city": "City", "state": "", "postcode": "", "country": "PK", "email": "email#email.com", "phone": "1234" }, "shipping": { "first_name": "Name", "last_name": "", "company": "", "address_1": "Address", "address_2": "", "city": "City", "state": "", "postcode": "", "country": "Country" }, "payment_method": "cod", "payment_method_title": "Cash on delivery", "transaction_id": "", "customer_ip_address": "8.8.8.8", "customer_user_agent": "Mozilla/5.0 (Linux; Android 11; M2102J20SG) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.88 Mobile Safari/537.36", "created_via": "checkout", "customer_note": "", "date_completed": null, "date_paid": null, "cart_hash": "64d834c72eecc8e32b9d83fd67d10d9c", "number": "47222", "meta_data": [ { "id": 869388, "key": "_shipping_calculator", "value": "" }, { "id": 869389, "key": "is_vat_exempt", "value": "no" }, { "id": 869391, "key": "_wfacp_report_data", "value": { "wfacp_total": "0.00" } }, { "id": 869392, "key": "_woofunnel_cid", "value": "4" }, { "id": 869393, "key": "_wfacp_post_id", "value": "24852" }, { "id": 869394, "key": "_wfacp_source", "value": "https://website.com/checkouts/checkout-page/" }, { "id": 869395, "key": "_wfacp_timezone", "value": "Asia/Karachi" }, { "id": 869396, "key": "order_comments", "value": "" }, { "id": 869412, "key": "_new_order_email_sent", "value": "true" }, { "id": 869424, "key": "_woofunnel_custid", "value": "4" }, { "id": 869425, "key": "_pys_purchase_event_fired", "value": "1" }, { "id": 869426, "key": "_wfob_stats_ids", "value": [] }, { "id": 869427, "key": "_wfocu_thankyou_visited", "value": "yes" } ], "line_items": [ { "id": 35114, "name": "MTECH Ultra Resilient Knife", "product_id": 11074, "variation_id": 0, "quantity": 1, "tax_class": "", "subtotal": "1700", "subtotal_tax": "0", "total": "1700", "total_tax": "0", "taxes": [], "meta_data": [], "sku": "", "price": 1700, "parent_name": null } ], "tax_lines": [], "shipping_lines": [ { "id": 35115, "method_title": "Fast Shipping (2-4 Days)", "method_id": "flat_rate", "instance_id": "1", "total": "150", "total_tax": "0", "taxes": [], "meta_data": [ { "id": 275053, "key": "Items", "value": "MTECH Ultra Resilient Knife × 1", "display_key": "Items", "display_value": "MTECH Ultra Resilient Knife × 1" } ] } ], "fee_lines": [], "coupon_lines": [], "refunds": [], "date_created_gmt": "2021-06-09T20:23:46", "date_modified_gmt":"2021-06-09T20:23:46", "date_completed_gmt": null, "date_paid_gmt": null, "currency_symbol": "₨","_links": { "self": [ { "href": "https://website.com/wp-json/wc/v3/orders/47222" } ],"collection": [ { "href": "https://website.com/wp-json/wc/v3/orders" } ] } }
Now send the same data to the following google sheet to see if it appends the row correctly each time.
https://script.google.com/macros/s/AKfycbxupm9bje86F4PQQkyys_LWtXs_kj279R0ipgnZ-cLd7aiEADf1AN_prhk28vOPW9JsRQ/exec
How do I solve the issue? Please let me know if you need any more information. Thanks.
Edit:
Instead of getting a full JSON body like mentioned above, the google sheets seems to be getting the following JSON.
{contextPath=, queryString=, parameter={}, postData=FileUpload, parameters={}, contentLength=3981.0}
I would like to know why the google sheets default parameter (e) contains this instead of a full JSON body sent to it.
Edit # 2
I would like to know why the google sheets default parameter (e) contains this instead of a full JSON body sent to it.
This is because (e) has a body which will always contain those parameters. The error is due to Google Sheets receiving an empty JSON body. I am still unable to understand why this happens. When I send the same JSON to API testing sites, they always receive full JSON body. Google sheets, in some cases, does not. Why is that?
I managed to solve the issue with some trial and error. For anyone facing the same issue in the future, here is what worked for me.
I was using e.postData.contents to get the JSON body but this seems to have stopped working, which was causing the JSON body to be empty. I tried e.postData.getDataAsString(); which seems to be working just fine and the issue has been resolved.

How can I access the value of elements nested deeply within several objects and arrays?

I'm making an API call to return data from the Google Distance Matrix API and saving that data in my (react)redux store.
The data object being returned is structured like this:
Object {
"destination_addresses": Array [
"21 Foo St, SomeCity, SomeState 33333, USA",
],
"origin_addresses": Array [
"5555 Somewhere Dr, Somewhere, Somewhere 55555, USA",
],
"rows": Array [
Object {
"elements": Array [
Object {
"distance": Object {
"text": "2,302 mi",
"value": 3703935,
},
"duration": Object {
"text": "1 day 10 hours",
"value": 123162,
},
"status": "OK",
},
],
},
],
"status": "OK",
}
That data structure is returned when I console.log(this.props.matrixData).
I need to access distance.text & duration.text so that I can display them on a component screen.
I made several different failed attempts like
this.props.matrixData.rows.elements.distance.text
and
this.props.matrixData.rows[0].elements[0]
etc to access deeper, but this.props.matrixData.rows is the deepest I've been able to get without throwing an error.
Can someone help please?
I tried your example in the (Chrome) browser console, but I left out the "type annotations". Your second example for access works for me, I am not sure why it would fail.
var o = {
"destination_addresses": [
"21 Foo St, SomeCity, SomeState 33333, USA",
],
"origin_addresses": [
"5555 Somewhere Dr, Somewhere, Somewhere 55555, USA",
],
"rows": [
{
"elements": [
{
"distance": {
"text": "2,302 mi",
"value": 3703935,
},
"duration": {
"text": "1 day 10 hours",
"value": 123162,
},
"status": "OK",
},
],
},
],
"status": "OK",
};
o.rows[0].elements[0]; // logs "Object { distance: {…}, duration: {…}, status: "OK" }"
Please note that o.rows[0].elements[0] will throw an error if one of the Arrays is empty. There are libraries which fail gracefully in such cases:
https://ramdajs.com/docs/#path, see also an example of Ramda path
https://lodash.com/docs/#get

Append '|' after every array element

I have this JSON & what I want to do is to make genres like this action|adventure|comedy
{
"id": 1,
"key": "deadpool",
"name": "Deadpool",
"description": "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool.",
"genres": [
"action",
"adventure",
"comedy"
],
"rate": 8.6,
"length": "1hr 48mins",
"img": "assets/images/movie-covers/deadpool.jpg"
},
{
"id": 2,
"key": "we-are-the-millers",
"name": "We're the Millers",
"description": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.",
"genres": [
"adventure",
"comedy",
"crime"
],
"rate": 7,
"length": "1hr 50mins",
"img": "assets/images/movie-covers/we-are-the-millers.jpg"
}
my component code snippet
data => {
this.movies = data;
var tempArr= data
var genres;
let genresWithPipe=[];
let len= tempArr.length;
for(var i=0; i<len; i++){
genres=tempArr[i].genres+'|';
// console.log(tempArr[i].genres)
for(var j=0;j<genres.length; j++){
if(j<genres.length-1)
genres[j]= genres[j]+'|';
console.log(genres,data);
//genresWithPipe=genres;
}
}
console.log(this.movies,genres)
}
I have tried to do it with the help of for loop in my component but then when I am displaying it in the html with the help of *ngFor then because it's a local variable,it won't show up. If I store array values in a global variable then the variable only store the last array.
You can use map method in order to achieve your requirement and obtain a more cleaner solution.
The map() method creates a new array with the results of calling a
provided function on every element in the calling array.
Also, you can use join method in order to obtain the structure action|adventure|comedy with | delimiter.
let array=[{ "id": 1, "key": "deadpool", "name": "Deadpool", "description": "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool.", "genres": [ "action", "adventure", "comedy" ], "rate": 8.6, "length": "1hr 48mins", "img": "assets/images/movie-covers/deadpool.jpg" }, { "id": 2, "key": "we-are-the-millers", "name": "We're the Millers", "description": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.", "genres": [ "adventure", "comedy", "crime" ], "rate": 7, "length": "1hr 50mins", "img": "assets/images/movie-covers/we-are-the-millers.jpg" }];
array=array.map(function(item){
item.genres=item.genres.join('|');
return item;
});
console.log(array);
A good solution with Array.map() has been proposed, here is another option with Array.forEach():
const data = [{
"id": 1,
"key": "deadpool",
"name": "Deadpool",
"description": "A former Special Forces operative turned mercenary is subjected to a rogue experiment that leaves him with accelerated healing powers, adopting the alter ego Deadpool.",
"genres": [
"action",
"adventure",
"comedy"
],
"rate": 8.6,
"length": "1hr 48mins",
"img": "assets/images/movie-covers/deadpool.jpg"
},
{
"id": 2,
"key": "we-are-the-millers",
"name": "We're the Millers",
"description": "A veteran pot dealer creates a fake family as part of his plan to move a huge shipment of weed into the U.S. from Mexico.",
"genres": [
"adventure",
"comedy",
"crime"
],
"rate": 7,
"length": "1hr 50mins",
"img": "assets/images/movie-covers/we-are-the-millers.jpg"
}
]
const genres = [];
data.forEach(film => genres.push(film.genres.join("|")));
console.dir(genres);
Note that your data definitely doesn't look like what you put in the code sample, it must be wrapped with [].

Request a complete response object instead of compact reponse object foursquare venues search api?

When we request a api call to foursquare for search venues of certain category
It returns a compact response not complete response because of which i am not able to get complete information about the place like if the place is open, price etc which is only returned in a complete response, can i get a complete response instead of compact response?? more info provided here.
Eg:
call:https://api.foursquare.com/v2/venues/search?ll=18.5308225,73.8474647&categoryId=4bf58dd8d48988d1e1931735&radius=1000&v=20131021&limit=1
Result:
{
"meta": {
"code": 200
},
"response": {
"venues": [{
"id": "4b975471f964a520c9ff34e3",
"name": "Yana Sizzler & Wok",
"contact": {
"phone": "+912066013897",
"formattedPhone": "+91 20 6601 3897"
},
"location": {
"address": "F C Road",
"lat": 18.52802688063791,
"lng": 73.84272476029567,
"distance": 589,
"cc": "IN",
"city": "Pune",
"state": "India",
"country": "India"
},
"categories": [{
"id": "4bf58dd8d48988d1df931735",
"name": "BBQ Joint",
"pluralName": "BBQ Joints",
"shortName": "BBQ",
"icon": {
"prefix": "https:\/\/ss1.4sqi.net\/img\/categories_v2\/food\/bbq_",
"suffix": ".png"
},
"primary": true
}],
"verified": false,
"restricted": true,
"stats": {
"checkinsCount": 542,
"usersCount": 402,
"tipCount": 19
},
"specials": {
"count": 0,
"items": []
},
"hereNow": {
"count": 0,
"groups": []
},
"referralId": "v-1386276988"
}]
}
}
But i am not getting informatiion like isOpen Price etc which we get in the complete response when we use explore.
The API does not support returning complete objects in venue search responses—you need to make a separate venue details call to get the information you're looking for. We recommend caching venue details (for up to 30 days) to avoid having to repeatedly calling this endpoint to retrieve this information that doesn't necessarily change that often.

Cannot access array objects when that array is itself an attribute of an object

I am unable to access an array of objects that is itself an attribute of a larger object.
console.log(skillprofiles);
console.log(skillprofiles.skills);
The above statements return an array of two objects that each have an attribute that is a, seemingly, valid array of objects ("skills" in this example).
I am unable to access the "skills" array attribute. The data I am ultimately trying to get at is the "item_name" attribute. As far as I know, that should be accessible via:
skillprofiles[0].skills[0].item_name
Interestingly enough, verifying the type of the "skills" attribute with "typeof" returns "object" instead of array. This could be because I am transferring an array of objects from one object to another earlier in my code. I thought I was doing this properly and seemed to have confirmed that by my logging statements.
UPDATE with actual data:
[{
"skillprofile_id": 144,
"skillprofile_name": " On-boarding",
"start_date": "January 30 2012",
"progress": 0,
"complete_date": " ",
"category": 1053,
"skills": [{
"category": "Acquire: Onboard New Hires",
"item_name": "3. On-boarding a New Hire - Day 1",
"skill_type": "activity",
"object_id": 68,
"duration": "8:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}, {
"category": "Acquire: Onboard New Hires",
"item_name": "4. On-boarding Checklist",
"skill_type": "activity",
"object_id": 67,
"duration": "1:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}]
}, {
"skillprofile_id": 143,
"skillprofile_name": " Setting Up Systems",
"start_date": "January 30 2012",
"progress": 0,
"complete_date": " ",
"category": 1053,
"skills": [{
"category": "Acquire: Onboard New Hires",
"item_name": "1. Office Organization",
"skill_type": "activity",
"object_id": 65,
"duration": "4:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}, {
"category": "Acquire: Onboard New Hires",
"item_name": "2. Welcome to the Team Documents",
"skill_type": "activity",
"object_id": 66,
"duration": "2:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}, {
"category": "Acquire: Onboard New Hires",
"item_name": "3. Welcome Documents: Feedback ",
"skill_type": "activity",
"object_id": 150,
"duration": "1:00:00",
"sco_status_code": 6,
"action": "activity",
"has_forums": false
}]
}]
UPDATE 2:
Given the responses so far, it seems that I should be able to run the following:
$.each(skillprofiles, function(){
console.log(this.skills)
});
I can do this from the console, but the console statements come back as "undefined" when run from my code
In your first block of code, skills is directly a child of skillprofiles. Whereas in the second one, you write skillprofiles[o].skills. If the first one works, maybe your code should be:
skillprofiles.skills[0].item_name
With that data structure, the proper access would be:
skillprofiles[i].skills[j].item_name
You can see it work here: http://jsfiddle.net/jfriend00/wPLZZ/
skillprofiles is an array of objects so you get an object from the array with:
skillprofiles[i]
Each object in that array, has a number of properties and one of those properties is named skills so you would get that property with
skillprofiles[i].skills
The contents of the skills property is another array so you would get an item from that aray with this:
skillprofiles[i].skills[j]
That array holds objects with their own properties so you would access a specific property with this:
skillprofiles[i].skills[j].item_name

Categories