Making a Facebook Messenger Chatbot

Written By Chetan Iterate (Administrator)

Updated at January 5th, 2021

We can actually make a Facebook messenger chatbot in Interplay.

But first, we have to understand the basic component to make a chatbot. The framework for making chatbot is similar to different platforms and quite easy to understand.

Let's understand the components first.

1 ) Facebook Receiver Node: It takes the string input from the Facebook chatbot and injects it into the flow as payload. It catches string in

msg.payload.content

2 ) Facebook Sender Node: The sender node is responsible to relay created node outputs in the messenger bot window.

3) Conversation sequence: This Node acts as the switch and is responsible for selecting different node flows based on the input string from the receiver.


Steps:

1) Create and save all the credentials of the Facebook developer account.

2) Drag the following two nodes in the workflow editor given below:

        1) Facebook in and

        2 ) Facebook out

These nodes are specifically made for Facebook messenger for flow initialization and termination

2 ) Edit the 'Facebook in' node by double-clicking  click on next to Bot configuration(development) to reveal more settings as given below

Similar settings are applicable for 'Facebook out' Node.

3 ) Check that both the nodes have the 'Connected' Tag beneath them. If it looks like this:

Then nodes can communicate to messenger API and are good to go.

4 ) Search and drag the switch node for a sequence which look like this:

We can direct conversation by this switch node. When comparing conditions to the input string, we set up our string to match like this :For this example we created a simple input switch which triggers the flow based on input values as numbers.

6 ) With all things settled up, we connect the nodes with each other like this 

The nodes prior to the conversation sequence are only to:

        set global variables: initial setup for creating the chatbot environment

        session initializer: creating a session for chatbot

We created a custom function 'FacebookOut_InitialStage' to initiate flow and end to 'Facebook Sender'. To parse output in the chatbot

we can easily create more flows like this to complete the project.


7) Now come to the blockchain part where Interplay provides the Ether blocks and keep them optional if the ether token exists

Find and drop the 'Content Ether Create customer', 'Content ether Token','Content Ether customer Transactions', 'Content Ether Token Balance' which look like this:

With other Node. js Functions, we create flows as shown:

Connected with original 'Facebook Receiver' for parallel flow 

Function code for :  Auth is Present :

var require = context.global.get('require'); node.warn("auth is present");msg.auth=global.get('blockchain_auth');node.warn(msg.auth);var chat = msg.chat();msg.UserName            = chat.get('firstName') + " " + chat.get('lastName'); msg.SenderName          = msg.UserName; msg.customer = {"type": "customer","name":msg.SenderName, "username":msg.UserName, "network":"Rinkeby Test Network", "api_version":"1","count":"10"};return msg;


Function code for : Set global Variables

