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.new "https://website.com/filename.jpg"
# Get the url value
.url # "https://website.com/filename.jpg"
# Get url file extension
.extension # "jpg"
# Different helper methods for different multimedia types.
.jpg? # True
.image? # True
.mp3? # False
.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.