Kanal

Welcome to Kanal!

Kanal is a platform to create chat-bots with it's own DSL. As a key feature Kanal provides router which is configured by you, the developer. Configuration of router implies setting specific responses to specific inputs. Router can consume input (text, images, audio, files) and prepare response (or several responses) to it to be processed further. Configured router defines chat-bot's communication logic that can be used by different types of chat-platforms (Telegram, Discord, etc.)

Core functionality of Kanal can be extended with plugins. For example, plugins can provide database to store data; user system that allows storing and working with data of end-users of chat-bot; integration with telegram or discord to receive messages from end-users and responses to be sent to them. Kanal has Batteries plugin that allows input and output to have text and also image, audio or file attached.

Overview of Kanal components

Core

Core is is a key Kanal component. To create the Kanal app is to create Core.

core = Kanal::Core::Core.new

Input and Output

Input is an object representing information received from end-user. To store data inside Input and access it later you need to register parameter for it. Then you can pass your data to it.

core.register_input_parameter :test_parameter
input = core.create_input  
input.test_parameter = "test_value"

Batteries plugin provides pre-made parameters, such as body and source.

input.body = <Your string>
# Source should be of Symbol type
input.source = :telegram
input.audio = 
input.image = 
input.file = 

TODO: Describe image, audio and file parameters. Are they supposed to contain url strings?

Output is an object representing information ready to be sent to end-user. As with Input, you can register your own parameters. Batteries provides same parameters for Output as for Input.

Conditions

Condition is a true/false blocks that will tell the router if particular route should be used. Conditions are registered within the condition pack that has specific name.

core.add_condition_pack :contains_day_of_week do
  add_condition :friday
    met? do |input, core, argument|
      # Rememer how you registered .body parameter of input? It will be accessible in condition here!
      input.body.include? "friday"
    end
  end

  add_condition :monday
    met? do |input, core, argument|
      input.body.include? "monday"
    end
  end
end

Router

Router is a collection of responses to specific conditions defined by user. Upon meeting the condition router will create output (or outputs). Using previously made conditions we can specify what operation will be performed and what the output (outputs) will contain.

core.router.configure do
  on :contains_day_of_week :friday do
    respond do
      body "What, already?"
    end
  end

  on :contains_day_of_week :tuesday do
    respond do
      body "Start of the week huh"
    end

    respond_async do
        <http request or database call here>
      body "I will work tirelessly!"
    end
  end
end

In respond block you can do anything besides setting output parameters.

It is advised to make database calls, http requests or other time-consuming operations in respond_async block.

Router has built-in default response for when none of the conditions are met. You can set your own default response.

core.router.default_response do
  body "Custom default message here"
end

Router has built-in error response for when there is an error during constructing of output. You can set your own error response.

core.router.error_response do
  body "Custom error message here"
end

Hooks

Hooks can be used to intercept the execution flow in specific places in your code and do something with data provided to it. Hooks are registered in the Core. You can attach to hook, specifying arguments and block of code to be executed. When the hook will be called, the argument will be passed to provided block and it will be executed.

core.hook_storage.register :on_something
val = nil
hooks.attach :on_something do |value|  
    val = value  
end
hooks.call :on_something, "testy"
puts val # "testy"

By default core has 3 hooks.

:input_just_created # input  
:input_before_router # input  
:output_before_returned # input, output

Attachments

Batteries plugin provides Attachments functionality.

attachment = ::Attachment.new "https://website.com/filename.jpg"
# Get the url value
attachment.url # "https://website.com/filename.jpg"
# Get url file extension
attachment.extension # "jpg"
# Different helper methods for different multimedia types.
attachment.jpg? # True
attachment.image? # True
attachment.mp3? # False
attachment.audio? # False

Interfaces

Plugins

Interfaces

Plugins

Installation

Install the gem and add to the application's Gemfile by executing:

$ bundle add kanal

If bundler is not being used to manage dependencies, install the gem by executing:

$ gem install kanal

Usage

TODO: Write usage instructions here

TODO

  • [DONE] ~provide default response for branch with subbranches because default response could be handy~
    Provided with the :flow condition pack with condition :any
  • [DONE] ~rework hooks storage, make hooks without arguments validation~
  • ~provide default logger with base class. this logger service should be used by every other service/plugin etc~
  • ~provide default response on error, when router node fails with error~
  • [DONE] ~provide :source condition for :source~
    Created :source condition pack
  • Allow to "append" conditions to condition packs

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and the created tag, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/kanal.

License

The gem is available as open source under the terms of the MIT License.