class Telegram::Composer
- Telegram::Composer
- Reference
- Object
Direct Known Subclasses
Defined in:
telegram/composer.crConstructors
-
.new(middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Create a new
Composer
with the given middleware -
.new(*middleware : AcceptableMiddleware)
Create a new
Composer
with the given middleware -
.new(&block : MiddlewareFn)
Create a new
Composer
with the given middleware
Class Method Summary
- .concat(first : Middleware, and_then : Middleware) : Middleware
- .flatten(mw : AcceptableMiddleware) : Middleware
- .match(ctx : Context, content : String, triggers : Array(Proc(String, Regex::MatchData | Nil)))
- .pass
- .trigger_fn(trigger : String | Regex | Array(String | Regex))
Instance Method Summary
-
#branch(predicate : Filter::Predicate, true_mw : AcceptableMiddleware, false_mw : AcceptableMiddleware)
Allows you to branch between two cases for a given context object.
-
#branch(true_mw : AcceptableMiddleware, false_mw : AcceptableMiddleware, &predicate : Filter::Predicate)
Allows you to branch between two cases for a given context object.
-
#callback_query(trigger, middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Registers some middleware for callback queries (updates that Telegram sends when a user clicks on a button in an inline keyboard).
-
#callback_query(trigger, *middleware : AcceptableMiddleware)
Registers some middleware for callback queries (updates that Telegram sends when a user clicks on a button in an inline keyboard).
-
#callback_query(trigger, &block : MiddlewareFn)
Registers some middleware for callback queries (updates that Telegram sends when a user clicks on a button in an inline keyboard).
-
#command(command, middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Registers a middleware that will be called when a certain command is found:
-
#command(command, *middleware : AcceptableMiddleware)
Registers a middleware that will be called when a certain command is found:
-
#command(command, &block : MiddlewareFn)
Registers a middleware that will be called when a certain command is found:
-
#drop(predicate : Filter::Predicate, middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Registers middleware behind a custom filter function that operates on the context object and determines whether or not to contuinue middleware execution.
-
#drop(predicate, *middleware : AcceptableMiddleware)
Registers middleware behind a custom filter function that operates on the context object and determines whether or not to contuinue middleware execution.
- #drop(middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware, &predicate : Filter::Predicate)
- #drop(*middleware : AcceptableMiddleware, &predicate : Filter::Predicate)
-
#error_boundary(error_handler : ErrorHandler, middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Installs an error boundary that catches errors that happen inside the given middleware.
-
#error_boundary(error_handler : ErrorHandler, *middleware : AcceptableMiddleware)
Installs an error boundary that catches errors that happen inside the given middleware.
-
#error_boundary(error_handler : ErrorHandler, &middleware : MiddlewareFn)
Installs an error boundary that catches errors that happen inside the given middleware.
-
#filter(predicate : Filter::Predicate, middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Registers middleware behind a custom filter function that operates on the context object and determines whether or not to contuinue middleware execution.
-
#filter(predicate, *middleware : AcceptableMiddleware)
Registers middleware behind a custom filter function that operates on the context object and determines whether or not to contuinue middleware execution.
-
#filter(middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware, &predicate : Filter::Predicate)
Registers middleware behind a custom filter function that operates on the context object and determines whether or not to contuinue middleware execution.
-
#filter(*middleware : AcceptableMiddleware, &predicate : Filter::Predicate)
Registers middleware behind a custom filter function that operates on the context object and determines whether or not to contuinue middleware execution.
-
#fork(middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Registers some middleware that run concurrently with other middleware in the stack.
-
#fork(*middleware : AcceptableMiddleware)
Registers some middleware that run concurrently with other middleware in the stack.
-
#fork(&block : MiddlewareFn)
Registers some middleware that run concurrently with other middleware in the stack.
-
#game_query(trigger, middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Registers some middleware for game queries (updates that Telegram sends when a user clicks an inline button to launch an HTML5 game).
-
#game_query(trigger, *middleware : AcceptableMiddleware)
Registers some middleware for game queries (updates that Telegram sends when a user clicks an inline button to launch an HTML5 game).
-
#game_query(trigger, &block : MiddlewareFn)
Registers some middleware for game queries (updates that Telegram sends when a user clicks an inline button to launch an HTML5 game).
-
#hears(trigger, middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Registers a
#middleware
that is executed when the message contains a specific pattern. -
#hears(trigger, *middleware : AcceptableMiddleware)
Registers a
#middleware
that is executed when the message contains a specific pattern. -
#hears(trigger, &block : MiddlewareFn)
Registers a
#middleware
that is executed when the message contains a specific pattern. -
#inline_query(trigger, middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Registers some middleware for inline queries (updates that Telegram sends when a user types "@YourBotName ..." into a text field).
-
#inline_query(trigger, *middleware : AcceptableMiddleware)
Registers some middleware for inline queries (updates that Telegram sends when a user types "@YourBotName ..." into a text field).
-
#inline_query(trigger, &block : MiddlewareFn)
Registers some middleware for inline queries (updates that Telegram sends when a user types "@YourBotName ..." into a text field).
-
#lazy(factory : MiddlewareFactory)
Executes some middleware that are generated on the fly for each context.
-
#lazy(&block : MiddlewareFactory)
Executes some middleware that are generated on the fly for each context.
-
#middleware : Telegram::Middleware
Returns the middleware that make up this Composer.
-
#on(filter, middleware : Array(AcceptableMiddleware) = [] of AcceptableMiddleware)
Registers
#middleware
that will only be executed when certainUpdateAction
s are included in an update. -
#on(filter, *middleware : AcceptableMiddleware)
Registers
#middleware
that will only be executed when certainUpdateAction
s are included in an update. -
#on(filter, &block : MiddlewareFn)
Registers
#middleware
that will only be executed when certainUpdateAction
s are included in an update. -
#route(router : RouterFn, handlers : Hash(String, AcceptableMiddleware), fallback : AcceptableMiddleware = Composer.pass)
This allows you to branch between different middleware per context object in much the same way you would branch between HTTP routes in a traditional web framework.
-
#route(handlers : Hash(String, AcceptableMiddleware), fallback : AcceptableMiddleware = Composer.pass, &router : RouterFn)
This allows you to branch between different middleware per context object in much the same way you would branch between HTTP routes in a traditional web framework.
-
#run(middleware : Middleware, context : Context)
Run the given
#middleware
with the givencontext
. -
#use(middleware : Array(AcceptableMiddleware))
Register the given
#middleware
with the current Composer. -
#use(*middleware : AcceptableMiddleware)
Register the given
#middleware
with the current Composer. -
#use(&proc : MiddlewareFn)
Register the given
#middleware
with the current Composer.
Constructor Detail
Create a new Composer
with the given middleware
Class Method Detail
Instance Method Detail
Allows you to branch between two cases for a given context object.
This method takes a predicate function and two middleware. If the predicate
returns true, true_mw
will be called, otherwise false_mw
will be called.
!!! note This is a more advanced function and is not needed for most use cases.
Allows you to branch between two cases for a given context object.
This method takes a predicate function and two middleware. If the predicate
returns true, true_mw
will be called, otherwise false_mw
will be called.
!!! note This is a more advanced function and is not needed for most use cases.
Registers some middleware for callback queries (updates that Telegram sends when a user clicks on a button in an inline keyboard).
This is essentially the same as calling:
bot.on(:callback_query) { |ctx| ... }
but it also allows you to match the query data against a given string or regular expression.
# Create an inline keyboard
kb = Telegram::InlineKeyboardMarkup.new.text("Go!", "button-payload")
# Send a message with the keyboard
bot.api.send_message(chat_id, "Press a button!", reply_markup: kb)
# Listen for a button press with that specific payload
bot.callback_query("button-payload") { |ctx| ... }
!!! note
Always remember to call answer_callback_query
, even if you don't do anything
with it.
crystal bot.callback_query("button-payload") do |ctx| ctx.answer_callback_query end
If you pass an array of triggers, your middleware will be called when at least one of them matches.
Registers some middleware for callback queries (updates that Telegram sends when a user clicks on a button in an inline keyboard).
This is essentially the same as calling:
bot.on(:callback_query) { |ctx| ... }
but it also allows you to match the query data against a given string or regular expression.
# Create an inline keyboard
kb = Telegram::InlineKeyboardMarkup.new.text("Go!", "button-payload")
# Send a message with the keyboard
bot.api.send_message(chat_id, "Press a button!", reply_markup: kb)
# Listen for a button press with that specific payload
bot.callback_query("button-payload") { |ctx| ... }
!!! note
Always remember to call answer_callback_query
, even if you don't do anything
with it.
crystal bot.callback_query("button-payload") do |ctx| ctx.answer_callback_query end
If you pass an array of triggers, your middleware will be called when at least one of them matches.
Registers some middleware for callback queries (updates that Telegram sends when a user clicks on a button in an inline keyboard).
This is essentially the same as calling:
bot.on(:callback_query) { |ctx| ... }
but it also allows you to match the query data against a given string or regular expression.
# Create an inline keyboard
kb = Telegram::InlineKeyboardMarkup.new.text("Go!", "button-payload")
# Send a message with the keyboard
bot.api.send_message(chat_id, "Press a button!", reply_markup: kb)
# Listen for a button press with that specific payload
bot.callback_query("button-payload") { |ctx| ... }
!!! note
Always remember to call answer_callback_query
, even if you don't do anything
with it.
crystal bot.callback_query("button-payload") do |ctx| ctx.answer_callback_query end
If you pass an array of triggers, your middleware will be called when at least one of them matches.
Registers a middleware that will be called when a certain command is found:
# reacts to `/start` commands
bot.command("start") { |ctx| ... }
# reacts to `/help` commands
bot.command("help") { |ctx| ... }
The rest of the text is provided as ctx.match
.
!!! note
Commands are only matched at the beginning of a message. To match a command
inside of a message you could use bot.on(:bot_command)
in conjunction with
the #hears
handler.
!!! note
By default commands are detected in channel posts too, which means
ctx.message
may be undefined. You should always use ctx.msg
instead to
grab both group and channel messages.
Registers a middleware that will be called when a certain command is found:
# reacts to `/start` commands
bot.command("start") { |ctx| ... }
# reacts to `/help` commands
bot.command("help") { |ctx| ... }
The rest of the text is provided as ctx.match
.
!!! note
Commands are only matched at the beginning of a message. To match a command
inside of a message you could use bot.on(:bot_command)
in conjunction with
the #hears
handler.
!!! note
By default commands are detected in channel posts too, which means
ctx.message
may be undefined. You should always use ctx.msg
instead to
grab both group and channel messages.
Registers a middleware that will be called when a certain command is found:
# reacts to `/start` commands
bot.command("start") { |ctx| ... }
# reacts to `/help` commands
bot.command("help") { |ctx| ... }
The rest of the text is provided as ctx.match
.
!!! note
Commands are only matched at the beginning of a message. To match a command
inside of a message you could use bot.on(:bot_command)
in conjunction with
the #hears
handler.
!!! note
By default commands are detected in channel posts too, which means
ctx.message
may be undefined. You should always use ctx.msg
instead to
grab both group and channel messages.
Registers middleware behind a custom filter function that operates on the context object and
determines whether or not to contuinue middleware execution. In other words, the middleware following
this one in a chain will only be called if the filter function returns false
. This is functionally
the opposite of Composer#filter
.
my_filter = ->(ctx : Context) { ctx.text == "hello" }
bot.on(:text).drop(my_filter) do |ctx|
# Will only be called if `ctx.text` is not "hello"
# ...
end
!!! note This is a more advanced function and is not needed for most use cases.
Registers middleware behind a custom filter function that operates on the context object and
determines whether or not to contuinue middleware execution. In other words, the middleware following
this one in a chain will only be called if the filter function returns false
. This is functionally
the opposite of Composer#filter
.
my_filter = ->(ctx : Context) { ctx.text == "hello" }
bot.on(:text).drop(my_filter) do |ctx|
# Will only be called if `ctx.text` is not "hello"
# ...
end
!!! note This is a more advanced function and is not needed for most use cases.
Installs an error boundary that catches errors that happen inside the given middleware. This allows you to insert custom error handlers into the pipeline for some parts of your bot, while leaving others untouched.
error_handler = ->(err : BotError) do
puts "Error boundary caught error!"
puts err
end
# All passed middleware will be protected by the error boundary.
safe = bot.error_boundary(error_handler, middleware0, middleware1, middleware2)
# This will also be protected
safe.on(:message, middleware3)
# No error from middleware4 will reach the `error_handler` from above.
Do nothing on error, and run outside middleware
suppress = ->(err : BotError) { }
safe.error_boundary(suppress).on(:edited_message, middleware4)
Installs an error boundary that catches errors that happen inside the given middleware. This allows you to insert custom error handlers into the pipeline for some parts of your bot, while leaving others untouched.
error_handler = ->(err : BotError) do
puts "Error boundary caught error!"
puts err
end
# All passed middleware will be protected by the error boundary.
safe = bot.error_boundary(error_handler, middleware0, middleware1, middleware2)
# This will also be protected
safe.on(:message, middleware3)
# No error from middleware4 will reach the `error_handler` from above.
Do nothing on error, and run outside middleware
suppress = ->(err : BotError) { }
safe.error_boundary(suppress).on(:edited_message, middleware4)
Installs an error boundary that catches errors that happen inside the given middleware. This allows you to insert custom error handlers into the pipeline for some parts of your bot, while leaving others untouched.
error_handler = ->(err : BotError) do
puts "Error boundary caught error!"
puts err
end
# All passed middleware will be protected by the error boundary.
safe = bot.error_boundary(error_handler, middleware0, middleware1, middleware2)
# This will also be protected
safe.on(:message, middleware3)
# No error from middleware4 will reach the `error_handler` from above.
Do nothing on error, and run outside middleware
suppress = ->(err : BotError) { }
safe.error_boundary(suppress).on(:edited_message, middleware4)
Registers middleware behind a custom filter function that operates on the context object and
determines whether or not to contuinue middleware execution. In other words, the middleware following
this one in a chain will only be called if the filter function returns true
.
my_filter = ->(ctx : Context) { ctx.text == "hello" }
bot.on(:text).filter(my_filter) do |ctx|
# Will only be called if `ctx.text` is "hello"
# ...
end
!!! note This is a more advanced function and is not needed for most use cases.
Registers middleware behind a custom filter function that operates on the context object and
determines whether or not to contuinue middleware execution. In other words, the middleware following
this one in a chain will only be called if the filter function returns true
.
my_filter = ->(ctx : Context) { ctx.text == "hello" }
bot.on(:text).filter(my_filter) do |ctx|
# Will only be called if `ctx.text` is "hello"
# ...
end
!!! note This is a more advanced function and is not needed for most use cases.
Registers middleware behind a custom filter function that operates on the context object and
determines whether or not to contuinue middleware execution. In other words, the middleware following
this one in a chain will only be called if the filter function returns true
.
my_filter = ->(ctx : Context) { ctx.text == "hello" }
bot.on(:text).filter(my_filter) do |ctx|
# Will only be called if `ctx.text` is "hello"
# ...
end
!!! note This is a more advanced function and is not needed for most use cases.
Registers middleware behind a custom filter function that operates on the context object and
determines whether or not to contuinue middleware execution. In other words, the middleware following
this one in a chain will only be called if the filter function returns true
.
my_filter = ->(ctx : Context) { ctx.text == "hello" }
bot.on(:text).filter(my_filter) do |ctx|
# Will only be called if `ctx.text` is "hello"
# ...
end
!!! note This is a more advanced function and is not needed for most use cases.
Registers some middleware that run concurrently with other middleware in the stack.
bot.use(...) # Will run first
bot.fork(...) # Will start second, but will run in the background
bot.use(...) # Will also run second
Forking is functionally the same as running your middleware in a spawn
block, but
also applies to all the middleware that follow it in the chain.
Registers some middleware that run concurrently with other middleware in the stack.
bot.use(...) # Will run first
bot.fork(...) # Will start second, but will run in the background
bot.use(...) # Will also run second
Forking is functionally the same as running your middleware in a spawn
block, but
also applies to all the middleware that follow it in the chain.
Registers some middleware that run concurrently with other middleware in the stack.
bot.use(...) # Will run first
bot.fork(...) # Will start second, but will run in the background
bot.use(...) # Will also run second
Forking is functionally the same as running your middleware in a spawn
block, but
also applies to all the middleware that follow it in the chain.
Registers some middleware for game queries (updates that Telegram sends when a user clicks an inline button to launch an HTML5 game).
This is functionally the same as Composer#callback_query
, but it only matches
when a game_short_name
is provided.
Registers some middleware for game queries (updates that Telegram sends when a user clicks an inline button to launch an HTML5 game).
This is functionally the same as Composer#callback_query
, but it only matches
when a game_short_name
is provided.
Registers some middleware for game queries (updates that Telegram sends when a user clicks an inline button to launch an HTML5 game).
This is functionally the same as Composer#callback_query
, but it only matches
when a game_short_name
is provided.
Registers a #middleware
that is executed when the message contains a specific pattern.
You can use either a regular expression, a string, or an array containing either:
# Match some exact text
bot.hears("Crystal is great") { |ctx| ... }
# Match a regular expression
bot.hears(/crystal/i) { |ctx| ... }
Passing multiple filters in an array works as an OR
, while chaining multiple #on
calls together works as an AND
.
Registers a #middleware
that is executed when the message contains a specific pattern.
You can use either a regular expression, a string, or an array containing either:
# Match some exact text
bot.hears("Crystal is great") { |ctx| ... }
# Match a regular expression
bot.hears(/crystal/i) { |ctx| ... }
Passing multiple filters in an array works as an OR
, while chaining multiple #on
calls together works as an AND
.
Registers a #middleware
that is executed when the message contains a specific pattern.
You can use either a regular expression, a string, or an array containing either:
# Match some exact text
bot.hears("Crystal is great") { |ctx| ... }
# Match a regular expression
bot.hears(/crystal/i) { |ctx| ... }
Passing multiple filters in an array works as an OR
, while chaining multiple #on
calls together works as an AND
.
Registers some middleware for inline queries (updates that Telegram sends when a user types "@YourBotName ..." into a text field). Your bot will receive the inline query and can respond with a number of different results. Check out https://core.telegram.org/bots/inline to read more about inline queries.
!!! note You have to enable inline mode in @BotFather
bot.inline_query("query") do |ctx|
# Answer the inline query, confer https://core.telegram.org/bots/api#answerinlinequery
ctx.answer_inline_query(...)
end
Registers some middleware for inline queries (updates that Telegram sends when a user types "@YourBotName ..." into a text field). Your bot will receive the inline query and can respond with a number of different results. Check out https://core.telegram.org/bots/inline to read more about inline queries.
!!! note You have to enable inline mode in @BotFather
bot.inline_query("query") do |ctx|
# Answer the inline query, confer https://core.telegram.org/bots/api#answerinlinequery
ctx.answer_inline_query(...)
end
Registers some middleware for inline queries (updates that Telegram sends when a user types "@YourBotName ..." into a text field). Your bot will receive the inline query and can respond with a number of different results. Check out https://core.telegram.org/bots/inline to read more about inline queries.
!!! note You have to enable inline mode in @BotFather
bot.inline_query("query") do |ctx|
# Answer the inline query, confer https://core.telegram.org/bots/api#answerinlinequery
ctx.answer_inline_query(...)
end
Executes some middleware that are generated on the fly for each context. Pass a factory function which generates a middleware (or an array of middleware) for the given context.
bot.lazy { |ctx| create_some_middleware(ctx) }
You can also return an empty array ([] of Middleware
) if you don't want to
run any middleware for the given context. This is the same as returning an
empty Composer
object.
!!! note This is a more advanced function and is not needed for most use cases.
Executes some middleware that are generated on the fly for each context. Pass a factory function which generates a middleware (or an array of middleware) for the given context.
bot.lazy { |ctx| create_some_middleware(ctx) }
You can also return an empty array ([] of Middleware
) if you don't want to
run any middleware for the given context. This is the same as returning an
empty Composer
object.
!!! note This is a more advanced function and is not needed for most use cases.
Registers #middleware
that will only be executed when certain UpdateAction
s are
included in an update. The #filter
specifies which actions you want to act on.
For example:
# All message updates
bot.on(:message) { |ctx| ... }
# Only messages containing text or a caption
bot.on([:text, :caption]) { |ctx| ... }
# Only text messages with a URL
bot.on(:text).on(:url) { |ctx| ... }
# Messages containing a photo
bot.on(:photo) { |ctx| ... }
As can be seen in the above example, passing multiple filters in an array works
as an OR
, while chaining multiple #on
calls together works as an AND
.
Registers #middleware
that will only be executed when certain UpdateAction
s are
included in an update. The #filter
specifies which actions you want to act on.
For example:
# All message updates
bot.on(:message) { |ctx| ... }
# Only messages containing text or a caption
bot.on([:text, :caption]) { |ctx| ... }
# Only text messages with a URL
bot.on(:text).on(:url) { |ctx| ... }
# Messages containing a photo
bot.on(:photo) { |ctx| ... }
As can be seen in the above example, passing multiple filters in an array works
as an OR
, while chaining multiple #on
calls together works as an AND
.
Registers #middleware
that will only be executed when certain UpdateAction
s are
included in an update. The #filter
specifies which actions you want to act on.
For example:
# All message updates
bot.on(:message) { |ctx| ... }
# Only messages containing text or a caption
bot.on([:text, :caption]) { |ctx| ... }
# Only text messages with a URL
bot.on(:text).on(:url) { |ctx| ... }
# Messages containing a photo
bot.on(:photo) { |ctx| ... }
As can be seen in the above example, passing multiple filters in an array works
as an OR
, while chaining multiple #on
calls together works as an AND
.
This allows you to branch between different middleware per context object in much the same way you would branch between HTTP routes in a traditional web framework. You can pass three things to it:
- a routing function.
- a hash of handlers.
- a fallback middleware.
The routing function decides based on the context object what middleware to run. Each middleware is idenfied by a key, so the routing function simply returns the key of the middleware to run.
route_handlers = {
"even_updates" => ->(ctx : Context) { ... },
"odd_updates" => ->(ctx : Context) { ... },
}
router = ->(ctx : Telegram::Context) do
if ctx.update.update_id.even?
"even_updates"
else
"odd_updates"
end
end
bot.route(router, route_handlers)
If a fallback is provided as a third argument, it will be run if the routing
function returns nil
or if the provided key doesn't match.
This allows you to branch between different middleware per context object in much the same way you would branch between HTTP routes in a traditional web framework. You can pass three things to it:
- a routing function.
- a hash of handlers.
- a fallback middleware.
The routing function decides based on the context object what middleware to run. Each middleware is idenfied by a key, so the routing function simply returns the key of the middleware to run.
route_handlers = {
"even_updates" => ->(ctx : Context) { ... },
"odd_updates" => ->(ctx : Context) { ... },
}
router = ->(ctx : Telegram::Context) do
if ctx.update.update_id.even?
"even_updates"
else
"odd_updates"
end
end
bot.route(router, route_handlers)
If a fallback is provided as a third argument, it will be run if the routing
function returns nil
or if the provided key doesn't match.
Run the given #middleware
with the given context
.
Register the given #middleware
with the current Composer. Registered middleware
reveive all updates and are contactenated into a single Middleware
.
This can be used to easily register new plugins:
bot.use(SomeTelegramPlugin.new)
This returns a new instance of Composer
which can be further extended.
Register the given #middleware
with the current Composer. Registered middleware
reveive all updates and are contactenated into a single Middleware
.
This can be used to easily register new plugins:
bot.use(SomeTelegramPlugin.new)
This returns a new instance of Composer
which can be further extended.
Register the given #middleware
with the current Composer. Registered middleware
reveive all updates and are contactenated into a single Middleware
.
This can be used to easily register new plugins:
bot.use(SomeTelegramPlugin.new)
This returns a new instance of Composer
which can be further extended.