class VkLongpollBot::Bot

Main class, which contains all the methods of bot.

Attributes

event_listeners[R]

@return [Hash<Symbol, Array<EventListener>>] hash with listeners for each of event type.

id[R]

@return [Integer] group ID.

Public Class Methods

new(access_token, group_id, options = {}) click to toggle source

Initialize bot. This method don't start longpoll session.

@param access_token [String] group access token. @param group_id [Integer] group of associated ID. @param options [Hash]

@option options [Gem::Version, String] api_version (VK_API_URL_BASE) version of VK API. @option options [Integer] longpoll_wait longpoll (LONGPOLL_STANDART_WAIT) requests timeout.

# File lib/vk_longpoll_bot/bot.rb, line 24
def initialize(access_token, group_id, options = {})
  @event_listeners = Hash.new { |hash, key| hash[key] = Array.new }
  @on_start = []
  @on_finish = []

  @access_token = access_token.to_s
  @id = group_id.to_i
  
  @api_version = options[:api_version] || VK_API_CURRENT_VERSION
  @longpoll_wait = options[:longpoll_wait] || LONGPOLL_STANDART_WAIT
  
  @longpoll = {}
end

Public Instance Methods

api(method_name, parameters = {}) click to toggle source

Call for API method.

@param method_name [“String”] name of requested method. See vk.com/dev/methods

@return [Hash]

# File lib/vk_longpoll_bot/bot.rb, line 47
def api(method_name, parameters = {})
  Request.api(method_name, parameters, @access_token, @api_version)
end
disable_online() click to toggle source

Disable group online status

@return [nil]

# File lib/vk_longpoll_bot/bot.rb, line 87
def disable_online
  begin
    api("groups.disableOnline", group_id: @id)
  rescue
    # Online is already disabled
  end
  nil
end
enable_online() click to toggle source

Enable group online status

@return [nil]

# File lib/vk_longpoll_bot/bot.rb, line 74
def enable_online
  begin
    api("groups.enableOnline", group_id: @id)
  rescue
    # Online is already enabled
  end
  nil
end
on(options, &block) click to toggle source

Add new event listener.

@param options [Hash]

@option options [String] subtype

@yieldparam event [Event]

@return [nil]

# File lib/vk_longpoll_bot/bot.rb, line 112
def on(options, &block)
  raise ArgumentError.new("Got subtype #{options[:subtype]} of class #{options[:subtype].class}") unless String === options[:subtype] && Events.valid_subtype?(options[:subtype])
  @event_listeners[options[:subtype]] << Events::EventListener.new(options, &block)
  nil
end
on_finish(&block) click to toggle source

Add code to be executed right after bot finishes.

# File lib/vk_longpoll_bot/bot.rb, line 126
def on_finish(&block)
  @on_finish << block
end
on_start(&block) click to toggle source

Add code to be executed right after bot starts.

# File lib/vk_longpoll_bot/bot.rb, line 120
def on_start(&block)
  @on_start << block
end
run() click to toggle source

Start bot. This methods freeze current thread until {Bot#stop} method is called.

@return [void]

# File lib/vk_longpoll_bot/bot.rb, line 137
def run
  @on_start.each(&:call)

  init_longpoll
  run_longpoll
  
  @on_finish.each(&:call)
end
send_message(target, content, options = {}) click to toggle source

Send text message.

@param target [Integer] ID of receiver. @param content [String] text of message. @param options [Hash] additional options which must be sent with request.

Options +user_id+, +message+ and +random_id+ will be overwritten

@return [Hash]

# File lib/vk_longpoll_bot/bot.rb, line 60
def send_message(target, content, options = {})
  target_id = target.to_i
  forced_options = {
    user_id: target_id,
    message: content,
    random_id: Utility.random_id(target_id)
  }
  api("messages.send", options.merge(forced_options))
end
stop() click to toggle source

Stop bot.

@return [void]

# File lib/vk_longpoll_bot/bot.rb, line 150
def stop
  @finish_flag = true
end

Private Instance Methods

init_longpoll() click to toggle source

Request longpoll data.

# File lib/vk_longpoll_bot/bot.rb, line 158
def init_longpoll
  lp = api("groups.getLongPollServer", group_id: @id)
  @longpoll[:server] = lp["server"]
  @longpoll[:key] = lp["key"]
  @longpoll[:ts] = lp["ts"]    
end
run_longpoll() click to toggle source

Start longpoll. Requires init_longpoll to be run first.

# File lib/vk_longpoll_bot/bot.rb, line 166
def run_longpoll
  @finish_flag = false # Setting up flag for loop
  
  until @finish_flag
    response = Request.longpoll(@longpoll[:server], @longpoll[:key], @longpoll[:ts], @longpoll_wait)
    if response["failed"]
      Utility.warn "Longpoll failed with code #{response["failed"]}. This must be solvable. Keep running..."
      case response["failed"]
        when 1
          # Just update ts
          @longpoll[:ts] = response["ts"]
        when 2, 3
          # Need to reconnect
          init_longpoll
      else
        raise Exceptions::LongpollError("Unknown 'failed' value: #{response["failed"]}. Full response: #{response.to_s}")
      end
    elsif response["ts"] && response["updates"]
      # Everything is fine. Handling update
      @longpoll[:ts] = response["ts"]
      updates = response["updates"]
      response["updates"].each { |update| update_handler(update) }
    else
      raise Exceptions::LongpollError("Strange longpoll response: #{response.to_s}")
    end
  end
end
update_handler(update) click to toggle source

Handle update from longpoll.

# File lib/vk_longpoll_bot/bot.rb, line 195
def update_handler(update)
  event = Events::Event.new(update["type"], update["object"], update["group_id"], self)
  @event_listeners[event.subtype].each do |listener|
    # NOTE: If we had any attributes, we would check whether matching here.
    Thread.new(event) { |e| listener.call(e) }
  end
end