# 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 = # 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 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](https://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](https://opensource.org/licenses/MIT).