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



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

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.



27
28
29
# File 'lib/telegram/bot/updates_poller.rb', line 27

def bot
  @bot
end

#controllerObject (readonly)

Returns the value of attribute controller.



27
28
29
# File 'lib/telegram/bot/updates_poller.rb', line 27

def controller
  @controller
end

#loggerObject (readonly)

Returns the value of attribute logger.



27
28
29
# File 'lib/telegram/bot/updates_poller.rb', line 27

def logger
  @logger
end

#offsetObject (readonly)

Returns the value of attribute offset.



27
28
29
# File 'lib/telegram/bot/updates_poller.rb', line 27

def offset
  @offset
end

#reloadObject (readonly)

Returns the value of attribute reload.



27
28
29
# File 'lib/telegram/bot/updates_poller.rb', line 27

def reload
  @reload
end

#runningObject (readonly)

Returns the value of attribute running.



27
28
29
# File 'lib/telegram/bot/updates_poller.rb', line 27

def running
  @running
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



27
28
29
# File 'lib/telegram/bot/updates_poller.rb', line 27

def timeout
  @timeout
end

Class Method Details

.add(bot, controller) ⇒ Object

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



13
14
15
# File 'lib/telegram/bot/updates_poller.rb', line 13

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

.instancesObject



8
9
10
# File 'lib/telegram/bot/updates_poller.rb', line 8

def instances
  @@instances
end

.start(bot_id, controller = nil) ⇒ Object



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

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



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

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



38
39
40
# File 'lib/telegram/bot/updates_poller.rb', line 38

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

#process_update(update) ⇒ Object

Override this method to setup custom error collector.



90
91
92
# File 'lib/telegram/bot/updates_poller.rb', line 90

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

#process_updates(updates) ⇒ Object



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

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

#reload!Object



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

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



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

def reloading_code
  Rails.application.reloader.wrap do
    yield
  end
end

#runObject



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

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

#startObject



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

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.



64
65
66
67
68
# File 'lib/telegram/bot/updates_poller.rb', line 64

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