Prompting user for information

PromptDialog is a class that allows you to prompt users to answer questions. Each question corresponds to an entity. When the user answers the questions, entities are extracted from the answer. The PromptDialog uses the extracted entities to decide what to do next.

For example, you can use a PromptDialog when you want to:

Configure a car purchase:

const { PromptDialog } = require('botfuel-dialog');

class CarDialog extends PromptDialog {}

CarDialog.params = {
  namespace: 'car',
  entities: {
    color: {
      dim: 'color',
    },
    brand: {
      dim: 'brand', // use a corpus extractor
    },
    transmission: {
      dim: 'transmission', // use a corpus extractor
    },
    isNew: {
      dim: 'system:boolean',
    },
  },
};

Book a hotel:

const { PromptDialog } = require('botfuel-dialog');

class BookHotelDialog extends PromptDialog {}

BookHotelDialog.params = {
  namespace: 'book-hotel',
  entities: {
    city: {
      dim: 'city',
    },
    personNumber: {
      dim: 'number',
      isFulfilled: number => number && number <= 10, // max 10 persons
    },
    fromDate: {
      dim: 'time',
      isFulfilled: fromDate => fromDate && fromDate > Date.now(),
    },
    toDate: {
      dim: 'time',
      isFulfilled: (toDate, { dialogEntities }) =>
        toDate > dialogEntities.fromDate,
    },
  },
};

Implementation

In order to use the PromptDialog, you need to import the class and extend it to your dialog class.

The following example illustrates a travel dialog:

const { PromptDialog } = require('botfuel-dialog');

class TravelDialog extends PromptDialog {}

TravelDialog.params = {
  namespace: 'travel',
  entities: {
    departure: {
      dim: 'city',
      priority: 3,
      isFulfilled: (city, { dialogEntities }) =>
        city & (city !== dialogEntities.destination),
    },
    destination: {
      dim: 'city',
      priority: 2,
      isFulfilled: (city, { dialogEntities }) =>
        city & (city !== dialogEntities.departure),
    },
    date: {
      dim: 'time',
      isFulfilled: date => date && date > Date.now(),
    },
  },
};

Parameters

The PromptDialog has the following parameters:

  • The namespace is used to identify the dialog in the brain, where things are stored.
  • The entities are extracted from users answers by extractors and used to customize the flow of a conversation or to perform some actions.

For example:

<dialog-name>.params = {
  namespace: '<dialog-namespace>',
  entities: {
    <entity-name>: {
      dim: String,
      priority: Number,
      isFulfilled: Function(),
      reducer: Function(),
    },
    ...
  },
}

Namespace

The namespace is a key used by the brain to store the dialog-related data into the brain and access it. The namespace must be unique.

Entities

An entity is defined by the following properties: dim, priority, isFulfilled and reducer.

dim

The dimension defines the type of information that will be extracted from the user sentence. Dimensions can be pre-defined or user-defined.

dim is a required property.

The entity extractor based on Botfuel NLP entity extraction web service supports 31 dimensions. Corpus extractors use user-defined dimensions. There is also a built-in entity dimension system:boolean used to extract yes/no answers.

priority

The priority is a positive number, the greater the priority, the earlier the bot will ask for this entity.

priority is an optional property with a default value of 0.

For example, you can have the bot ask for the name of the user first, and then for his/her age:

age: {
  dim: 'number',
  priority: 1,
},
name: {
  dim: 'forename',
  priority: 2,
},

isFulfilled

The isFulfilled property is a function that returns a boolean value indicating if the entity value is matching the condition of done of the entity.

isFulfilled (entityName, { dialogEntities })

isFulfilled is an optional property. By default, an entity is fulfilled if the entity value is defined.

For example, if you want to store exactly 3 cities:

cities: {
  dim: 'city',
  isFulfilled: cities => cities && cities.length === 3,
}

Or if you want to retrieve a date later than today:

date: {
  dim: 'time',
  isFulfilled: date => date && date > Date.now(),
}

reducer

The reducer property is a function that defines how to deal with new values for the entity.

reducer (newValue, oldValue)

reducer is an optional property. By default the old value is replaced with the new one.

For example, if you want to replace the color only if the new one extracted is blue:

color: {
  dim: 'color',
  reducer: (oldColor, newColor) => newColor === 'blue' ? newColor : oldColor,
}

You want to replace the age only if is greater than the previous one:

number: {
  dim: 'number',
  reducer: (oldNumber, newNumber) => newNumber > oldNumber ? newNumber : oldNumber,
}