Contexts

Contexts are the skeleton of an application developed with Kogno, since in these, a large part of the logic of capturing, processing and replying to an incoming message is developed.

In a given project, all the contexts needed can be created in order to develop a well structured conversation.

Making a parallel with Ruby on Rails or the MVC architecture, the contexts would be the equivalent of controllers.

Creating a new Context

A context is represented by a class which is declared as follows:

class TheContextNameContext < Conversation

Basic rules to create a new context

  1. All contexts created must inherit from the Conversation class.

  2. The class name must end in Context. Ex: MainContext, ProductsContext, PurchaseContext and so on.

  3. All context files must be located in the bot/contexts/ directory under files with ".rb" extension. Ex: the_context_name_context.rb, profile_context.rb ,people_context.rb and so on.

Default context: MainContext

In a new project, the context MainContext is created by default into the file bot/contexts/main_context.rb.

This is the general context of the conversation and the context by default in a new conversation.

All the logic of capturing, processing and replying to a message from a user that is in a conversation without a context, will be developed here.

Change the default context

The default context can be changed by modifying the config.routes.message field in config/application.rb configuration file.

blocks() method

The blocks() method is declared in a Context class and within it, the action blocks necessary to capture messages with the characteristics that the context is expecting to handle.

class MainContext < Conversation

  def blocks
    
      # Here you will define the action blocks.
      
  end
  
end

Usage Example

In the code below, see how MainContext can handle the following scenarios with the declaration of 3 action blocks:

  • intent "greeting" : A greeting messages, such as "Hello" or "Hi". If the intent exists and has been trained on the NLP engine.

  • postback "email_subscription": A click event, that occurs when the user clicks on the button "Subscribe Me" replied by the block above.

  • everything_else: A generic response, in case the message were not any the ones declared above.

class MainContext < Conversation

  def blocks

    intent "greeting" do 
      @reply.text "Hello!"
      @reply.button(
        "What can I do for you?",
        [
          {
            title: "Subscribe Me",
            payload: "email_subscription"
          },
          {
            title: "See Featured Products",
            payload "products/featured"
          }
        ]
      )      
    end
    
    postback "email_subscription" do
      @reply.text "Great!"
      @reply.typing 1
      ask "/profile/ask_email"
    end
    
    everything_else do 
      @reply.text "My answers are still a bit limited."
    end

  end
  
end

The ask() method, that together with the block answer, focuses and reduces the conversation to achieve a goal. In this case "get the user's email".

Read more in the ask & answers chapter.

Multi-Context conversation

When the logic of the conversation becomes broader, a better distribution of the code will be very helpful.

For this reason, it's recommendable to create as many contexts needed, in a similar way to when the controllers are created in the MVC architecture.

Example

For this example we will create a new context called ProductsContext in bot/contexts/products_context.rb.

class ProductsContext < Conversation

  def blocks
  
    postback "featured" do
      products = Product.where(featured: true).limit(10)
      @reply.text "Here you can see our featured products 👇"
      @reply.template "products/carousel", products: products
    end

  end
  
end

And remembering the first example above, in the hypothetical scenario in which a user clicks on the second button "See Featured Products" (payload: "products/featured") that has been sent as reply in the block intent "greeting".

The click event will delegated in order to be handled by the ProductsContext, since the payload contains a route to this context. Learn more about this in Context Routing chapter.

Moving between contexts

These methods are used to take the conversation from one context to another:

change_to(route=String, params=Hash)

Changes the context of the conversation, from the current context to another context or sub-context.

After this method is called, all incoming messages from a particular user will be captured by the context defined in the route argument, and this context will remain active until the context changes again or exit_context() method were called.

Usage

Change to other context:

change_to "some_context_name"

Change to a sub context from other context:

change_to "some_context_name/sub_context_name"

Change to a sub context in the same context

change_to "./sub_context_name"

Change From a sub context to his parent context:

change_to "../sub_context_name"

Params

NameDescription

route String

Required.

Contains a context's name of a path to a context or sub-context.

params Hash

Optional. Only available for sub-contexts. It sends parameters to the sub-context defined. Read more in sub-contexts chapter.

delegate_to(route=String, args=Hash)

It delegates the handling of the incoming message to a context or sub-context, but without the conversation changing context.

Usage

delegate_to "some_context_name_or_path", ignore_everything_else: false

The format of the route argument is the same as with the change_to() method.

Params

NameDescription

route String

Required.

Contains a context's name of a path to a context or sub-context.

args Hash

Optional.

If ignore_everything_else is true, it will not execute the everything_else block, if it exists in the delegate context. By default false.

exit_context()

Exits the current context and takes the conversation to the default context.

Usage

exit_context()

keep()

Keeps the conversation in the delegated context. Whether it was delegated by context routing or by calling the delegate_to() method.

Usage

keep()

Last updated