зеркало из
https://github.com/glebtv/telegram-bot.git
synced 2026-09-03 17:55:52 +03:00
Drop .context_handler, .context_to_action! methods
Этот коммит содержится в:
@@ -2,51 +2,35 @@ module Telegram
|
||||
module Bot
|
||||
class UpdatesController
|
||||
# Allows to store context in session and treat next message according to this context.
|
||||
#
|
||||
# It provides `save_context` method to store method name
|
||||
# to be used as action for next update:
|
||||
#
|
||||
# def set_location!(*)
|
||||
# save_context(:set_location_from_message)
|
||||
# respond_with :message, text: 'Where are you?'
|
||||
# end
|
||||
#
|
||||
# def set_location_from_messge(city = nil, *)
|
||||
# # update
|
||||
# end
|
||||
#
|
||||
# # OR
|
||||
# # This will support both `/set_location city_name`, and `/set_location`
|
||||
# # with subsequent refinement.
|
||||
# def set_location!(city = nil, *)
|
||||
# if city
|
||||
# # update
|
||||
# else
|
||||
# save_context(:set_location!)
|
||||
# respond_with :message, text: 'Where are you?'
|
||||
# end
|
||||
# end
|
||||
module MessageContext
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
include Session
|
||||
|
||||
module ClassMethods
|
||||
def context_handlers
|
||||
@_context_handlers ||= {}
|
||||
end
|
||||
|
||||
# Registers handler for context.
|
||||
#
|
||||
# context_handler :rename do |*|
|
||||
# resource.update!(name: payload['text'])
|
||||
# end
|
||||
#
|
||||
# # To run other action with all the callbacks:
|
||||
# context_handler :rename do |*words|
|
||||
# process(:rename, *words)
|
||||
# end
|
||||
#
|
||||
# # Or just
|
||||
# context_handler :rename, :your_action_to_call
|
||||
# context_handler :rename # to call :rename
|
||||
#
|
||||
def context_handler(context = nil, action = nil, &block)
|
||||
context &&= context.to_sym
|
||||
if block
|
||||
action = "_context_handler_#{context}"
|
||||
define_method(action, &block)
|
||||
end
|
||||
context_handlers[context] = action || context
|
||||
end
|
||||
|
||||
attr_reader :context_to_action
|
||||
|
||||
# Use it to use context value as action name for all contexts
|
||||
# which miss handlers.
|
||||
# For security reasons it supports only action methods and will
|
||||
# raise AbstractController::ActionNotFound if context is invalid.
|
||||
def context_to_action!
|
||||
@context_to_action = true
|
||||
end
|
||||
end
|
||||
|
||||
# Action to clear context.
|
||||
def cancel!
|
||||
# Context is already cleared in action_for_message
|
||||
@@ -54,10 +38,6 @@ module Telegram
|
||||
|
||||
private
|
||||
|
||||
# Context is read from the session to treat messages
|
||||
# according to previous request.
|
||||
attr_reader :context
|
||||
|
||||
# Controller may have multiple sessions, let it be possible
|
||||
# to select session for message context.
|
||||
def message_context_session
|
||||
@@ -68,13 +48,11 @@ module Telegram
|
||||
# it has higher priority than contextual action.
|
||||
def action_for_message
|
||||
val = message_context_session.delete(:context)
|
||||
@context = val && val.to_sym
|
||||
context = val && val.to_s
|
||||
super || context && begin
|
||||
handler = handler_for_context
|
||||
if handler
|
||||
action_options = {type: :message_context, context: context}
|
||||
[[handler, action_options], payload['text'].try!(:split) || []]
|
||||
end
|
||||
args = payload['text'].try!(:split) || []
|
||||
action = action_for_message_context(context)
|
||||
[[action, type: :message_context, context: context], args]
|
||||
end
|
||||
end
|
||||
|
||||
@@ -83,18 +61,16 @@ module Telegram
|
||||
message_context_session[:context] = context
|
||||
end
|
||||
|
||||
def handler_for_context
|
||||
self.class.context_handlers[context] || self.class.context_to_action && begin
|
||||
action_name = context.to_s
|
||||
unless action_method?(action_name)
|
||||
raise AbstractController::ActionNotFound,
|
||||
"The action '#{action_name}' could not be set from context " \
|
||||
"for #{self.class.name}. " \
|
||||
'context_to_action! supports only action methods for security reasons. ' \
|
||||
'If you need to call this action use context_handler for it.'
|
||||
end
|
||||
action_name
|
||||
end
|
||||
# Returns action name for message context. By default it's the same as context name.
|
||||
# Raises AbstractController::ActionNotFound if action is not available.
|
||||
# This differs from other cases where invalid actions are silently ignored,
|
||||
# because message context is controlled by developer, and users are not able
|
||||
# to construct update to run any specific context.
|
||||
def action_for_message_context(context)
|
||||
action = context.to_s
|
||||
return action if action_method?(action)
|
||||
raise AbstractController::ActionNotFound,
|
||||
"The context action '#{action}' is not found in #{self.class.name}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Ссылка в новой задаче
Block a user