зеркало из
https://github.com/glebtv/telegram-bot.git
synced 2026-09-07 11:25:52 +03:00
New api methods and support for inline keyboards
Этот коммит содержится в:
@@ -1,3 +1,8 @@
|
|||||||
|
# 0.7.0 Unreleased
|
||||||
|
|
||||||
|
- New Bot API methods.
|
||||||
|
- Helpers for inline keyboards.
|
||||||
|
|
||||||
# 0.6.0
|
# 0.6.0
|
||||||
|
|
||||||
- StaleChat error.
|
- StaleChat error.
|
||||||
|
|||||||
@@ -68,22 +68,27 @@ module Telegram
|
|||||||
end
|
end
|
||||||
|
|
||||||
%w(
|
%w(
|
||||||
|
answerCallbackQuery
|
||||||
answerInlineQuery
|
answerInlineQuery
|
||||||
forwardMessage
|
forwardMessage
|
||||||
getFile
|
getFile
|
||||||
getMe
|
getMe
|
||||||
getUpdates
|
getUpdates
|
||||||
getUserProfilePhotos
|
getUserProfilePhotos
|
||||||
|
kickChatMember
|
||||||
sendAudio
|
sendAudio
|
||||||
sendChatAction
|
sendChatAction
|
||||||
|
sendContact
|
||||||
sendDocument
|
sendDocument
|
||||||
sendLocation
|
sendLocation
|
||||||
sendMessage
|
sendMessage
|
||||||
sendPhoto
|
sendPhoto
|
||||||
sendSticker
|
sendSticker
|
||||||
|
sendVenue
|
||||||
sendVideo
|
sendVideo
|
||||||
sendVoice
|
sendVoice
|
||||||
setWebhook
|
setWebhook
|
||||||
|
unbanChatMember
|
||||||
).each do |method|
|
).each do |method|
|
||||||
define_method(method.underscore) { |*args| request(method, *args) }
|
define_method(method.underscore) { |*args| request(method, *args) }
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ module Telegram
|
|||||||
require 'telegram/bot/updates_controller/session'
|
require 'telegram/bot/updates_controller/session'
|
||||||
require 'telegram/bot/updates_controller/log_subscriber'
|
require 'telegram/bot/updates_controller/log_subscriber'
|
||||||
require 'telegram/bot/updates_controller/instrumentation'
|
require 'telegram/bot/updates_controller/instrumentation'
|
||||||
|
require 'telegram/bot/updates_controller/reply_helpers'
|
||||||
autoload :MessageContext, 'telegram/bot/updates_controller/message_context'
|
autoload :MessageContext, 'telegram/bot/updates_controller/message_context'
|
||||||
autoload :Botan, 'telegram/bot/updates_controller/botan'
|
autoload :Botan, 'telegram/bot/updates_controller/botan'
|
||||||
|
|
||||||
@@ -71,6 +72,7 @@ module Telegram
|
|||||||
end
|
end
|
||||||
|
|
||||||
include AbstractController::Translation
|
include AbstractController::Translation
|
||||||
|
include ReplyHelpers
|
||||||
prepend Instrumentation
|
prepend Instrumentation
|
||||||
extend Session::ConfigMethods
|
extend Session::ConfigMethods
|
||||||
|
|
||||||
@@ -80,6 +82,7 @@ module Telegram
|
|||||||
message
|
message
|
||||||
inline_query
|
inline_query
|
||||||
chosen_inline_result
|
chosen_inline_result
|
||||||
|
callback_query
|
||||||
).freeze
|
).freeze
|
||||||
CMD_REGEX = %r{\A/([a-z\d_]{,31})(@(\S+))?(\s|$)}i
|
CMD_REGEX = %r{\A/([a-z\d_]{,31})(@(\S+))?(\s|$)}i
|
||||||
CONFLICT_CMD_REGEX = Regexp.new("^(#{PAYLOAD_TYPES.join('|')}|\\d)")
|
CONFLICT_CMD_REGEX = Regexp.new("^(#{PAYLOAD_TYPES.join('|')}|\\d)")
|
||||||
@@ -161,46 +164,27 @@ module Telegram
|
|||||||
def action_for_payload
|
def action_for_payload
|
||||||
case payload_type
|
case payload_type
|
||||||
when 'message' then action_for_message
|
when 'message' then action_for_message
|
||||||
|
when 'callback_query' then action_for_callback_query
|
||||||
end || [false, payload_type, [payload]]
|
end || [false, payload_type, [payload]]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Separate method, so it can be easily overriden (ex. MessageContext).
|
||||||
def action_for_message
|
def action_for_message
|
||||||
cmd, args = self.class.command_from_text(payload['text'], bot_username)
|
cmd, args = self.class.command_from_text(payload['text'], bot_username)
|
||||||
cmd &&= self.class.action_for_command(cmd)
|
cmd &&= self.class.action_for_command(cmd)
|
||||||
[true, cmd, args] if cmd
|
[true, cmd, args] if cmd
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Same purpose as #action_for_message.
|
||||||
|
def action_for_callback_query
|
||||||
|
[false, payload_type, [payload]]
|
||||||
|
end
|
||||||
|
|
||||||
# Silently ignore unsupported messages.
|
# Silently ignore unsupported messages.
|
||||||
# Params are `action, *args`.
|
# Params are `action, *args`.
|
||||||
def action_missing(*)
|
def action_missing(*)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Helper to call bot's `send_#{type}` method with already set `chat_id` and
|
|
||||||
# `reply_to_message_id`:
|
|
||||||
#
|
|
||||||
# reply_with :message, text: 'Hello!'
|
|
||||||
# reply_with :message, text: '__Hello!__', parse_mode: :Markdown
|
|
||||||
# reply_with :photo, photo: File.open(photo_to_send), caption: "It's incredible!"
|
|
||||||
def reply_with(type, params)
|
|
||||||
method = "send_#{type}"
|
|
||||||
chat = self.chat
|
|
||||||
payload = self.payload
|
|
||||||
params = params.merge(
|
|
||||||
chat_id: (chat && chat['id'] or raise 'Can not reply_with when chat is not present'),
|
|
||||||
reply_to_message: payload && payload['message_id'],
|
|
||||||
)
|
|
||||||
bot.public_send(method, params)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Same as reply_with, but for inline queries.
|
|
||||||
def answer_inline_query(results, params = {})
|
|
||||||
params = params.merge(
|
|
||||||
inline_query_id: payload['id'],
|
|
||||||
results: results,
|
|
||||||
)
|
|
||||||
bot.answer_inline_query(params)
|
|
||||||
end
|
|
||||||
|
|
||||||
ActiveSupport.run_load_hooks('telegram.bot.updates_controller', self)
|
ActiveSupport.run_load_hooks('telegram.bot.updates_controller', self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -39,6 +39,12 @@ module Telegram
|
|||||||
Instrumentation.instrument(:reply_with, type: type) { super }
|
Instrumentation.instrument(:reply_with, type: type) { super }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
%i(answer_callback_query answer_inline_query).each do |type|
|
||||||
|
define_method(type) do |*args|
|
||||||
|
Instrumentation.instrument(:reply_with, type: type) { super(*args) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# A hook invoked every time a before callback is halted.
|
# A hook invoked every time a before callback is halted.
|
||||||
|
|||||||
42
lib/telegram/bot/updates_controller/reply_helpers.rb
Обычный файл
42
lib/telegram/bot/updates_controller/reply_helpers.rb
Обычный файл
@@ -0,0 +1,42 @@
|
|||||||
|
module Telegram
|
||||||
|
module Bot
|
||||||
|
class UpdatesController
|
||||||
|
module ReplyHelpers
|
||||||
|
# Helper to call bot's `send_#{type}` method with already set `chat_id` and
|
||||||
|
# `reply_to_message_id`:
|
||||||
|
#
|
||||||
|
# reply_with :message, text: 'Hello!'
|
||||||
|
# reply_with :message, text: '__Hello!__', parse_mode: :Markdown
|
||||||
|
# reply_with :photo, photo: File.open(photo_to_send), caption: "It's incredible!"
|
||||||
|
def reply_with(type, params)
|
||||||
|
method = "send_#{type}"
|
||||||
|
chat = self.chat
|
||||||
|
payload = self.payload
|
||||||
|
params = params.merge(
|
||||||
|
chat_id: (chat && chat['id'] or raise 'Can not reply_with when chat is not present'),
|
||||||
|
reply_to_message: payload && payload['message_id'],
|
||||||
|
)
|
||||||
|
bot.public_send(method, params)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Same as reply_with, but for inline queries.
|
||||||
|
def answer_inline_query(results, params = {})
|
||||||
|
params = params.merge(
|
||||||
|
inline_query_id: payload['id'],
|
||||||
|
results: results,
|
||||||
|
)
|
||||||
|
bot.answer_inline_query(params)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Same as reply_with, but for callback queries.
|
||||||
|
def answer_callback_query(text, params = {})
|
||||||
|
params = params.merge(
|
||||||
|
callback_query_id: payload['id'],
|
||||||
|
text: text,
|
||||||
|
)
|
||||||
|
bot.answer_callback_query(params)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
38
spec/telegram/bot/updates_controller/reply_helpers_spec.rb
Обычный файл
38
spec/telegram/bot/updates_controller/reply_helpers_spec.rb
Обычный файл
@@ -0,0 +1,38 @@
|
|||||||
|
RSpec.describe Telegram::Bot::UpdatesController do
|
||||||
|
include_context 'telegram/bot/updates_controller'
|
||||||
|
|
||||||
|
describe '#reply_with' do
|
||||||
|
subject { controller.reply_with type, params }
|
||||||
|
let(:params) { {arg: 1, 'other_arg' => 2} }
|
||||||
|
let(:type) { :photo }
|
||||||
|
let(:result) { double(:result) }
|
||||||
|
let(:payload_type) { :message }
|
||||||
|
let(:payload) { {message_id: double(:message_id)} }
|
||||||
|
let(:chat) { {'id' => double(:chat_id)} }
|
||||||
|
|
||||||
|
it 'sets chat_id & reply_to_message' do
|
||||||
|
expect(controller).to receive(:chat) { chat }
|
||||||
|
expect(bot).to receive("send_#{type}").with(params.merge(
|
||||||
|
chat_id: chat['id'],
|
||||||
|
reply_to_message: payload[:message_id],
|
||||||
|
)) { result }
|
||||||
|
should eq result
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when chat is missing' do
|
||||||
|
let(:payload_type) { :some_type }
|
||||||
|
it { expect { subject }.to raise_error(/chat/) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when update is not set' do
|
||||||
|
let(:update) { {chat: chat} }
|
||||||
|
it 'sets chat_id & reply_to_message' do
|
||||||
|
expect(bot).to receive("send_#{type}").with(params.merge(
|
||||||
|
chat_id: chat['id'],
|
||||||
|
reply_to_message: nil,
|
||||||
|
)) { result }
|
||||||
|
should eq result
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -268,39 +268,4 @@ RSpec.describe Telegram::Bot::UpdatesController do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#reply_with' do
|
|
||||||
subject { controller.reply_with type, params }
|
|
||||||
let(:params) { {arg: 1, 'other_arg' => 2} }
|
|
||||||
let(:type) { :photo }
|
|
||||||
let(:result) { double(:result) }
|
|
||||||
let(:payload_type) { :message }
|
|
||||||
let(:payload) { {message_id: double(:message_id)} }
|
|
||||||
let(:chat) { {'id' => double(:chat_id)} }
|
|
||||||
|
|
||||||
it 'sets chat_id & reply_to_message' do
|
|
||||||
expect(controller).to receive(:chat) { chat }
|
|
||||||
expect(bot).to receive("send_#{type}").with(params.merge(
|
|
||||||
chat_id: chat['id'],
|
|
||||||
reply_to_message: payload[:message_id],
|
|
||||||
)) { result }
|
|
||||||
should eq result
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when chat is missing' do
|
|
||||||
let(:payload_type) { :some_type }
|
|
||||||
it { expect { subject }.to raise_error(/chat/) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when update is not set' do
|
|
||||||
let(:update) { {chat: chat} }
|
|
||||||
it 'sets chat_id & reply_to_message' do
|
|
||||||
expect(bot).to receive("send_#{type}").with(params.merge(
|
|
||||||
chat_id: chat['id'],
|
|
||||||
reply_to_message: nil,
|
|
||||||
)) { result }
|
|
||||||
should eq result
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user