Class: Telegem::Core::Bot

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(token, **options) ⇒ Bot

Returns a new instance of Bot.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/core/bot.rb', line 6

def initialize(token, **options)
  @token = token
  @api = API::Client.new(token, **options.slice(:endpoint, :logger))
  @handlers = {
    message: [],
    callback_query: [],
    inline_query: [],
    chat_member: [],
    poll: [],
    pre_checkout_query: [],
    shipping_query: []
  }
  @middleware = []
  @scenes = {}
  @logger = options[:logger] || Logger.new($stdout)
  @error_handler = nil
  @session_store = options[:session_store] || Session::MemoryStore.new
  @concurrency = options[:concurrency] || 10
  @semaphore = Async::Semaphore.new(@concurrency)
end

Instance Attribute Details

#apiObject (readonly)

Returns the value of attribute api.



4
5
6
# File 'lib/core/bot.rb', line 4

def api
  @api
end

#handlersObject (readonly)

Returns the value of attribute handlers.



4
5
6
# File 'lib/core/bot.rb', line 4

def handlers
  @handlers
end

#loggerObject (readonly)

Returns the value of attribute logger.



4
5
6
# File 'lib/core/bot.rb', line 4

def logger
  @logger
end

#middlewareObject (readonly)

Returns the value of attribute middleware.



4
5
6
# File 'lib/core/bot.rb', line 4

def middleware
  @middleware
end

#scenesObject (readonly)

Returns the value of attribute scenes.



4
5
6
# File 'lib/core/bot.rb', line 4

def scenes
  @scenes
end

#tokenObject (readonly)

Returns the value of attribute token.



4
5
6
# File 'lib/core/bot.rb', line 4

def token
  @token
end

Instance Method Details

#command(name, **options, &block) ⇒ Object

DSL Methods



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

def command(name, **options, &block)
  pattern = /^\/#{Regexp.escape(name)}(?:@\w+)?(?:\s+(.+))?$/i

  on(:message, text: pattern) do |ctx|
    ctx.match = ctx.message.text.match(pattern)
    ctx.state[:command_args] = ctx.match[1] if ctx.match
    block.call(ctx)
  end
end

#delete_webhookObject



108
109
110
111
112
# File 'lib/core/bot.rb', line 108

def delete_webhook
  Async do
    await @api.call('deleteWebhook', {})
  end
end

#error(&block) ⇒ Object



54
55
56
# File 'lib/core/bot.rb', line 54

def error(&block)
  @error_handler = block
end

#get_webhook_infoObject



114
115
116
117
118
# File 'lib/core/bot.rb', line 114

def get_webhook_info
  Async do
    await @api.call('getWebhookInfo', {})
  end
end

#hears(pattern, **options, &block) ⇒ Object



38
39
40
41
42
43
# File 'lib/core/bot.rb', line 38

def hears(pattern, **options, &block)
  on(:message, text: pattern) do |ctx|
    ctx.match = ctx.message.text.match(pattern)
    block.call(ctx)
  end
end

#on(type, filters = {}, &block) ⇒ Object



45
46
47
# File 'lib/core/bot.rb', line 45

def on(type, filters = {}, &block)
  @handlers[type] << { filters: filters, handler: block }
end

#process(update_data) ⇒ Object

Core Processing



121
122
123
124
125
126
# File 'lib/core/bot.rb', line 121

def process(update_data)
  Async do
    update = Types::Update.new(update_data)
    await process_update(update)
  end
end

#scene(id, &block) ⇒ Object



58
59
60
# File 'lib/core/bot.rb', line 58

def scene(id, &block)
  @scenes[id] = Scene.new(id, &block)
end

#set_webhook(url, **options) ⇒ Object



101
102
103
104
105
106
# File 'lib/core/bot.rb', line 101

def set_webhook(url, **options)
  Async do
    params = { url: url }.merge(options)
    await @api.call('setWebhook', params)
  end
end

#shutdownObject



128
129
130
131
132
# File 'lib/core/bot.rb', line 128

def shutdown
  @logger.info "Shutting down..."
  @api.close
  @logger.info "Bot stopped"
end

#start_polling(**options) ⇒ Object

Async Polling



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/core/bot.rb', line 63

def start_polling(**options)
  Async do |parent|
    @logger.info "Starting async polling..."
    offset = nil

    loop do
      updates = await fetch_updates(offset, **options)

      # Process updates concurrently with limits
      updates.each do |update|
        parent.async do |child|
          @semaphore.async do
            await process_update(update)
          end
        end
      end

      offset = updates.last&.update_id.to_i + 1 if updates.any?
    end
  rescue => e
    handle_error(e)
    raise
  end
end

#use(middleware, *args, &block) ⇒ Object



49
50
51
52
# File 'lib/core/bot.rb', line 49

def use(middleware, *args, &block)
  @middleware << [middleware, args, block]
  self
end

#webhook(app = nil, &block) ⇒ Object

Webhook Support



89
90
91
92
93
94
95
96
97
98
99
# File 'lib/core/bot.rb', line 89

def webhook(app = nil, &block)
  require 'telegem/webhook'

  if block_given?
    Webhook::Server.new(self, &block)
  elsif app
    Webhook::Middleware.new(self, app)
  else
    Webhook::Server.new(self)
  end
end