Using Duckling to Extract Dates and Times in Your Rasa Chatbot

Adam Bowker
4 min readSep 27, 2020

--

It’s easy, I promise!

Photo by Moritz Kindler on Unsplash

I recently started using Rasa to create a chatbot for my job. Rasa is an extremely powerful open source conversational AI for building contextual assistants (or, chatbots). There are so many use-cases for Rasa, including personal assistants, FAQ chatbots, customer support bots, and more. Reply and let me know if you have any other potential use-cases!

One of the things my chatbot needed to do was extract dates and times from user messages.

This was a really daunting task, because dates are hard.

After a bit of research, I discovered Duckling, a Haskell library for parsing text into structured data. Rasa supports adding Duckling to your bot’s pipeline, but does not provide very good documentation surrounding it.

So, here’s how to get it done!

Install Stack + Duckling

The Duckling GitHub repo provides sufficient instructions for this, but to recap: first you’ll need to install stack , a project builder for Haskell. Then, you can clone the Duckling repo and build it.

macOS

Stack: curl -sSL https://get.haskellstack.org/ | sh

Note: On macOS systems, you may need to install PCRE development headers. Do so with brew install pcre, and if needed, run brew doctor afterward.

Linux

Stack: wget -qO- https://get.haskellstack.org/ | sh

Then, you can install Duckling by cloning the GitHub repo:

git clone https://github.com/facebook/duckling.git

Build Ducking and Start the Server

To build Duckling, simply navigate to wherever you installed it and run stack build.

Then, to start a sample server, run stack exec duckling-example-exe.

You’ll now have a Duckling server running on port 8000.

You can send a sample POST request to the server to make sure it’s working. For example, if you wanted to parse a string that said “tomorrow at 8pm,” you could use this:

curl -XPOST http://0.0.0.0:8000/parse --data 'locale=en_US&text=tomorrow at 8pm'

The response should look like this:

[
{
"body": "tomorrow at 8pm",
"start": 0,
"value": {
"values": [
{
"value": "2020–09–28T20:00:00.000–07:00",
"grain": "hour",
"type": "value"
}
],
"value": "2020–09–28T20:00:00.000–07:00",
"grain": "hour",
"type": "value"
},
"end": 15,
"dim": "time",
"latent": false
}
]

You can see it took “tomorrow at 8pm” and returned a timestamp of 2020-09-28T200:00:00.000-07:00. This is accurate, given that I’m writing this on September 27, 2020, and my timezone is GMT-7.

Adding Duckling to Your NLU Pipeline

You can add Duckling to your NLU pipeline the same way you’d add any other service or tokenizer.

Simply add a new entry like this in your config.yml file, indicating the URL and port of your Duckling server, as well as the entities you’d like to extract (listed as dimensions).

- name: "DucklingHTTPExtractor"
url: "http://localhost:8000"
dimensions: ["time"]

Duckling supports many dimensions (i.e. things it can extract), such as money, distances, durations, temperatures, and URLs. You can learn more about the dimensions Duckling offers here.

Almost done — the last step in configuring Duckling is defining the slots it will use.

In your domain.yml file, add two new things: a time entity, and a time slot.

entities:
- time
slots:
time:
type: unfeaturized

Please note: Duckling does not require you to mark the entities it will extract in your training data, and it can actually mess things up if you do, so refrain from marking your stories with entities that Duckling is looking for.

Reading What Duckling Extracts

Now that your Duckling server is up & running and it has been added to your NLU pipeline, Duckling will attempt to extract values from every message a user sends to your Rasa chatbot.

In this example, because I amextracting time, the data will automatically be saved to the time slot.

Using Rasa Forms

If you’re using Rasa Forms, you can check the value of the time slot in your actions.py file using this code:

time = tracker.get_slot("time")

This will return a string, in the same format we saw during our test POST request, and you can convert it to a Python datetime with strptime using the following syntax:

from datetime import datetime as dt
time_object = dt.strptime(time, "%Y-%m-%dT%H:%M:%S.%f%z")

At this point, you can do anything you want with your new datetime object! Save it to a database, convert it to something human-readable to say back to your user, or even use it to check for calendar availability.

Without Rasa Forms

Rasa Forms will provide the most functionality for handling user input, but without it, you can still print out the extracted time back to your user.

Use this syntax in one of your bot’s utterances in your domain.yml file:

utter_sounds_good:
- text: Great. I'll see you at {time}!

When your bot uses this utterance, if the time slot has been set, the {time} bit will be replaced with the value of the slot.

Go create an amazing bot!

Duckling is an amazing solution to extracting all sorts of data from user input, and hopefully this article has helped you understand how to incorporate it into your Rasa project. I’m looking forward to seeing all of the incredible things you will create 😄

--

--