Search code examples
botschatbotfacebook-chatbot

What is the right way to save/track state inside a Facebook Messenger bot?


If my bot asks different questions and if the user answers each of them, how do I find out which answer relates to which question. There is a field called metadata that you can attach to the sendTextMessage API but when the user responds, this metadata comes in as undefined. Do you guys use any node-cache for tracking state or an FSM such as machina.js? How can I best figure out at what of the conversation we are currently stuck in?


Solution

  • When your app receives a message, there's no payload or metadata associated with it. This is as opposed to a quick-reply or post-back which can have a payload. The only way to associate a response with a question this is to manually track the conversation state in your app as suggested by @anshuman-dhamoon

    To do this, it's best to maintain a state for each user, as well as the next state for each state.

    // optionally store this in a database
    const users = {}
    
    // an object of state constants
    const states = {
        question1: 'question1',
        question2: 'question2',
        closing: 'closing',
    }
    
    // mapping of each to state to the message associated with each state
    const messages = {
        [states.question1]: 'How are you today?',
        [states.question2]: 'Where are you from?',
        [states.closing]: 'That\'s cool. It\'s nice to meet you!',
    }
    
    // mapping of each state to the next state
    const nextStates = {
        [states.question1]: states.question2,
        [states.question2]: states.closing,
    }
    
    const receivedMessage = (event) => {
        // keep track of each user by their senderId
        const senderId = event.sender.id
        if (!users[senderId].currentState){
            // set the initial state
            users[senderId].currentState = states.question1
        } else {
            // store the answer and update the state
            users[senderId][users[senderId].currentState] = event.message.text
            users[senderId].currentState = nextStates[users[senderId.currentState]]
        }
        // send a message to the user via the Messenger API
        sendTextMessage(senderId, messages[users[senderId].currentState])
    }
    

    Note If you wanted, you can even make the values of nextStates into callable functions that take the answer of the current state and branch off into different conversation flows by passing the user to a different state depending on his/her response.