RBender is a DSL-specified framework to create bots for Telegram platform. Framework are developed to be maximally comfortable and intuitive for developers and proposes ultimate tools for bot creation.
- Domain Specific Language based
- FSM (Final State Machine) model
- Logically encapsulated codee
- Simple, clear and powerfull
- WEB-like sessions
- Logger
- i18n support
- Inline API support
- Game API support
- Payment support
To use this framework you need MongoDB installed. Please visit MongoDB website for more information.
~$ gem install rbender
To create new project type in terminal:
~$ rbender new DemoBot
Then new project with templates will be created.
To run your bot:
~$ cd DemoBot
~/DemoBot$ rbender start
The Rbender framework based on Final State Machine model. Every state a represents one set of actions, which user could do while in state. The main idea of RBender are describing states and their's inner structure.
Every state can include:
- Keyboard
- One or more inline keyboards
- Text/Audio/Video/other hooks
- Before/After hooks
- Helper methods
The first state where user should be after '/start' command is start state.
For example, this code redirects user to :state_1 after :start state code has been executed.
state :start do
after do
switch(:state_1)
# used to change states
end
end
state :state_1 do
# ...
# some code
# ...
end
User's state before execution:
User's state after execution:
Beside this, there are can be global state where you can define helper methods and command hooks.
States are main logical part of bot. States could be described as follow by using state keyword:
state :start do
# do some code
end
state :state_first do
# do some code
end
state :state_second do
# do some code
end
global do
# do some code
end
:start state is required and is a main entry point.
Global state helps developers to define global inline keyboards, helpers and commands.
Hooks are callbacks which execututes when user sends to bot some different type messages like text/audio/video.
state :state_main do
text do
# execetues when user sends text message
end
image do
# executes when user sends picture
end
video do
# executes when user sends video
end
end
Available typed hooks:
- text
- audio
- photo
- video
- voice
- document
- location
- contact
- animation
- sticker
- chat
Before hook executes immediatly when user before state has changed.
After hook executes after state has changed
state :state_one do
text do
switch(:state_second) if message == 'switch'
end
after do
# executes before switch happens
end
end
state :state_second do
before do
# executes when state will be :state_second
end
end
Commands are messages begins with '/' symbol. Commands are availble from all states to user and should be described as follows
global do
command '/about' do
send_message(text: "by Arthur Korochansky @art2rik")
end
command '/with_params' do |params|
# f.e. if command was /with_params 1 one odin
# params = [1, 'one', 'odin']
end
end
Every keyboard are assigned to single state and executes at the same time as state has changed.
state :state_main do
keyboard do
keyboard_response = "This is a keyboard"
set_response(keyboard_response) # Response is REQUIRED!!!
button :btn_one, "One" do
set_response("You've pressed ONE") # change keyboard response to user
# action callback
end
button :btn_two, "Two" do
set_response("You've pressed TWO")
# action callback
end
button :btn_third, "Thrid" do
set_response("You've pressed THIRD")
# action callback
end
add_line(:btn_one, :btn_two) # put "one" and "two" buttons in first line
add_line(:btn_third) # put "third" button in second line
resize() # auto resize button
one_time() # hide keyboard after use
end
end
Inline Keyboards are similar to common keyboard, but it's must be attached to message.
There are three button types in inline mode:
- Button – classic button with callback
- Link button – button with URL
- Inline switch button – switch to inline mode
state :state_main do
before do
# Invoke inline keyboard
send_message(text: "This is inline keyboard under this message",
reply_markup: inline_markup(:kb_sample))
end
keyboard_inline :kb_sample do
button :btn_hello, "Hi!" do
# Action callback
edit_message(text: "Hello!")
end
button_link(:btn_url,
"RBender homepage",
https://github.com/art2rik/RBender)
add_line(:btn_hello)
add_line(:btn_url)
end
end
Sessions are special structure which stores different user's information.
You could find out following data in the sessions:
session[:state] # Current user's state
session[:lang] # Current user's language
session[:user][:chat_id] # User's chat id
session[:user][:user_name] # Telegram alias if available
session[:user][:first_name]
session[:user][:last_name] # If available
Futhermore, you can contain your own values inside session variable to store parameters and other user's data, but keys above are reserved (also :state_stack, :keyboard_switchers, :keyboard_switch_groups are reserved too).
state :state_main do
before do
# Init new user's session parameter
session[:notes] = []
end
text do
# Add user's message to saved notes
session[:notes].push(message.text)
end
end
Likely, you may want to expand your bot functionality by additional functionality modules. You can use telegram api driver and mongodb driver to use it in your own classes or modules.
How to do it:
modules do |api, mongo|
YourModule.set_api(api)
YourModule.set_mongo(mongo)
end
RBender use telegram-bot-ruby api driver and MongoDB ruby driver. Also you can get access to MongoDB driver like this:
RBender::MongoClient.client
Method name | Arguments | Description |
---|---|---|
state | state_id * Symbol/String id of a state &block state block |
Defines state |
global | &block global state code block | Defines global state |
modules | — | Defines additional bot modules (Returns additional parameters api_driver and mongodb_driver) |
Used in state block.
Method name | Arguments | Description |
---|---|---|
keyboard | kb_response String message displayed to user when keyboard has showed &block keyboard code block |
Defines keyboard |
keyboard_inline | keyboard_id Symbol/String inline keyboard id &block keyboard code block |
Defines inline keyboard |
after | &block hook block code | Hook invoked after state are changed |
before | &block hook block code | Hook invoked before over hooks are executed |
text | &block hook block code | Hook invoked on text messages |
audio | &block hook block code | Hook invoked on audio messages |
photo (Aliases: image, picture) |
&block hook block code | Hook invoked on photos |
video | &block hook block code | Hook invoked on video messages |
voice | &block hook block code | Hook invoked on voice messages |
document | &block hook block code | Hook invoked on document messages |
location | &block hook block code | Hook invoked on location messages |
contact | &block hook block code | Hook invoked on contact messages |
animation | &block hook block code | Hook invoked on animation messages |
sticker | &block hook block code | Hook invoked on sticker messages |
chat | &block hook block code | Hook invoked on messages with chats |
command | command command name &block action callback |
Defines global commands Throws params argument (global state only) |
helpers | &block block with defined helper methods | Defines helpers |
Used inside hooks.
Method name | Arguments | Description |
---|---|---|
switch | state_id Symbol id of needed state | Changes state of user |
switch_prev | – | Returns to previous state |
inline_markup | keyboard_id Symbol id of required keyboard | Returns inline markup object |
session | – | Return user's session |
message | - | Returns last (usually actual) message object |
Used inside keyboard block.
Method name | Arguments | Description |
---|---|---|
session | – | Return user's session |
button | id Symbol Id of button description String value of button &action callback |
Adds button |
add_line | *buttons Ids of button | Adds buttons row to markup |
resize | - | Resizes button |
one_time | - | Hide keyboard after use |
Used inside keyboard_inline block.
Method name | Arguments | Description |
---|---|---|
session | – | Return user's session |
button | id Symbol Id of button description String value of button &action callback |
Adds button |
button_link | id Symbol Id of button description String value of button link URL |
Adds URL-button |
button_inline | id Symbol Id of button description String value of button query Query object |
Adds Inline Mode button |
add_line | *buttons Ids of button | Adds buttons row to markup |
RBender supports all avalaible Telegram Bot API methods. But there are some litlle differences:
- There are not necessary to specify user_id, you're always work with concrette user
- Use snake_case instead CamelCase
state :state_main do
before do
send_message(text: "Some useless words")
send_message(chat_id: session[:chat_id],
text: "Another useless text")
# Both (!!!) messages will be delievered to the same user
end
end
Inside helpers block you could define helper methods inside your states.
# You could define helpers visible inside a state only
state :state_main do
kb_response = "Press any button"
keyboard kb_response do
button :btn_local, "Local helper" do
local_helper_method()
end
button :btn_global, "Global helper" do
global_helper_method()
end
add_line(:btn_local)
add_line(:btn_global)
end
helpers do
def local_helper_method
send_message(text: "Local helper method has been invoked")
end
end
end
# Or you could define global helper
global do
helpers do
def global_helper_method
send_message(text: "Global helper method has been invoked")
end
end
end
For detailed documentation please visit our wiki.
RBender widely used for e-commerce bot creation. There are at least one professional team, which successful integrated RBender into their work and uses the framework to create commercial bots (Anybots team, Telegram: @spiritized). Also, RBender is used for inner-communication bots inside Innopolis city (Russia).
- @HighTechFmBot: HighTech.FM media journal bot
- @FintechRankingbot: FintechRanking news bot
- @icecakemoscowbot: Food delievery bot