lib/telegram/bot/updates_controller.rb in telegram-bot-0.16.1 vs lib/telegram/bot/updates_controller.rb in telegram-bot-0.16.3
- old
+ new
@@ -1,5 +1,7 @@
+# frozen_string_literal: true
+
require 'abstract_controller'
require 'active_support/core_ext/string/inflections'
require 'active_support/callbacks'
require 'active_support/version'
@@ -45,11 +47,11 @@
# There is also ability to run action without update:
#
# ControllerClass.new(bot, from: telegram_user, chat: telegram_chat).
# process(:help, *args)
#
- class UpdatesController < AbstractController::Base # rubocop:disable ClassLength
+ class UpdatesController < AbstractController::Base # rubocop:disable Metrics/ClassLength
abstract!
%w[
Commands
Instrumentation
@@ -67,16 +69,16 @@
].each { |mod| autoload mod, "telegram/bot/updates_controller/#{mod.underscore}" }
include AbstractController::Callbacks
# Redefine callbacks with default terminator.
if ActiveSupport::VERSION::MAJOR >= 5
- define_callbacks :process_action,
- skip_after_callbacks_if_terminated: true
+ define_callbacks :process_action,
+ skip_after_callbacks_if_terminated: true
else
- define_callbacks :process_action,
- terminator: ->(_, result) { result == false },
- skip_after_callbacks_if_terminated: true
+ define_callbacks :process_action,
+ terminator: ->(_, result) { result == false },
+ skip_after_callbacks_if_terminated: true
end
include Commands
include Rescue
include ReplyHelpers
@@ -85,80 +87,109 @@
# all the methods properly.
include Instrumentation
extend Session::ConfigMethods
- PAYLOAD_TYPES = %w[
+ PAYLOAD_TYPES = Set.new(%w[
message
edited_message
channel_post
edited_channel_post
+ business_connection
+ business_message
+ edited_business_message
+ deleted_business_messages
+ message_reaction
+ message_reaction_count
inline_query
chosen_inline_result
callback_query
shipping_query
pre_checkout_query
poll
poll_answer
my_chat_member
chat_member
chat_join_request
- ].freeze
+ chat_boost
+ removed_chat_boost
+ pre_checkout_query
+ ].freeze)
class << self
# Initialize controller and process update.
def dispatch(*args)
new(*args).dispatch
end
def payload_from_update(update)
- update && PAYLOAD_TYPES.find do |type|
- item = update[type]
- return [item, type] if item
+ case update
+ when nil then nil
+ when Hash
+ # faster lookup for the case when telegram-bot-types is not used
+ update.find do |type, item|
+ return [item, type] if PAYLOAD_TYPES.include?(type)
+ end
+ else
+ payload_from_typed_update(update)
end
end
+
+ private
+
+ def payload_from_typed_update(update)
+ PAYLOAD_TYPES.find do |type|
+ begin
+ item = update[type]
+ return [item, type] if item
+ rescue Exception # rubocop:disable Lint/RescueException
+ # dry-rb raises exception if field is not defined in schema
+ end
+ end
+ end
end
attr_internal_reader :bot, :payload, :payload_type, :update, :webhook_request
delegate :username, to: :bot, prefix: true, allow_nil: true
# `update` can be either update object with hash access & string
# keys or Hash with `:from` or `:chat` to override this values and assume
# that update is nil.
# ActionDispatch::Request object is passed in `webhook_request` when bot running
# in webhook mode.
- def initialize(bot = nil, update = nil, webhook_request = nil)
+ def initialize(bot = nil, update = nil, webhook_request = nil) # rubocop:disable Lint/MissingSuper
if update.is_a?(Hash) && (update.key?(:from) || update.key?(:chat))
options = update
update = nil
end
@_bot = bot
@_update = update
- @_chat, @_from = options && options.values_at(:chat, :from)
+ @_chat, @_from = options&.values_at(:chat, :from)
@_payload, @_payload_type = self.class.payload_from_update(update)
@_webhook_request = webhook_request
end
# Accessor to `'chat'` field of payload. Also tries `'chat'` in `'message'`
# when there is no such field in payload.
#
# Can be overriden with `chat` option for #initialize.
- def chat
- @_chat ||=
+ def chat # rubocop:disable Metrics/PerceivedComplexity
+ @_chat ||= # rubocop:disable Naming/MemoizedInstanceVariableName
if payload
if payload.is_a?(Hash)
- payload['chat'] || payload['message'] && payload['message']['chat']
+ payload['chat'] || (payload['message'] && payload['message']['chat'])
else
- payload.try(:chat) || payload.try(:message).try!(:chat)
+ payload.try(:chat) || payload.try(:message)&.chat
end
end
end
# Accessor to `'from'` field of payload. Can be overriden with `from` option
# for #initialize.
def from
- @_from ||= payload.is_a?(Hash) ? payload['from'] : payload.try(:from)
+ @_from ||= # rubocop:disable Naming/MemoizedInstanceVariableName
+ payload.is_a?(Hash) ? payload['from'] : payload.try(:from)
end
# Processes current update.
def dispatch
action, args = action_for_payload
@@ -219,10 +250,10 @@
end
# Silently ignore unsupported messages to not fail when user crafts
# an update with usupported command, callback query context, etc.
def action_missing(action, *_args)
- logger.debug { "The action '#{action}' is not defined in #{self.class.name}" } if logger
+ logger&.debug { "The action '#{action}' is not defined in #{self.class.name}" }
nil
end
PAYLOAD_TYPES.each do |type|
method = :"action_for_#{type}"