How to create a Date slot such that it should be greater than current date

I am creating a Medical Chatbot which should ask user for date of appointment and it should be greater than today’s date.

You can use Duckling to extract the date.

Then you can create a Custom Action that sets the Slot only if the extracted date is greater than today’s.

@ChrisRahme thanks for your reply. Could you please help me with how could I write custom action for this condition?

@deepali0162 You can check this blog post for ducking : Using Duckling to Extract Dates and Times in Your Rasa Chatbot | by Adam Bowker | Medium OR see this youtube link : Using Duckling for Entity Extraction with Rasa | Rasa Tutorial - YouTube

Good Luck!

Hey @nik202 thanks for your reply however, I need to validate here if the date entered by user is greater than today or not. I have written below action to do so however, it is not doing anything :frowning: entities:

  • date

slots: date: type: text

forms: appointment_form: ignored_intents: - chitchat required_slots: date: - entity: date type: from_entity

class ValidateAppointmentForm(Action): def name(self) → Text: return “action_validate_form”

def validate_date(
    self,
    value: Text,
    dispatcher: CollectingDispatcher,
    tracker: Tracker,
    domain: Dict[Text, Any],
) -> Dict[Text, Any]:
    now = dt.datetime.now()
    if timeslot < now:
        message='Date of appointment cannot be less than today.'
    else:
        timeslot = tracker.get_slot("timeslot")

    return []

@deepali0162 can you format the code so, that we can see properly? and even share config.yml file for the same.

@nik202 I am attaching files and screenshots for your reference. config.yml (678 Bytes)

@deepali0162 Did you seen the suggested videos which I shared to you?

@nik202 yup but they don’t suggest how can I validate date? -_-

@deepali0162 Did you able to get any response I mean date or time with above mention code? you mentioned timeslot as get_slot but where you mentioned in domain under slots? or did I am missing anything?

Tip: Try archived small code first and slowly slowly add the extra bytes of code in previous code.

@nik202 Thanks for pointing out the problem. I have made changes accordingly however, now I am getting below warning message.

actions.py (2.6 KB) config.yml (678 Bytes)

Could someone please suggest on this? I am able to input date but it is not validating for the condition (entered date greater than today). It is still accepting older dates.

from datetime import datetime

from database_connectivity import DataUpdate

import datetime as dt

date_object = dt.strptime(date, "%Y-%m-%d")

class ValidateAppointmentForm(Action):
    def name(self) -> Text:
        return "action_validate_form"

    def validate_date(
        self,
        value: Text,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: Dict[Text, Any],
    ) -> Dict[Text, Any]:
        now = dt.datetime.now()
        if date < now:
            message="Date of appointment cannot be less than today."
        else:
            date = tracker.get_slot("date")

        return []

Can’t figure out what is wrong.

Try (also read my comments to learn):

from datetime import datetime

class ValidateAppointmentForm(FormValidationAction): # FormValidationAction instead of Action
    def name(self):
        return "action_validate_form"

    def validate_date(self, value, dispatcher, tracker, domain):
        now = datetime.datetime.now()

        if value < now: # `value` instead of `date`
            message = "Date of appointment cannot be less than today."
            dispatcher.utter_message(message) # You forgot to display the message
            value = None # Set date/value to None to show it has not been filled
        # No need for an else, since the slot is stored in `value`

        return {"date": value}

Not 100% sure it works, maybe there are some syntax errors.

1 Like

@ChrisRahme thank you!!

1 Like

Hi @ChrisRahme ,

I have replaced my function with yours, ,thank you!! However, the bot is still able to except older date. As per the debugger, it is not even validating the date entered.

Could you please advise?

As per the yellow warnings, please discard the “date” entity extracted by DIET and everything related to it.

The entity you want is the "time’ entity extracted by Duckling. Please also mention it in the domain.

Hi @ChrisRahme as suggested, I have updated date entity to time (if my understanding is correct), as follows:

entities:

  • time

slots: time: type: rasa.shared.core.slots.UnfeaturizedSlot initial_value: null auto_fill: true influence_conversation: false

forms: appointment_form: required_slots: time: - entity: time type: from_entity

However, the yellow warnings still comes up, and the bot is still accepting older dates.

Did you also remove the time/date entity from the intents?

Also delete your older models and train again.

Hi @ChrisRahme , thanks for your suggestion. I have amended the code as below which is now working as per requirement however, the date value is getting converted to some random number.

class ValidateAppointmentForm(FormValidationAction):
    def name(self) -> Text:
        return "validate_appointment_form"

    def validate_time(
        self, 
        value: Any, 
        dispatcher: CollectingDispatcher, 
        tracker: Tracker, 
        domain: DomainDict,
    ) -> Dict[Text, Any]:
        
        
        value = datetime.strptime(value, "%Y-%m-%dT%H:%M:%S.%f%z")
        
        now = datetime.now()
        now = pytz.utc.localize(now)

        print(f"Date given = {value} ")
        if value < now:
            dispatcher.utter_message(text=f"Date of Appointment cannot be less than today.")
            return{"time" : None}

        return {"time":value}

The date value is converted to 1632034800. Please suggest.

This value is not a random number, but is indeed the time. This is how computers read the time, as the number of seconds since 01/01/1970.

Please read about Unix time. Also check the Unix time converter.

1 Like