Change user uttered event on custom action

Is it possible to change the latest user utterance using a custom action?

I am trying to map a user message with a number to a button, so Rasa evaluates the intent the same as if the button was clicked, I want to revert the number utterance and add the corresponding utterance for the button.

Ex.:

User: Hello
Bot: Hi. I am the Acme Bot. I can help you with:
        1. Appointments
        2. Order status
        3. Contact a support agent
User: 1
Bot: Let's make an appointment...

Those numbered options are actually buttons, that are being displayed like that since the channel does not support buttons. Here is my custom action, but the issue is, whenever I answer with a number one, even though the Tracker gets the correct intent from the number mapping, the Keras policy predicts the next action as “action_listen”

class ActionCheckOptions(Action):
def name(self):
    return "action_check_options"

def run(
    self,
    dispatcher: CollectingDispatcher,
    tracker: Tracker,
    domain: Dict[Text, Any],
):
    # Get selected option from entities
    option = next(tracker.get_latest_entity_values("option"), None)

    if option:
        # Get latest bot event
        bot_event = next(e for e in reversed(tracker.events) if e["event"] == "bot")

        # Check for buttons in latest bot event
        if "buttons" in bot_event["data"] and bot_event["data"]["buttons"]:
            buttons = bot_event["data"]["buttons"]
            option = int(option) - 1

            # Check selected option is within options range
            if option < len(buttons):
                intent = buttons[option]["payload"][1:]
                parse_data = {
                    "text": f"/{intent}",
                    "intent": {"name": intent, "confidence": 1.0},
                    "intent_ranking": [{"name": intent, "confidence": 1.0}],
                    "entities": [],
                }
                return [
                    UserUtteranceReverted(),
                    UserUttered(f"/{intent}", parse_data=parse_data),
                ]
            else:
                dispatcher.utter_template(template="utter_invalid_option")

    return [FollowupAction("action_listen")]

It sounds like you might be looking for a form here. There’s a tutorial on our blog that you may like here.

If you insist on using a custom action here, the issue may indeed be the keras policy. We’ve upgraded this system a while ago and may recommend the TED policy instead. There’s a video on the algorithm whiteboard that highlights the merits of this new approach to policies.