Block just user message

hi , I want to block user messages until the action ends its calculation and then I unblock Do you have a solution please ? :thinking:

hi @wassimgt, would you mind clarifying what exactly you’re trying to do? Is it disabling user input until an action has finished running? What input channel are you using?

i am using fb messenger. I have an action which takes a little time in the response because in this action I made a prediction on the stock market. I want to block the user message in this moment until the action ends @ricwo

I don’t think there’s a way to prevent the user from giving text input in fb messenger while you wait for the action to complete. What you could do though is utter a message that tells the user that the prediction will take a moment. would that work in your case?

I have already done this, but my problem starts after this message. if the user asks another question and the prediction action is in progress, here the fb messanger will send a post every 20 s until it receives a response. look this

logically after rasa will send the response several times @ricwo

I’m afraid there’s no way to block new incoming user messages. Have you tried defining your custom action so that it sends a message every few seconds indicating that the prediction is still in progress?

the same problem, this actions will enter a queue, the execution of this actions is done when the previous action (prediction action) ends @ricwo

One way do that on facebook MAYBE you could use the handover protocol.

When your bot is answering on facebook it is because it is listed as the primary receiver, so, in the beginning of your python action you could write a code that would activate the handover protocol and set your bot as secondary receiver instead, that way any message sent with go to inbox and not to your bot.

Once the execution is completed you just activate the handover protocol again

have you an example? @jusce17

Basically you just have to create 2 pythons functions, stop_assistant() and resume_assistant()

The stop_assistant() will look something like this:

def stop_assistant(self):
    url = 'https://graph.facebook.com/v6.0/me/pass_thread_control?access_token={}'.format(YOUR-TOKEN-HERE)

    headers ={
        "Content-Type": "application/json"
    }
    data = {
        "recipient":{"id":facebook_sender_id}, # facebook id of the user
        "target_app_id":facebook_inbox_id, # id of your inbox id
        "metadata":"passing to inbox"
    }

    try:
        r = requests.post(url, headers=headers, data =json.dumps(data))
        return(r.status_code)        
    except requests.exceptions.RequestException as error:
        return(error)

All the messages will be send to the inbox instead of your Facebook App, any thing your user says the assistant won’t be able to see nor record it.

The resume_assistant() will look something like this:

def resume_assistant(self):
        
        url = 'https://graph.facebook.com/v6.0/me/take_thread_control?access_token={}'.format(YOUR-TOKEN)

        headers ={
            "Content-Type": "application/json"
        }
        data = {
            "recipient":{"id":facebook_sender_id}, # facebook id of the user
            "metadata":"assistant Taking over"
        }

        try:
            r = requests.post(url, headers=headers, data =json.dumps(data))
            return(r.status_code)
        except requests.exceptions.RequestException as error:
            return(error)

Your Facebook App will take control of that thread again and all the message will start going to your bot again.

Summary
class ActionStocks(Action):
    
    def name(self) -> Text:
        return "action_stocks"

    def stop_assistant(self):
        url = 'https://graph.facebook.com/v6.0/me/pass_thread_control?access_token={}'.format(YOUR-TOKEN)

        headers ={
            "Content-Type": "application/json"
        }
        data = {
            "recipient":{"id":facebook_sender_id}, # facebook id of the user
            "target_app_id":facebook_inbox_id, # id of your inbox id
            "metadata":"passing to inbox"
        }

        try:
            r = requests.post(url, headers=headers, data =json.dumps(data))
            return(r.status_code)        
        except requests.exceptions.RequestException as error:
            return(error)

    def resume_assistant(self):
        
        url = 'https://graph.facebook.com/v6.0/me/take_thread_control?access_token={}'.format(YOUR-TOKEN)

        headers ={
            "Content-Type": "application/json"
        }
        data = {
            "recipient":{"id":facebook_sender_id}, # facebook id of the user
            "metadata":"assistant Taking over"
        }

        try:
            r = requests.post(url, headers=headers, data =json.dumps(data))
            return(r.status_code)
        except requests.exceptions.RequestException as error:
            return(error)


    def run(self, dispatcher, tracker, domain):

        self.stop_assistant()
        # get your stocks here
        self.resume_assistant()

        dispatcher.utter_message('The stocks are')

        return []

The main problem is that your bot will be unavailable for that user till your function is done running. :frowning_face: