Custom handling for AMAZON.DATE slot type to find Past Dates only

270 Views Asked by At

The Problem

I know in the docs that AMAZON.DATE slot type defaults to look for future dates. As far as I can see there's no way for me to set it to past dates by default.

If that's the case, what can I do within my code to handle this?

Example

A simpler version of my case: fetch news articles from a specific day. With today's date (2021-11-14) a user says the following:

User Input Intended Date input_date diff = (input_date- today).days Handling
Get me news articles from last Wednesday 2021-11-10 2021-11-10 -4 Accept as-is
Get me news articles from November 10th 2021 2021-11-10 2021-11-10 -4 Accept as-is
Get me Wednesday's news 2021-11-10 2021-11-17 3 Subtract 7 days
Get me the news from November 10th 2021-11-10 2022-11-10 361 Returned date is in future: needs 1 year subtracted
Get me the news for next week 2022-11-15 2022-11-15 1 Returned date is in future: user specifically asked for future news (for some reason), should give user friendly error response

Near-Solution I've Tried

Here's a function I mocked up in Python for troubleshooting with some detailed comments:

def getArticleDate(input_date):
    today = datetime.date.today()
    diff = (input_date - today).days

    if diff <= 0:
        # === CASE A ===
        # Condition: input_date is in the past
        # Input: User must have been specific enough or used keyword like "last" or "previous"
        # Example input: "from last Wednesday", or "June 19th 2021", or "in the previous month"
        # Handling: None

        return input_date

    if diff <= 7:
        # === CASE B ===
        # Condition: input_date is up to a week in the future
        # Input: User MIGHT have specified day of week
        # Example input: "Wednesday" on any day but Wednesday
        # Handling: Subtract 7 days

        return input_date - datetime.timedelta(days=7)

    if input_date.month == today.month and input_date.year == today.year:
        # === CASE C ===
        # Condition: input_date is within the same month and year as today, but more than 1 week in the future
        # Input: User MIGHT have specified the day of the month but not the month
        # Example input: "on the 21st"
        # Handling: Get the last occurrance of that day of the month
        # Note: Usually, but not necessarily the previous month, e.g. user says "on the 31st" on October 20th and there is no September 31st so must be July 31st

        end_of_month = today
        while end_of_month.day < input_date.day:
            end_of_month = end_of_month.replace(day=1) - datetime.timedelta(days=1)
        return end_of_month.replace(day=input_date.day)

    if input_date.replace(year=input_date.year - 1) < today:
        # === CASE D ===
        # Condition: input_date is more than a week in the future but no more than 1 year
        # Input: User MIGHT have specified day and a month, but not a year
        # Example: "May 10th", or "on 27th September"
        # Handling: Subtract 1 year
        return input_date.replace(year=input_date.year - 1)

    # === CASE E ===
    # Condition: input_date is more than 1 year in the future
    # Input: User must have specified a date more than 1 year in the future
    # Example: "August 21st, 2022"
    # Handling: Raise error
    raise ValueError(
        f"{input_date.isoformat()} is out of range."
    )

This doesn't work in 2 cases:

  1. The user specifies a date less than a year in the future e.g. "tomorrow", or "next month", or "January 30th, 2022". Instead it is handled by CASE B, CASE C, or CASE D.
  2. The user specifies a day of the month, but not the month, AND the input_date is less than a week in the future e.g. "from the 17th" on November 14th. This should be handled by CASE C but instead is handled by CASE B. Switching the order just reverses the problem, making weekday-specifying inputs handled by CASE C instead of CASE B.

Thanks for any help, I've been really stuck on this!

1

There are 1 best solutions below

1
tole On BEST ANSWER

Unfortunately Amazon forces this own NLU resolving engine and not giving out the raw text user actually said. That makes these kinds of tasks nearly impossible to achieve and puts a lot of “User MIGHT have specified”. This brings you to two, quite opposite approaches you can use here:

  • just rely on what Amazon gives you and call it a platform feature (not bug :)). Amazon Alexa users are used to it, because all developers have the same problem and almost all the similar skills will have the same issue.
  • use the AMAZON.SearchQuery slot type and handle all manually. Hard, but doable.