Custom Utterances

Lets say, I have a list of responses that I want the bot to respond with and I want it to pick one randomly. However, there is something that I want to tell the user before the random response. For example:

  1. I’ve added a cheeseburger to your order, will that be all?
  2. I’ve added a cheeseburger to your order, anything else?
  3. I’ve added a cheeseburger to your order, is there anything else you would like to add to your order today? etc.

I generate “I’ve added a cheeseburger to your order” in a custom action, how can I utter this and a random response in 1 utterance. The reason why it needs to be 1 utterance is because it has to interface with a tts/asr audio system, so I do not want multiple utterances by a machine at once.

@dragon18456

In domain.yml

responses:
utter_random_response:
-text: will that be all?
-text: anything else?
-text: is there anything else you would like to add to your order today? etc.

In will pick random response every time.

In acttion.py

dispatcher.utter_message(text="I’ve added a cheeseburger to your order;", "template=" utter_random_response")

Text is the fixed response and utter_random_response will change every time.

You need to create the story or rule as per your scenario.

Good Luck and your post make me hungry :slight_smile:

No, the part about “I’ve added cheeseburger to your order” is part of the generated stuff, I wanted the “will that be all?”, “anything else?” and “is there anything else etc.” to be in utter_random_response. So I can add that field “text” = “I’ve added a cheeseburger to your order” to the utter_message and it just works?

@dragon18456 replace it and try. concept is same. what ever you want to add in random it will show random pick and text one will be fixed.

Wait, but this causes 2 separate responses from the bot. I need these 2 to be 1 utterance instead of 2.

@dragon18456 I have update that’s what you want right? Its a voice does it matter? @dragon18456 Try, if not work then will provide you other possible solution.

No, I need the bot to just respond with:

“I’ve added a cheeseburger to your order, will that be all”

Not

“I’ve added a cheeseburger to your order”

Newline

“Will that be all”

My system will be asr/audio based, so I can’t have 2 separate responses

If you want to do it in the domain:

responses:
  utter_cheeseburger :
  - text: I’ve added a cheeseburger to your order, will that be all?
  - text: I’ve added a cheeseburger to your order, anything else?
  - text: I’ve added a cheeseburger to your order, is there anything else you would like to add to your order today?

Or, if you want to do it in an action:

import random

class ActionCheeseburger(Action):
    def name(self):
        return 'action_cheeseburger'
    
    def run(self, dispatcher, tracker, domain):
        base      = "I’ve added a cheeseburger to your order, "
        questions = ["will that be all?", "anything else?", "is there anything else you would like to add to your order today?"]
        full_text = base + random.choice(questions)

        dispatcher.utter_message(text = full_text)
        return []
2 Likes

@ChrisRahme Nice! can we do this with button also or if we need to select multiple buttons?

1 Like

Thanks, I thought that this was how to do it, but it is a bit disappointing that Rasa doesn’t have this built in. I would have thought there would have been a way for Rasa to do this automatically, so that my random responses can be in the domain.yml rather than a python list

1 Like

Yes you can!

I used variable buttons in my multilingual chatbot to output the buttons according to the language :slight_smile:

@ChrisRahme can you shared the snippet or some thread for the reference.

But you can do it in the domain as I’ve shown in the first example. You’ll have to repeat the same part though of course, but it’s all doable in the domain.

Sure @nik202! Here’s an example:

class ActionUtterServiceTypes(Action):
    def name(self):
        return 'action_utter_service_types'
    
    def run(self, dispatcher, tracker, domain):
        announce(self, tracker)
        text = get_text_from_lang(
            tracker,
            [['How can I help you today?', 'So I can get you to the right place, tell me what service you’d like help with.', 'How can I help?'],
            ['Comment puis-je vous aider?', 'Pour que je puisse vous guider, dites-moi pour quel service vous aimeriez obtenir de l’aide.', 'Comment puis-je aider?'],
            ['حتى أتمكن من إيصالك إلى المكان الصحيح ، أخبرني بالخدمة التي ترغب في المساعدة فيها.', 'كيف يمكنني أن أقدم المساعدة؟'],
            ['Այսպիսով, ես կարող եմ ձեզ ճիշտ տեղ հասցնել, ասեք ինձ, թե որ ծառայության հետ կցանկանայիք օգնել', 'Ինչպե՞ս կարող եմ օգնել:']]
        )
        
        buttons  = get_buttons_from_lang(
            tracker,
            [['Wireless', 'Internet', 'DSL Internet', 'CableVision TV'],
            ['Sans Fil', 'Internet', 'Internet DSL', 'CableVision TV'],
            ['لاسلكي','إنترنت','DSL إنترنت','تلفزيون الكابل'],
            ['Անլար', 'Ինտերնետ', 'DSL ինտերնետ', 'CableVision TV']],
            [
                '/inform_service_type{"service_type": "wireless"}',
                '/inform_service_type{"service_type": "internet"}',
                '/inform_service_type{"service_type": "dsl"}',
                '/inform_service_type{"service_type": "cablevision"}'
            ])
        
        print('\nBOT:', text, buttons)
        dispatcher.utter_message(text = text, buttons = buttons)
        return []

Basically the get_text_from_lang and get_buttons_from_lang functions access the language slot and return the text or button depending on its value.

get_text_from_lang takes in a list of lists, each list represents a language, and each element inside it will be chosen randomly, like when writing multiple values for a response in the domain.

get_buttons_from_lang takes in a list of lists and a second list. The first list of lists are the button titles in the different languages, and the second list is a list of payloads. Meaning, in the example above, ‘Wireless’ and ‘Sans Fil’ buttons both have the payload /inform_service_type{"service_type": "wireless"}. ‘Wireless’ will appear if the bot is speaking English, and ‘Sans Fil’ will appear if it speaks French.

And this is the whole chatbot if you’d like to see more of the code: ChrisRahme/fyp-chatbot.

1 Like

@ChrisRahme Surely, I will try and recommend this to others on the forum if somebody required this idea.Many thanks. Regards Nik.

1 Like