Recurrence rules with NLP
Published: 2023-11-19 15:42:20

Recurrence rules allow users to set the frequency of events, such as:

1. Daily
2. By day of week (Every Monday, Every Tuesday, etc.)
3. Monthly, By day of week
4. Monthly, By day of month
5. Every certain date (Every 1st, Every 2nd, etc.)
6. By a range of days of week (From Monday to Wednesday)
7. By a range of days of month (From 1st to 3rd)
8. By a range of dates (From 10/1 to 12/7)
9. Between a start time and end time (From 7 AM to 9 AM)
10. Monthly (or Every 2 months, Every 3 months, etc.)
11. Starting on a date (No end date)
12. Ends on a certain date
13. Until a number of recurrences

Almost all apps (think Google Calendar) implement recurrence rules via a form. Radio buttons are used for different cases. However, what if we wanted to condense the form into a single text input that lets the user type what they want?

The feature we’re describing is known as natural language processing (NLP), which is a complex field of AI that involves interpreting, recognizing, and understanding human language in a valuable way.

It can be challenging to implement this feature because of the complexities involved with understanding and interpreting human language. We need to consider a wide range of possible user inputs and how to parse and interpret them.

However, there are libraries and APIs available that can make this task easier! For example, the `chrono` JavaScript library can parse dates written in natural language.

Here’s a simple example of how we could implement recurrence rules via NLP:

Listen for changes to the recurrence-rule input field.

```
document.getElementById('recurrence-rule').addEventListener('change', function() {

}
```

When the field is changed, we parse the user’s input using the `chrono` library:

```
document.getElementById('recurrence-rule').addEventListener('change', function() {
     var parsedResult = chrono.parse(this.value);
}
```

If `chrono` is unable to parse the user’s input, we will display a message asking the user to try again:

```
document.getElementById('recurrence-rule').addEventListener('change', function() {
     var parsedResult = chrono.parse(this.value);
     // If chrono couldn't parse the input, show a default message.
    if (parsedResult.length === 0) {
        document.getElementById('suggested-rule').textContent = "Sorry, we couldn't understand your recurrence rule. Please try again.";
        return;
    }
}
```

We then check whether or not the parsed result is recurrent (i.e., whether or not it’s certain of the weekday). If the event is recurrent, we suggest a rule of “Every [Day of Week]”. If the parsed date is certain of the weekday and the user’s input includes the word “other”, it suggests a rule of “Every other [Day of Week]”. If the user’s input includes the word “weekday”, it suggests a rule of “Every weekday”.

If the event is not recurrent, we suggest a rule of “Once on [Date]”:

```
document.getElementById('recurrence-rule').addEventListener('change', function() {
     var parsedResult = chrono.parse(this.value);
     // If chrono couldn't parse the input, show a default message.
    if (parsedResult.length === 0) {
        document.getElementById('suggested-rule').textContent = "Sorry, we couldn't understand your recurrence rule. Please try again.";
        return;
    }
    // Extract the relevant information from the parsed result.
    var date = parsedResult[0].start.date();
    var isRecurrent = parsedResult[0].start.isCertain('weekday');
    
    // Create the suggested recurrence rule.
    var suggestedRule;
    if(isRecurrent) {
        var days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
        var dayOfWeek = days[date.getDay()];
        var everyOther = this.value.toLowerCase().includes('other') ? 'other ' : '';
        suggestedRule = `Every ${everyOther}${dayOfWeek}`;
    } else if(this.value.toLowerCase().includes('weekday')) {
        suggestedRule = 'Every weekday';
    } else {
        suggestedRule = `Once on ${date.toLocaleDateString()}`;
    }
}
```

Finally, we display the suggested recurrence rule:

```
document.getElementById('recurrence-rule').addEventListener('change', function() {
...
// Display the suggested recurrence rule to the user for confirmation.
    document.getElementById('suggested-rule').textContent = `Suggested Rule: ${suggestedRule}`;  
});
```

Of course, this function becomes much more complex the more use cases we implement. We also need to add additional checks for the validity of the user's input. However, this is a great start to using NLP to condense a form of recurrence rule radio buttons to a sleek, minimal input. Remember, great implementation abstracts the complex details behind the scenes and provides a simple interface to the user.