зеркало из
https://github.com/glebtv/telegram-bot.git
synced 2026-09-04 18:25:51 +03:00
v0.1.0
Этот коммит содержится в:
105
lib/telegram/bot/updates_controller.rb
Обычный файл
105
lib/telegram/bot/updates_controller.rb
Обычный файл
@@ -0,0 +1,105 @@
|
||||
require 'abstract_controller'
|
||||
require 'active_support/callbacks'
|
||||
|
||||
module Telegram
|
||||
class Bot
|
||||
class UpdatesController < AbstractController::Base
|
||||
include AbstractController::Callbacks
|
||||
include AbstractController::Translation
|
||||
|
||||
require 'telegram/bot/updates_controller/log_subscriber'
|
||||
require 'telegram/bot/updates_controller/instrumentation'
|
||||
prepend Instrumentation
|
||||
|
||||
PAYLOAD_TYPES = %w(
|
||||
message
|
||||
inline_query
|
||||
chosen_inline_result
|
||||
).freeze
|
||||
CMD_REGEX = %r{\A/([a-z\d_]{,31})(@(\S+))?(\s|$)}i
|
||||
CONFLICT_CMD_REGEX = Regexp.new("^(#{PAYLOAD_TYPES.join('|')}|\\d)")
|
||||
abstract!
|
||||
|
||||
class << self
|
||||
def dispatch(*args)
|
||||
new(*args).dispatch
|
||||
end
|
||||
|
||||
# Overrid it to filter or transform commands.
|
||||
# Default implementation is to convert to downcase and add `on_` prefix
|
||||
# for conflicting commands.
|
||||
def action_for_command(cmd)
|
||||
cmd.downcase!
|
||||
cmd.match(CONFLICT_CMD_REGEX) ? "on_#{cmd}" : cmd
|
||||
end
|
||||
|
||||
# Fetches command from text message. All subsequent words are returned
|
||||
# as arguments.
|
||||
# If command has mention (eg. `/test@SomeBot`), it returns commands only
|
||||
# for specified username. Set `username` to `true` to accept
|
||||
# any commands.
|
||||
def command_from_text(text, username = nil)
|
||||
return unless text
|
||||
match = text.match CMD_REGEX
|
||||
return unless match
|
||||
return if match[3] && username != true && match[3] != username
|
||||
[match[1], text.split(' ').drop(1)]
|
||||
end
|
||||
end
|
||||
|
||||
attr_internal_reader :update, :bot, :payload, :payload_type, :is_command
|
||||
alias_method :command?, :is_command
|
||||
delegate :username, to: :bot, prefix: true, allow_nil: true
|
||||
|
||||
def initialize(bot = nil, update = nil)
|
||||
@_update = update
|
||||
@_bot = bot
|
||||
|
||||
update && PAYLOAD_TYPES.find do |type|
|
||||
item = update[type]
|
||||
next unless item
|
||||
@_payload = item
|
||||
@_payload_type = type
|
||||
end
|
||||
end
|
||||
|
||||
def dispatch
|
||||
@_is_command, action, args = action_for_payload
|
||||
process(action, *args)
|
||||
end
|
||||
|
||||
# Calculates action name and args for payload.
|
||||
# If payload is a message with command, then returned action is an
|
||||
# action for this command. Otherwise it's the same as payload type.
|
||||
# Returns array `[is_command?, action, args]`.
|
||||
def action_for_payload
|
||||
case payload_type
|
||||
when 'message'
|
||||
cmd, args = self.class.command_from_text(payload['text'], bot_username)
|
||||
cmd &&= self.class.action_for_command(cmd)
|
||||
[true, cmd, args] if cmd
|
||||
end || [false, payload_type, [payload]]
|
||||
end
|
||||
|
||||
# Silently ignore unsupported messages.
|
||||
# Params are `action, *args`.
|
||||
def action_missing(*)
|
||||
end
|
||||
|
||||
%w(chat from).each do |field|
|
||||
define_method(field) { payload[field] }
|
||||
end
|
||||
|
||||
def reply_with(type, params)
|
||||
method = "send_#{type}"
|
||||
params = params.merge(
|
||||
chat_id: chat['id'],
|
||||
reply_to_message: payload['message_id'],
|
||||
)
|
||||
bot.public_send(method, params)
|
||||
end
|
||||
|
||||
ActiveSupport.run_load_hooks('telegram.bot.updates_controller', self)
|
||||
end
|
||||
end
|
||||
end
|
||||
Ссылка в новой задаче
Block a user