Class: Telegram::Bot::UpdatesPoller

Inherits:
Object
  • Object
show all
Defined in:
lib/telegram/bot/updates_poller.rb

Overview

Supposed to be used in development environments only.

Constant Summary collapse

DEFAULT_TIMEOUT =
5
@@instances =

rubocop:disable Style/ClassVars

{}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(bot, controller, **options) ⇒ UpdatesPoller

Returns a new instance of UpdatesPoller.



31
32
33
34
35
36
37
38
# File 'lib/telegram/bot/updates_poller.rb', line 31

def initialize(bot, controller, **options)
  @logger = options.fetch(:logger) { defined?(Rails.logger) && Rails.logger }
  @bot = bot
  @controller = controller
  @timeout = options.fetch(:timeout) { DEFAULT_TIMEOUT }
  @offset = options[:offset]
  @reload = options.fetch(:reload) { defined?(Rails.env) && Rails.env.development? }
end

Instance Attribute Details

#botObject (readonly)

Returns the value of attribute bot.



29
30
31
# File 'lib/telegram/bot/updates_poller.rb', line 29

def bot
  @bot
end

#controllerObject (readonly)

Returns the value of attribute controller.



29
30
31
# File 'lib/telegram/bot/updates_poller.rb', line 29

def controller
  @controller
end

#loggerObject (readonly)

Returns the value of attribute logger.



29
30
31
# File 'lib/telegram/bot/updates_poller.rb', line 29

def logger
  @logger
end

#offsetObject (readonly)

Returns the value of attribute offset.



29
30
31
# File 'lib/telegram/bot/updates_poller.rb', line 29

def offset
  @offset
end

#reloadObject (readonly)

Returns the value of attribute reload.



29
30
31
# File 'lib/telegram/bot/updates_poller.rb', line 29

def reload
  @reload
end

#runningObject (readonly)

Returns the value of attribute running.



29
30
31
# File 'lib/telegram/bot/updates_poller.rb', line 29

def running
  @running
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



29
30
31
# File 'lib/telegram/bot/updates_poller.rb', line 29

def timeout
  @timeout
end

Class Method Details

.add(bot, controller) ⇒ Object

Create, start and add poller instnace to tracked instances list.



15
16
17
# File 'lib/telegram/bot/updates_poller.rb', line 15

def add(bot, controller)
  new(bot, controller).tap { |x| instances[bot] = x }
end

.instancesObject



10
11
12
# File 'lib/telegram/bot/updates_poller.rb', line 10

def instances
  @@instances
end

.start(bot_id, controller = nil) ⇒ Object



19
20
21
22
23
24
# File 'lib/telegram/bot/updates_poller.rb', line 19

def start(bot_id, controller = nil)
  bot = bot_id.is_a?(Symbol) ? Telegram.bots[bot_id] : Client.wrap(bot_id)
  instance = controller ? new(bot, controller) : instances[bot]
  raise "Poller not found for #{bot_id.inspect}" unless instance
  instance.start
end

Instance Method Details

#fetch_updates(offset = self.offset) ⇒ Object



72
73
74
75
76
77
78
# File 'lib/telegram/bot/updates_poller.rb', line 72

def fetch_updates(offset = self.offset)
  response = bot.async(false) { bot.get_updates(offset: offset, timeout: timeout) }
  response.is_a?(Array) ? response : response['result']
rescue Timeout::Error
  log { 'Fetch timeout' }
  nil
end

#log(&block) ⇒ Object



40
41
42
# File 'lib/telegram/bot/updates_poller.rb', line 40

def log(&block)
  logger&.info(&block)
end

#process_update(update) ⇒ Object

Override this method to setup custom error collector.



92
93
94
# File 'lib/telegram/bot/updates_poller.rb', line 92

def process_update(update)
  controller.dispatch(bot, update)
end

#process_updates(updates) ⇒ Object



80
81
82
83
84
85
86
87
88
89
# File 'lib/telegram/bot/updates_poller.rb', line 80

def process_updates(updates)
  reload! do
    updates.each do |update|
      @offset = update['update_id'] + 1
      process_update(update)
    end
  end
rescue StandardError => exception
  logger&.error { ([exception.message] + exception.backtrace).join("\n") }
end

#reload!Object



96
97
98
99
100
101
102
103
104
# File 'lib/telegram/bot/updates_poller.rb', line 96

def reload!
  return yield unless reload
  reloading_code do
    if controller.is_a?(Class) && controller.name
      @controller = Object.const_get(controller.name)
    end
    yield
  end
end

#reloading_codeObject



107
108
109
# File 'lib/telegram/bot/updates_poller.rb', line 107

def reloading_code(&block)
  Rails.application.reloader.wrap(&block)
end

#runObject



58
59
60
61
62
63
# File 'lib/telegram/bot/updates_poller.rb', line 58

def run
  while running
    updates = fetch_updates
    process_updates(updates) if updates&.any?
  end
end

#startObject



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/telegram/bot/updates_poller.rb', line 44

def start
  return if running
  begin
    @running = true
    log { 'Started bot poller.' }
    run
  rescue Interrupt
    nil # noop
  ensure
    @running = false
  end
  log { 'Stopped polling bot updates.' }
end

#stopObject

Method to stop poller from other thread.



66
67
68
69
70
# File 'lib/telegram/bot/updates_poller.rb', line 66

def stop
  return unless running
  log { 'Stopping polling bot updates.' }
  @running = false
end