States and Actions

This framework makes it possible to define bot with all allowed state.

The state defines behaviour of the bot, the way it should respond to commands, updates and other events.

States

There can be more than one handler for the event. We call these handlers "Actions".

An action should return a NIL or a new state. In latter case, the current bot's state will be changed to the new one and handlers for on-activation event will be called.

State is constructed using state function, which accepts handlers for different kinds of events. Here is simples state which greets a user when it start the chat and then reply with the same text:

(defun reply-with-same-text (update)
  (reply (message-text
          (update-message update)))
  (values))


(state (send-text "Hello, I'm the echo bot.")
       :on-update 'reply-with-same-text)

The first argument to state function is a handler for on-activation event. If you don't want to react on activation, you can pass NIL instead. The send-text function returns an action instance. This way, we tell what bot should do, we use a declarative way to describe bot's behaviour.

The :ON-UPDATE argument specifies a handler for on-update event. This is the most generic event which occur when bot receives an update which wasn't processed by other event handlers. For this handler we are using a custom function bound to the symbol reply-with-same-text. The function accepts a single argument - update object. Use generic functions from cl-telegram-bot2/api package to work with this update object.

The reason why we only accept a special action object or a symbol but not a lambda function is because this way we'll be able to generate schemas of all states and transitions between them. Another reason is that it will be possible to redefine fbound function and use interactive approach to changing bot's behaviour.

See other support events in state function documentation.

Actions

Actions in cl-telegra-bot are small objects holding an information about what should be done on some event. Typically, you will want to reply with some text or send a photo.

Usually, actions are created using a function having the same name as action's class. Here are which actions are available:

More actions will be added in future and you can create your own.

Also, a function bound symbol can be used instead an action object. Why do we require a symbol but not a function object? Because symbol has a name and it can be useful when we want to save bot's state or to render states graph.

Event processing

When some event occur, a corresponding generic function is called first on state object then on an action specified for this kind.

For example, if new update was received, then cl-telegram-bot2/generics:process generic-function will be called with current state as the first argument and update object as the second argument. Then the method specified on state class will call the same cl-telegram-bot2/generics:process generic-function on the object specified as :ON-UPDATE argument for the action. If action is a symbol, then it's function will be called with update object as a single argument in case if this function accepts one argument and without any arguments otherwise.

Action's method should return should return a new state object if it wants to change the current bot's state or NIL otherwise. If new state was returned, then on-activate event will be processed afterwards.

Instead of one action a list of actions can be specified as an event handler. In this case processing will stop on an action which returns a new state.