0

I receive a json object with some number of quick reply elements from wit.ai, like this:

 "msg": "So glad to have you back.  What do you want me to do?  
 "action_id": "6fd7f2bd-db67-46d2-8742-ec160d9261c1",
 "confidence": 0.08098269709064443,
 "quickreplies": [
   "News?",
   "Subscribe?",
   "Contribute?",
   "Organize?"
 ],
 "type": "msg"

I then need to convert them to a slightly different format as they are passed to FaceBook Messenger as described in the code below. Wit only exposes 'msg' and 'quickreplies.' Can you suggest a good way to do this? It goes after "console.log(element)" as far as I understand.

      if (quickreplies){
        // got simple array of quickreplies
        // need to format quickreplies for FB:
                                  //  "quick_replies":[
                                  //     {
                                  //       "content_type":"text",
                                  //       "title":"Red",
                                  //       "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_PICKING_RED"
                                  //     },
                                  //     {
                                  //       "content_type":"text",
                                  //       "title":"Green",
                                  //       "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_PICKING_GREEN"
                                  //     }
        console.log('we got quickreplies, here they are:');
        var quick_replies = []; // ??
        quickreplies.forEach(function(element) {
          console.log(element)

        });
      }
      else (console.log('no quickreplies'));                               

In the above example, the end result should be this:

 "recipient":{
    "id":"USER_ID"
  },
  "message":{
    "text":"Pick a color:",
    "quick_replies":[
      {
        "content_type":"text",
        "title":"Red",
        "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_PICKING_RED"
      },
      {
        "content_type":"text",
        "title":"Green",
        "payload":"DEVELOPER_DEFINED_PAYLOAD_FOR_PICKING_GREEN"
      }
    ]
  }
jeromekjerome
  • 501
  • 1
  • 8
  • 26
  • What's the format of a quick reply from `wit.ai?` Have you tried to convert one into FB format? `var quick_replies=quickreplies.map( conversionFunction)` may be better than `.forEach` – traktor Feb 05 '17 at 22:23
  • If I read it correctly, this conversion is part of preparing a message object whose text property will be "welcom back...." and will contain a `quick_replies` array. Each `quick_reply` object will have a title such as "subscribe" and a payload _that will be returned as metadata_ when receiving a reply in conversation. The next step is to decide what that metadata needs to be for each action, based on how you are going to tell the bot what the response is. – traktor Feb 05 '17 at 23:13
  • Yes. But at this stage I would be very happy just to see the quick replies show up as buttons on the FB bot. To do that, I only need to format it correctly and send it over to FB. – jeromekjerome Feb 05 '17 at 23:20

1 Answers1

1

I am not sure if this has been a course of confusion, but there is no such thing as a "JSON object". One works with data objects returned by JSON.parse in the same manner as working with any other object. Before sending to FB, of course, data objects have to be converted into JSON string format using JSON.stringify. This might occur automatically in some code libraries depending on how the data is sent.

Here's an example of preparing a quick-replies array - I simply chose an example structure for the payload and went with it. The quick_replies array is still an object and has not been converted to a JSON string.

Edit the format of a text only payload, shown in the first text only example for quick replies indicates the payload is a string. The code below had been updated to meet with this requirement.

// test values for quickreplies:

var quickreplies= [ "News?", "Subscribe?", "Contribute?", "Organize?" ];

/********

     convert quickreplies to quick_replies array
     using an example payload of:

     { "text" : "text string",       // button text
       "index" : index,              // index into quickreply for button
       "other": "tbd"                // anything else needed in a reply
     }

*********/
var quick_replies;
if (quickreplies) {
    console.log('we got quickreplies, here they are:');
    quick_replies = quickreplies.map( function(element, index) {

        var payload = {
                text: element,
                index: index,
                other: "tbd"    // example value only.
        };
        var payloadString = JSON.stringify( payload);
        console.log(element);
        var quick_reply = {
            content_type: "text",
            title: element,
            payload: payloadString
        };
        console.log("** converted to : " + JSON.stringify(quick_reply));
    });
    quickreplies=null; // housekeeping
}
else {
    console.log('no quickreplies');
    quick_replies = undefined; // or [] ?
}
traktor
  • 17,588
  • 4
  • 32
  • 53
  • action_id is undefined but if commented out, this code works. – jeromekjerome Feb 06 '17 at 15:45
  • it works on first pass but fails after that, looks like housekeeping problem – jeromekjerome Feb 06 '17 at 16:02
  • edited your code above, added housekeeping, works good so far – jeromekjerome Feb 06 '17 at 20:45
  • edit accepted with two changes: replaced `action_id` with `other` and moved housekeeping reset of `quickreplies` outside the `map` function. The whole payload structure was for example and should be modified to suit your requirements in a reply. – traktor Feb 06 '17 at 22:07
  • I'm not sure why you want the payload structured that way. When the user presses the quickreply button, I suppose my bot will get the payload back, so I could adapt to anything in the payload so long as it adds value. – jeromekjerome Feb 07 '17 at 00:26
  • Thank you so much for the help. I've updated the data structure in the question to show that quick replies are part of "message" that includes "text" and "quick_replies". Sorry for being such a dunce, but how would you modify your code to append the array of quick replies to the "message" that already includes "text"? – jeromekjerome Feb 07 '17 at 23:55
  • Work with a reply object, let's say `reply`, rather than text. For the text only example then, `reply` will have a property, of type object, called `message`. This property will have a property `text` and can have also take a `quick_replies` property. So you add quick replies as `reply.message.quick_replies = array_of_quick_replies`. Conversion of `reply` to a JSON string is only performed once, as part of Ajax processing. – traktor Feb 08 '17 at 01:47