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?
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 |
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:
CASE B
, CASE C
, or CASE D
.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!
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:
AMAZON.SearchQuery
slot type and handle all manually. Hard, but doable.