Delay in dispatcher.utter_message()

Hi, I’m trying to introduce a small delay between messages that are sent using the dispatcher.utter_message() using time module. But what I see is that dispatcher sends them out in batches. Example:

I have a bunch of replies to be made one after the other in an array. So I’m doing:

for reply in replies:
       time.sleep(2)
       dispatcher.utter_message(text=reply)

But dispatcher ends up waiting for 2*len(replies) time, and post this it sends all the dispatcher messages together. How can I introduce a small delay between messages? @ChrisRahme any idea?

Hum… in the past i made a solution but i chosen frontend way

I put delay while javascript inserting news mensagens in chat

I have some ideas but i need to test first :joy: :joy:

I will back with my results

1 Like

sure, thanks @itsjhonny :smile:

Hi! I’m still trying :joy:

Its little hard because we need to process asynchronously and use an external event to respond to the user. Customs Actions can’t wait more than (i guess 20 seconds) to return. Else, action return TimeOut error :cry:

Maybe reminders can be an way but i’m not sure this is a good way to use in this case

I will try first somethings using threading.Timer but i believe the best way is build delay in frontend or using Custom Connectors

I will try more :smiley:

@edit -----

thread don’t work :frowning:

threading.Timer
1 Like

Thanks @itsjhonny, gonna check if asyncio in python is gonna help me.

I have no success here :cry: I think the best way is do it in frontend

Maybe @nik202 or Chris knows some other ways

@lis what is your front end, it depends on the front end not related to rasa.

You can’t use sleep() inside a same action.

dispatcher.utter_message() adds an event under the hood, like the ones you put inside the return [] of custom actions. And events are ran after the action.

What you can do is make two actions, action_a and action_b. action_a prints the first message and at the end, you return [FollowupAction("action_b"]). In action_b, you introduce the delay and print a second message.

I am not sure this will work though! I never tried it. If it doesn’t work, I would use Reminders as @itsjhonny suggested. But try this way first since it’s easier.

1 Like

I tried this solution. Its working for two message if has more, its show TimeoutError and Circuit breaker tripped

my action.py

from typing import Any, Text, Dict, List

from rasa_sdk import Action, Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.events import FollowupAction,BotUttered,UserUtteranceReverted,ReminderScheduled,ActionExecuted

import time

class ActionDelayMsg1(Action):
    current_msg_number = 0
    def name(self) -> Text:
        return "action_delay_msg1"

    async def run(
      self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]
    ) -> List[Dict[Text, Any]]:
        msgs = ["teste1","teste2","teste3"]
        if(self.current_msg_number > 5):
            self.current_msg_number = 0
            return []

        self.current_msg_number +=1
        return [FollowupAction('action_delay_msg2')]



class ActionDelayMsg2(Action):
    def name(self) -> Text:
        return "action_delay_msg2"

    async def run(
      self, dispatcher, tracker: Tracker, domain: Dict[Text, Any]
    ) -> List[Dict[Text, Any]]:

        time.sleep(3)
        dispatcher.utter_message("teste")
        return [FollowupAction('action_delay_msg1')]

Console output

Your input ->  hi                                                                                     
teste
teste
2022-04-19 17:59:25 ERROR    asyncio  - Task exception was never retrieved
future: <Task finished name='Task-3' coro=<configure_app.<locals>.run_cmdline_io() done, defined at /Users/johnguimaraes/miniforge3/envs/rasa3/lib/python3.8/site-packages/rasa/core/run.py:130> exception=TimeoutError()>
Traceback (most recent call last):
  File "/Users/johnguimaraes/miniforge3/envs/rasa3/lib/python3.8/site-packages/rasa/core/run.py", line 134, in run_cmdline_io
    await console.record_messages(
  File "/Users/johnguimaraes/miniforge3/envs/rasa3/lib/python3.8/site-packages/rasa/core/channels/console.py", line 185, in record_messages
    async for response in bot_responses:
  File "/Users/johnguimaraes/miniforge3/envs/rasa3/lib/python3.8/site-packages/rasa/core/channels/console.py", line 140, in _send_message_receive_stream
    async for line in resp.content:
  File "/Users/johnguimaraes/miniforge3/envs/rasa3/lib/python3.8/site-packages/aiohttp/streams.py", line 35, in __anext__
    rv = await self.read_func()
  File "/Users/johnguimaraes/miniforge3/envs/rasa3/lib/python3.8/site-packages/aiohttp/streams.py", line 311, in readline
    return await self.readuntil()
  File "/Users/johnguimaraes/miniforge3/envs/rasa3/lib/python3.8/site-packages/aiohttp/streams.py", line 343, in readuntil
    await self._wait("readuntil")
  File "/Users/johnguimaraes/miniforge3/envs/rasa3/lib/python3.8/site-packages/aiohttp/streams.py", line 304, in _wait
    await waiter
  File "/Users/johnguimaraes/miniforge3/envs/rasa3/lib/python3.8/site-packages/aiohttp/helpers.py", line 721, in __exit__
    raise asyncio.TimeoutError from None
asyncio.exceptions.TimeoutError
2022-04-19 17:59:27 WARNING  rasa.core.processor  - Circuit breaker tripped. Stopped predicting more actions for sender 'bae92dd506394cc2a6209257ea47b3a9'.
2 Likes

Interesting, thanks for testing it out :slight_smile:

Just for documentation purposes, can you edit your post and add the full error?

1 Like

Sure! :blush:

I will test reminders. This is will be interesting to use for facebook, telegram, whatsapp and other platform But just in this case. If has own frontend, is think better build the solution in frontend

I didn’t have success with custom connector too :frowning:

2 Likes

Yep, @itsjhonny I’m using slack as my connector. Which is why I’m struggling. If I had another frontend, I would definitely tried it there :frowning: Like you said, I couldn’t do it with connector also.

Hi Lis :smiley:

So… reminder work very well for it The logic is very similar with my last post contenting actiion.py file

Reminders don’t work with Rest but, i think it will work for slack

channels available

output_channel	
string
Enum: "latest" "slack" "callback" "facebook" "rocketchat" "telegram" "twilio" "webexteams" "socketio"

I will build the solution using botfront widget Socket.io and share the project in this thread :smiley:

Reference: Rasa Reminders are not working in custom UI - #2 by Tobias_Wochinger

inject an intent into a conversation

1 Like

Thanks @itsjhonny