var require = context.global.get('require'); var conversation_state=global.get('convo_state');var input_recieved_i1=global.get('input_state');if (input_recieved_i1===undefined) {    global.set('input_state',undefined);    input_recieved_i1=global.get('input_state');}// global.set('convo_step',0);var input_recieved_i2=global.get('input_state')if (conversation_state===undefined) {    global.set('convo_state',0);    conversation_state=global.get('convo_state');}// node.warn("counter value "+conversation_step// if (msg.payload.content == 'FlowCommand_GUEST_LEGALACCEPT'){//     global.set('convo_state',1);//     node.warn("User accepts it");//     conversation_state=global.get('convo_state');// }// if (msg.payload.content == 'FlowCommand_SHOWURL_ULTACOMPRIVACYPOLICY'){//     global.set('convo_state',2);//     node.warn("User wants to check for privacy policy");//     conversation_state=global.get('convo_state');// }if (msg.payload.type==='photo'){    global.set('convo_state','OCR_photo');    node.warn("User Provides a photo");    conversation_state=global.get('convo_state');}else{    switch(msg.payload.content){    case "FlowCommand_GUEST_LEGALACCEPT":         global.set('convo_state',1);        node.warn("User accepts legal shizz");        conversation_state=global.get('convo_state');        break;    case "FlowCommand_SHOWURL_ULTACOMPRIVACYPOLICY":        global.set('convo_state',2);        node.warn("User wants to check for privacy policy");        conversation_state=global.get('convo_state');        break;    case "AddPoints":        global.set('convo_state','MT');        node.warn("User is missing points");        conversation_state=global.get('convo_state');        break;    case '3129829843':        global.set('convo_state','MT_phoneno');        node.warn("User provided phone no");        conversation_state=global.get('convo_state');        break;    case '04/24':        global.set('convo_state','MT_dob');        node.warn("User gave DOB");        conversation_state=global.get('convo_state');        break;    case 'Physical':        global.set('convo_state','MT_ocr');        node.warn("User purchased it in store");        conversation_state=global.get('convo_state');        break;     case 'Electronic':        global.set('convo_state','MT_ocr');        node.warn("User purchased it online");        conversation_state=global.get('convo_state');        break;    case 'user_ratings':        global.set('convo_state','MT_end');        node.warn("User finished MT flow");        conversation_state=global.get('convo_state');        break;    case "ViewProducts":        global.set('convo_state','show_product_categories');        node.warn("User has picked product carousel, show categories here");        conversation_state=global.get('convo_state');        break;    case "user_picked_shirts":        global.set('convo_state','show_shirts_from_product_carousel');        node.warn("User has picked shirts as category");        conversation_state=global.get('convo_state');        break;    case "user_picked_lipstick":        global.set('convo_state','show_lipsticks_from_product_carousel');        node.warn("User has picked lipstick as category");        conversation_state=global.get('convo_state');        break;    case "buying_this_shirt":        global.set('convo_state','shirt_purchase_complete');        node.warn("User selected which shirt to buy");        conversation_state=global.get('convo_state');        break;    case "buying_this_lipstick":        global.set('convo_state','lipstick_purchase_complete');        node.warn("User selected which lipstick to buy");        conversation_state=global.get('convo_state');        break;    case "points":        global.set('convo_state','using_points');        node.warn("User wants to purchase this using points in his account");        conversation_state=global.get('convo_state');        break;    case "card":        global.set('convo_state','using_card');        node.warn("User wants to purchase this using his/her card");        conversation_state=global.get('convo_state');        break;    case "ViewProducts_Manually":        global.set('convo_state','user_picked_manual_query');        node.warn("User wants to type out his/her question");        conversation_state=global.get('convo_state');        break;    case 'new_bee':        global.set('convo_state','user_needs_a_wallet');        node.warn("User wants to setup a new wallet");        conversation_state=global.get('convo_state');        break;    case 'old_bee':        global.set('convo_state','user_has_a_wallet');        node.warn("User already has a wallet");        conversation_state=global.get('convo_state');        break;    case 'user_doesnt_want_wallet':        global.set('convo_state','user_exit_wallet');        node.warn("User does not want to setup a wallet, paying using card");        conversation_state=global.get('convo_state');        break;    case 'ULTA4089813344':        global.set('convo_state','user_account_ID_verification');        node.warn("User gave their ID to verify and setup Wallet");        conversation_state=global.get('convo_state');         break;    case 'user_wants_to_convert_points':        global.set('convo_state','user_is_converting_points');        node.warn("User gave their acceptance to conversion");        conversation_state=global.get('convo_state');        break;     case 'user_said_no_redirect_to_wallet':        global.set('convo_state','user_said_no');        node.warn("User said NO for conversion, redirect");        conversation_state=global.get('convo_state');        break;}}if (input_recieved_i2==="Initial input recieved"){    var stage1="accept_input";    node.warn("Im here inside input_recieved_i1");    switch(stage1){    case "accept_input":        global.set('convo_state','user_input_recieved');        node.warn("User input recieved");        conversation_state=global.get('convo_state');        break;}}node.warn("counter value for conversation state is  "+conversation_state);return msg;

Function code for : Save BC token globally

var require = context.global.get('require'); global.set('blockchain_auth',msg.auth);node.warn(global.get('blockchain_auth'));

var chat = msg.chat();msg.UserName            = chat.get('firstName') + " " + chat.get('lastName'); msg.SenderName          = msg.UserName; msg.customer = {"type": "customer", // "name":msg.SenderName, "name":"contentether","username":msg.UserName, "api_version":"1","status":"active"};node.warn("customer created");node.warn(msg.customer);return msg;


Function code for :  Session Initializer:

var require = context.global.get('require'); var chat = msg.chat();    // msg.ConversationChannel === "Facebook";    msg.UserId              = msg.originalMessage.sender.id;    msg.UserName            = chat.get('firstName') + " " + chat.get('lastName');     msg.SenderName          = msg.UserName;var session_handler = global.get("IterateSessionHandler");if (session_handler === undefined) {    var cmemcache = require('/interplay_v2/cmemcache/cmemcache');    var memvar = context.global.get('memcached');    var memcached_servers = memvar.getServerLocations();    //var success = cmemcache.init('--SERVER=localhost');    var success = cmemcache.init(memcached_servers);    if(success != true)    {        node.error("Unable to initialize memcached servers");    }    else    {        global.set('IterateSessionHandler', cmemcache);        session_handler = global.get("IterateSessionHandler");    }}msg.session_handler = session_handler;// +----------------------------------+// | Conversation Type Initialization |// +----------------------------------+msg.ConversationType = msg.session_handler.get(msg.originalMessage.userId + "__CONVERSATION_TYPE");node.warn("session." + msg.originalMessage.userId +"__CONVERSATION_TYPE: " + msg.ConversationType);node.warn("[" + node.name + "]");var user_first_name = msg.UserName.split(' ')[0];var quick_reply;// if (msg.ConversationInitStage === null || msg.ConversationInitStage === undefined) {// }    // msg.session_handler.set(    //     msg.UserId + "__CONVERSATION_INITSTAGE",    //     0,    //     1    // );    // node.warn("here");    // node.warn(msg.ConversationSequence);    // if (msg.ConversationChannel === "Facebook" ) {    //     msg.payload = "D " + msg.UserId + " Hi " + user_first_name + ", welcome to Beauty Box! 👋";         // }    // msg.payload = "D " + msg.UserId + " Hi " + user_first_name + ", welcome to Beauty Box! 👋";// var conversation_state=global.get("convo_state")// node.warn()if (global.get("convo_state")===0){    msg.ConversationSequence = 1;    msg.FacebookReplyType = "initialization";    msg.payload =" Hi " + user_first_name + ", Welcome to Beauty Box! 👋 ";    msg.payload += "\n\nBefore we start, we want to let you know that this is a chatbot that can help direct your inquiry with a few simple questions...";    msg.payload += "\n\nAs a reminder, please do not share any sensitive information (credit card, password, etc). We will only ask for your phone number to look up your Account details if necessary. By chatting with us, you agree to the attached privacy policy.";    msg.payload+="\n\n\nPlease note that we use our loyalty program based on Blockchain to assign you tokens for every purchase. Balance is displayed at the end of your purchase 💰";    msg.payload+="\n\n\nIf you want to know more about BlockChain and how it works, please check this out- https://en.wikipedia.org/wiki/Blockchain"    quick_reply = {        type : "options",        options : [{            label: "Sounds good",            metadata: "FlowCommand_GUEST_LEGALACCEPT"        },        {            label: "Privacy policy",            metadata: "FlowCommand_SHOWURL_ULTACOMPRIVACYPOLICY"        }]    }    msg.quick_reply = quick_reply;}if (global.get("convo_state")===1){    msg.ConversationSequence = 1;    msg.FacebookReplyType = "givehelpinghand";    msg.payload =" Great, " + user_first_name + " .How can I help you today";    msg.payload += "\n\nFeel free to pick from options below and I will take care of it from there, for you!";    quick_reply = {        type : "options",        options : [{            label: "Product Carousel(Manual)",            metadata: "ViewProducts_Manually"        },        {            label: "Product Carousel(Drop Down)",            metadata: "ViewProducts"        },        {            label: "Missing Transaction",            metadata: "AddPoints"        }]    }    msg.quick_reply = quick_reply;}if (global.get("convo_state")===2){    msg.ConversationSequence = 1;    msg.FacebookReplyType = "show_privacy_policy";    msg.payload ="Here you go... http://interplay.iterate.ai🙌";    msg.payload += "\n\nHow can I help you today?";    msg.payload += "\n\nFeel free to pick from options below and I will take care of it from there, for you!";    quick_reply = {        type : "options",        options : [{            label: "Product Carousel",            metadata: "ViewProducts"        },        {            label: "Missing Transaction",            metadata: "AddPoints"        }]    }    msg.quick_reply = quick_reply;}if (global.get("convo_state")==='MT'){    node.warn("In MT condition")    msg.ConversationSequence = 2;    msg.FacebookReplyType = "initial_missing_transaction";    msg.payload =user_first_name + " ,Sorry to hear that😔";    msg.payload += "\n\nLet me take care of this issue.Can I have a phone number registered with this account?";    msg.payload += "\n\n No need to use dashes.";}if (global.get("convo_state")==='MT_phoneno'){    node.warn("In DOB condition")    msg.ConversationSequence = 2;    msg.FacebookReplyType = "dob_missing_transaction";    msg.payload =user_first_name + ", Thanks for that 👍";    msg.payload += "\n\nCan I also get you D.O.B in MM/DD format like 03/04?";}if (global.get("convo_state")==='MT_dob'){    node.warn("DOB recieved")    msg.ConversationSequence = 2;    msg.FacebookReplyType = "purchase_missing_transaction";    msg.payload ="That was super helpful, "+user_first_name;    msg.payload="\n\nWe were able to verify you and your Beauty Box account balance is 1115 points"     msg.payload += "\n\nWhere did you do this purchase?";    quick_reply = {        type : "options",        options : [{            label: "In Store",            metadata: "Physical"        },        {            label: "On the Website",            metadata: "Electronic"        }]    }    msg.quick_reply = quick_reply;}if (global.get("convo_state")==='MT_ocr'){    node.warn("PHOTO NEEDED")    msg.ConversationSequence = 2;    msg.FacebookReplyType = "ocr_missing_transaction";    msg.payload ="Well, lets fix this 😎";    msg.payload += "\n\nIn order to proceed further, can you please upload the reciept copy?";}if (global.get("convo_state")==='OCR_photo'){    node.warn("PHOTO recieved")    msg.ConversationSequence = 3;    // msg.FacebookReplyType = "ocr_missing_transaction";    // msg.payload ="Well, lets fix this 😎";    // msg.payload += "\n\nIn order to proceed further, can you please upload the reciept copy?";}if (global.get("convo_state")==='MT_end'){    node.warn("WE GOT A RATING")    msg.ConversationSequence = 4;    msg.payload ="Thanks for using Beauty Box 🙏";    msg.payload += "\n\nHope to see you soon 👆";    // msg.payload += "\n\nOn your way out,say hi to our new FAQ's, made just for you!";}if (global.get("convo_state")==='show_product_categories'){    node.warn("show product categories")    msg.ConversationSequence = 5;    msg.FacebookReplyType = "initial_prod_cat_show";    msg.payload ="What exactly are you looking for? ";    msg.payload += "\n\nFeel free to pick from the following categories";}if (global.get("convo_state")==='show_shirts_from_product_carousel'){    node.warn("Showing all available shirts")    msg.ConversationSequence = 6;    msg.FacebookReplyType = "show_all_shirts";    msg.payload ="Okay, here are all the shirts we have for you!👕 ";}if (global.get("convo_state")==='show_lipsticks_from_product_carousel'){    node.warn("Showing all available lipsticks")    msg.ConversationSequence = 6;    msg.FacebookReplyType = "show_all_lipsticks";    msg.payload ="Okay, here is our lipstick collection 💄� ";}if (global.get("convo_state")==='shirt_purchase_complete'){    node.warn("User wants to pay and finish the process")    msg.ConversationSequence = 7;    msg.FacebookReplyType = "checkout_based_on_options";    quick_reply = {        type : "options",        options : [{            label: "Loyalty Points",            metadata: "points"        },        {            label: "Use Credit/Debit card",            metadata: "card"        }]    }    msg.quick_reply = quick_reply;}if (global.get("convo_state")==='lipstick_purchase_complete'){    node.warn("User wants to pay and finish the process")    msg.ConversationSequence = 7;    msg.FacebookReplyType = "checkout_based_on_options";   quick_reply = {        type : "options",        options : [{            label: "Loyalty Points",            metadata: "points"        },        {            label: "Use Credit/Debit card",            metadata: "card"        }]    }    msg.quick_reply = quick_reply;}if (global.get("convo_state")==='using_points'){    node.warn("Use points and conclude transaction")    msg.ConversationSequence = 8;    msg.FacebookReplyType = "finish_transaction_for_shirts_using_points";}if (global.get("convo_state")==='using_card'){    node.warn("Use card and conclude transaction")    msg.ConversationSequence = 8;    msg.FacebookReplyType = "finish_transaction_for_shirts_using_card";}if (global.get("convo_state")==='user_picked_manual_query'){    node.warn("Take input and pass it to RASA")    msg.ConversationSequence = 9;   msg.payload ="How can I help you today, "+user_first_name+" ?";     msg.payload+="\n\nYou can type 'eyeshadow' or 'lipstick to start."    msg.payload+="\n\nPlease remember, I am still a bot, so try to keep it simple 😛"    msg.FacebookReplyType = "input_for_rasa_initial";}if (global.get("convo_state")==='user_input_recieved'){    node.warn("pass msg.payload.content to rasa")    msg.ConversationSequence = 10;    msg.payload =msg.payload.content;    msg.FacebookReplyType = "input_for_rasa_from_user";}if (global.get("convo_state")==='user_needs_a_wallet'){    node.warn("setup a new wallet for user")    msg.ConversationSequence = 12;    msg.FacebookReplyType = "new_wallet_needed";}if (global.get("convo_state")==='user_has_a_wallet'){    node.warn("use existing wallet")    msg.ConversationSequence = 11;    msg.FacebookReplyType = "use_old_wallet";}if (global.get("convo_state")==='user_exit_wallet'){    node.warn("pay using card[NO WALLET NEEDED]")    msg.ConversationSequence = 11;    msg.FacebookReplyType = "card_payment";}if (global.get("convo_state")==='user_account_ID_verification'){    node.warn("ID Verified, ask for permission")    msg.ConversationSequence = 13;    msg.FacebookReplyType = "id_verified_ask_permission";}if (global.get("convo_state")==='user_is_converting_points'){    node.warn("time to convert the points now")     msg.ConversationSequence = 11;     msg.FacebookReplyType = "id_verified_acceptance_recieved";}if (global.get("convo_state")==='user_said_no'){    node.warn("User said NO, redirect to wallet section")    msg.ConversationSequence = 8;    msg.FacebookReplyType = "redirecting_from_user_acceptance";}// node.warn(msg.ConversationInitStage);return msg;


Function code for :  Setting input state to Initial input recieved:var require = context.global.get('require'); global.set('input_state','Initial input recieved');return msg;


Function code for :  setting FacebookReplyType:

var require = context.global.get('require'); if (msg.payload==='user_picked_lipstick'){    msg.FacebookReplyType = "show_lipstick_manual_query";}else{    msg.FacebookReplyType = "show_shirts_manual_query";}return msg;



Was this article helpful?