Modifying user input and sending it to backend

Hi Team,

I am calling a custom API in the before_incoming_minddleware hook and I want to send the modified user input to the backend. Similarly, I want to modify the output before it is received by the user. Please help in this regard.

Thanks in advance.

Hi @ruchi thanks for posting on the forum.

To do so you need to override the event variable.
In the botpress code editor you can use event. and check all the suggestions.
I guess you want to use event.payload.text to modify the user input.

You can use the before_incoming_middleware hook to modify before botpress analyse the event and the before_outgoing_middleware to modify it before sending the reply to the user.

I also replied to your other post (which I guess is related)

Happy building :robot:

Thanks @PierreSnell , I did try replacing event.preview and event.payload.text variables, however, it didn’t work as expected. I believe I shouldn’t use async call to my custom API in the before_incoming_middleware hook.
I am sharing the snippet of my code below. Please have a look at and guide me through this.


const translate_to_english = async() => {

var input_text = event.payload.text

var data = JSON.stringify({ "text": input_text, "language": "en" })

var headers = {

    'Content-Type': 'application/json',

    'Access-Control-Allow-Origin': true

}

bp.logger.info("inside translate hook")

//config object to call the translation API
var config = {

    method: 'post',

    url: 'http:URL/language_call_url',

    headers: headers,

    mode: 'cors',

    data: data

};

// axios call to the API
var resp = await axios(config)

try {

    bp.logger.info("in success")

    bp.logger.info(JSON.stringify(resp.data))

    const botId = event.botId

    const userId = event.target

    bp.logger.info("Resp " + resp.data)

// replacing event.preview with the response of the above API
event.preview = resp.data

} catch (error) {

    bp.logger.info("in error")

    bp.logger.error(error);

}

}

bp.logger.info("Channel : " + event.channel)

if (event.preview != “Reset the conversation” && event.channel != ‘api’) {

translate_to_english()

bp.logger.info("Preview : " + event.preview)

}

Hi Rucchi,

I formatted and modified a bit your hook code bellow,

In the hook you should return the fonction at the end (and botpress can deal with async functions)

Can you try this and tell me what exactly is not working ?

Happy building :robot:

function hook(bp: typeof sdk, event: sdk.IO.IncomingEvent) {
    /** Your code starts below */

    const translate_to_english = async() => {
        const input_text = event.payload.text

        const apiData = JSON.stringify({ "text": input_text, "language": "en" })

        const headers = { 'Content-Type': 'application/json',
                          'Access-Control-Allow-Origin': true }
        
        bp.logger.info("inside translate hook")

        //config object to call the translation API
        var config = {method: 'post',
                      url: 'http:URL/language_call_url',
                      headers: headers,
                      mode: 'cors', 
                      data: apiData};

        // axios call to the API
        const data = await axios(config)

        try {
            bp.logger.info("in success")
            bp.logger.info(JSON.stringify(data))
            const botId = event.botId
            const userId = event.target
            bp.logger.info("Resp " + data)

            // replacing event.preview with the response of the above API
            event.preview = data
        } 
        catch (error) {
            bp.logger.info("in error")
            bp.logger.error(error);
        }
    }

  bp.logger.info("Channel : " + event.channel)
  bp.logger.info("Preview : " + event.preview)
 
  return translate_to_english() // return a promise on the code you want to execute
                                // so botpress will wait for it automatically
}

Thanks for the modifications @PierreSnell ,

I have modified my code a bit. Below is the snippet of it.

async function translate_to_english(set_preview) {

var input_text = event.payload.text

var apiData = JSON.stringify({ "text": input_text, "language": "en" })

const headers = {

    'Content-Type': 'application/json',

    'Access-Control-Allow-Origin': true

}

bp.logger.info("inside translate API function")

//config object to call the translation API

var config = {

    method: 'post',

    url: 'http://URL/language_call_url',

    headers: headers,

    mode: 'cors',

    data: apiData

};

// axios call to the API

await axios(config)

    .then((res) => {

        bp.logger.info("in success")

        bp.logger.info("Resp " + res.data)

        set_preview(res.data)

        return res.data

    })

    .catch((error) => {

        bp.logger.info("In error " + error)

        return ""

    })

}

async function sendDataToBackend() {

bp.logger.info("calling translate function")

await translate_to_english(function(input) {

        event.preview = input

        bp.logger.info("Preview line 58 : " + event.preview)

    })

    // return result

}

if (event.preview != “Reset the conversation” && event.channel != “api”) {

sendDataToBackend()

}

The problem here is that , contents of event.preview change at the same time when I get a response from the native NLU engine. Can we make the backend processing to wait until the api call finishes its execution?

Hi @ruchi,

The before_incomming_middleware hook is executed before the nlu engine processing.
The before_outgoing_middleware is executed after the nlu engine and just before sending back the message to the user.

So on the before_incomming_hook, your data can’t be modified by the engine.

Because the snippet I gave you use an async fonction, botpress will wait until the completion of the hook before continuing so everything should work fine.

You should use twice this code, once in a before incoming hook to translate for the engine and again after the engine in a before outgoing hook.

event -> before_incomming -> modified event -> nlu processing -> analyzed event -> before outgoing -> modified analyzed event -> send to user
You have control on the bold part of the pipeline.