Chatbot message only appears after custom action has finished running

Dear Community,

my bot runs a custom action that takes around 20 seconds as it includes pulling data from a public API.

Therefore, I want to send a message informing the user about this delay.

I defined the following rule in the rules.yml:

- rule: Say the action takes a while whenever user requests new tracks
  steps:
  - intent: request_new_tracks
  - action: utter_takesawhile
  - action: custom_action_get_new_tracks

The utter_takesawhile is defined as followed in the domain.yml:

responses:
  utter_takesawhile:
  - text: Please wait, this action takes a while as it needs to pull data from the Spotify API.

The custom action looks as follows in the actions.py:

class GetNewTracks(Action):

    def name(self) -> Text:

        return "custom_action_get_new_tracks"

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

        # Establish connection to Spotify API through Spotipy
        sp = connect_to_api()

        # Read artists CSV
        artists = read_artists_csv()

        # # Get all new tracks from artists in CSV file
        days = 10
        tracklist = get_new_tracks_from_artists(sp, artists["artist_uri"], days=days)
        dispatcher.utter_message(text="Tracks from selected artists in the last " + str(days) + " days:")

        for track_name in tracklist['track_name']:
            dispatcher.utter_message(text=track_name)

        return []

Expected behavior: Bot sends message, then performs the action (which also has a dispatcher.utter_message)

Observed behavior: Message “takesawhile” is only visible to the user after the custom action has finished.

I already tried to remove the “async” but the behavior remains the same. I also tried to define a new custom action that utters the message, still the same behavior is observed.

Is there a way to force the bot to send the utter to the user before the custom action starts running?

Thanks a lot.

Yes, you would spin the longer running function off in a separate thread and return immediately with the takes a while message.

When the thread completes, it would use an external event to send the response.

Greg

Hi Greg,

thanks for the hint. I am not familiar with threads.

Are you talking about general threads in python or specifically this part of the Rasa documentation?

Best