1
0
зеркало из https://github.com/glebtv/telegram-bot.git synced 2026-09-07 11:25:52 +03:00

New api methods and support for inline keyboards

Этот коммит содержится в:
Max Melentiev
2016-05-17 09:26:20 +03:00
родитель 148023bb0d
Коммит 4593a10dec
7 изменённых файлов: 106 добавлений и 61 удалений

Просмотреть файл

@@ -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.

Просмотреть файл

@@ -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

Просмотреть файл

@@ -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