Digital Assistant and Mobile

Get Involved. Join the Conversation.

Topic

    Abhishek Singh
    postback action is not getting triggered on MessageModel...Answered
    Topic posted September 9, 2018 by Abhishek SinghRed Ribbon: 250+ Points, tagged Bots, Mobile, OMCE 
    125 Views, 7 Comments
    Title:
    postback action is not getting triggered on MessageModel cards
    Content:

    In my custom component, i am calling one rest api to fetch the data and then putting into cards with actions on each card (no global action) but i am clicking on any card, it is not triggering any action button and simply moving to next state. i.e. it is supposed to call my custom component where i am handling if postback/ textReceived things as it has been described in "cmmcards" sample by Frank, but in my case it is not getting called.

    Not able to figure out why it is not getting triggerd? I have integrated "cmmcardssample" by frank, which is working fine but not mine.

    Image:
    Code Snippet:

    Best Comment

    Abhishek Singh

    I just removed just two line from the above code and it worked great. But seeking further clarification on what is the meaning of not putting those two lines

    conversation.reply(cardResponseMessage);
    // conversation.keepTurn(false);
    // conversation.transition();
    done();

     

    Comment

     

    • Frank Nimphius

      Hi,

       

      the code only shows how you create the card. It does not show how you intercept the postback calls in your custom component. It also does not show the use of conversation.transition(...)

       

      Frank

      • Abhishek Singh
        "use strict";
         
        var log4js = require('log4js');
        var logger = log4js.getLogger();
        console.log(" Abhishek: inside products.js file of tst_cxproductsccs module");
        module.exports = {


         
        metadata: () => ({
        "name": "CX.tst_products",
        "properties": {
        "productName": { "type": "string", "required": false },
        "brandName": { "type": "string", "required": false },
        "listPrice": { "type": "number", "required": false },
        "salePrice": { "type": "number", "required": false },
         
        "variable": { "type": "string", "required": true },
        "cardlayout": { "type": "string", "required": false },
        "keepTurn": { "type": "boolean", "required": false }
        },
        "supportedActions": ["found", "error", "textReceived"]
        }),
         
        invoke: (conversation, done) => {
         
        // context parameters
        const productName = conversation.properties().productName ? conversation.properties().productName : "";
        const brandName = conversation.properties().brandName ? conversation.properties().brandName : "";
        const listPrice = conversation.properties().listPrice ? conversation.properties().listPrice : "";
        const salePrice = conversation.properties().salePrice ? conversation.properties().salePrice : "";
         
        // card parameters
        var cardLayout = conversation.properties().cardlayout ? conversation.properties().cardlayout : "vertical";
        var keepTurn = conversation.properties().keepTurn ? conversation.properties().keepTurn : false;
        var variableName = conversation.properties().variable;
         
        // card tracker, if true i.e. already rendered, else yet to be rendered
        var statetracker = (conversation.variable('___cardcomp_state___') == 'true') ? 'true' : 'false';
         
        console.log("Abhishek: productName " + productName + " brandName " + brandName + " listPrice " + listPrice + " salePrice " + salePrice);
        console.log('Abhishek: cardLayout ' + cardLayout);
        console.log('Abhishek: keepTurn ' + keepTurn);
        console.log('Abhishek: variableName ' + variableName);
        console.log('Abhishek: statetracker ' + statetracker);
         
        // query string arguments
        var args = {};
        args.productName = productName;
        args.brandName = brandName;
        args.listPrice = listPrice;
        args.salePrice = salePrice;


         
         
        // let postbackpayload = conversation.postback();
        // console.log("Abhishek : before any if else postbackpayload " + JSON.stringify(postbackpayload));
        console.log('Abhishek: before any if else statetracker '+statetracker);
        //handle postback response i.e. user has selected one option among the cards
        // postback is true and statetracker is true
        if (conversation.postback() && statetracker == 'true')
        {
        console.log('Abhishek: Inside postback and card is already rendered')
        //reset state tracker ,
        conversation.variable('___cardcomp_state___', 'false');
         
        //postback contains a key-value object
        let postbackpayload = conversation.postback();
         
        console.log('Abhishek: variableName ' + variableName+' getting updated with '+ postbackpayload[variableName]);
         
        // console.log('Abhishek:variableName ' + postbackpayload[variableName]);
        // update variable with the postback value
         
        conversation.variable(variableName, postbackpayload[variableName]);
        console.log(' Abhishek : keepTurn '+keepTurn);
        conversation.keepTurn(keepTurn);
        conversation.transition('found');
        done();
         
        }
        //handle text response returning textReceived action as CRC component does
        else if (conversation.text() && statetracker == 'true')
        {
         
        console.log(' Abhishek: text has been received and card has been already rendered')
        //reset state tracker
        conversation.variable('___cardcomp_state___', 'false');
        conversation.transition('textReceived');
        //navigate to the next state with no further user input required
        conversation.keepTurn(true);
        done();
        }
         
        else{


         
        conversation.variable('___cardcomp_state___', 'true');
         
        conversation.oracleMobile.custom.tst_cxproducts.post('products', args, {
        inType: 'json'
        }).then(
         
        function (result) {
         
        //set state tracker indcating that card has been rendered
        console.log('Abhishek : inside Else i.e. rendering first time');
         
        var productsInfo = JSON.parse(result.result); // returned from shared api string
        var prodObj = JSON.parse(productsInfo); // object
        var itemArray = prodObj.items; // all items
        console.log('Abhishek: the number of items we have '+itemArray.length);
        var serviceuri = 'https://ccadmin-stage-nbgb.oracleoutsourcing.com';
        console.log('Abhishek: statetracker ' + statetracker);
         
        var cards = []; // to store messageModel objects
         
        if ((typeof itemArray) === "object") {
         
        for (var indexOfObject in itemArray) {
         
        var prodImages = itemArray[indexOfObject].thumbImageURLs;
         
         
        var brand = itemArray[indexOfObject].brand ? itemArray[indexOfObject].brand : "--";
        var description = itemArray[indexOfObject].description ? itemArray[indexOfObject].description : "--";
        var displayName = itemArray[indexOfObject].displayName ? itemArray[indexOfObject].displayName : "--";
        var lsPrice = itemArray[indexOfObject].listPrice ? itemArray[indexOfObject].listPrice : "--";
        console.log('Abhishek: Inside Else, action key '+variableName+' value '+brand);
         
         
        console.log(' prodImages.length '+prodImages.length+ '(typeof prodImages '+(typeof prodImages));
         
        if (prodImages.length != 0 && (typeof prodImages) === "object") {
        console.log('Abhishek : if of push ');
        let action = conversation.MessageModel().postbackActionObject('Buy at' + lsPrice + ' only', null, {
        //define which variable to update when postback action is used
        [variableName]: brand
        });
         
        let cardObj = conversation.MessageModel().cardObject(brand, description, serviceuri + prodImages, null, [action]);
        cards.push(cardObj);
        } else {
        console.log('abhishek : inside else of push');
         
        let action = conversation.MessageModel().postbackActionObject('Buy at' + lsPrice + ' only', null, {
        //define which variable to update when postback action is used
        [variableName]: brand
        });
        let cardObj = conversation.MessageModel().cardObject(brand + '\n' + displayName, description, null, null, [action]);
        cards.push(cardObj);
         
        }
         
        } // end of for loop
        } // end of if
         
         
        // var cardResponseMessage = conversation.MessageModel().cardConversationMessage(cardLayout, cards, null);
        var cardResponseMessage = conversation.MessageModel().cardConversationMessage(cardLayout, cards);
         
        conversation.reply(cardResponseMessage);
        conversation.keepTurn(false);
        conversation.transition("found");
        done();
        }, // end of result
         
        function (error) {
        var errorInfo = JSON.parse(error.error); // returned from shared api
        conversation.reply({ text: 'Oops! Error encountered ' + JSON.stringify(errorInfo) });
        conversation.transition("error");
        done();
        } // end of error
         
         
        ); // end then
        } // end of else
        } // end of invoke
        }; // end of exports
    • Frank Nimphius

      Hi,

       

      look at this:

       

                          var cardResponseMessage = conversation.MessageModel().cardConversationMessage(cardLayout, cards);

                          conversation.reply(cardResponseMessage);
                          conversation.keepTurn(false);
                          conversation.transition("found");
                          done();

       

      After rendering the cards it seems you transition to "found", which basically means that when you press a postback button you actually provide input for the next state

       

      Frank

      • Abhishek Singh

        Forgot to thank, hope you ignore my ignorance as rightly it has been said, "Ignorance is blisssss" :)

        Thank you Frank.

    • Abhishek Singh

      I just removed just two line from the above code and it worked great. But seeking further clarification on what is the meaning of not putting those two lines

      conversation.reply(cardResponseMessage);
      // conversation.keepTurn(false);
      // conversation.transition();
      done();

       

    • Frank Nimphius

       

      conversation.transitions( ... ) triggers navigation to a next state. keepTurn defines whether users need to provide input (false) or not (true).  

      Frank