class Line::Bot::Client

Attributes

channel_secret[RW]

@return [String]

channel_token[RW]

@return [String]

endpoint[RW]

@return [String]

httpclient[RW]

@return [Object]

Public Class Methods

new(options = {}) { |self| ... } click to toggle source

Initialize a new Bot Client.

@param options [Hash]

@return [Line::Bot::Client]

# File lib/line/bot/client.rb, line 36
def initialize(options = {})
  options.each do |key, value|
    instance_variable_set("@#{key}", value)
  end
  yield(self) if block_given?
end

Public Instance Methods

credentials() click to toggle source

@return [Hash]

# File lib/line/bot/client.rb, line 52
def credentials
  {
    "Authorization" => "Bearer #{channel_token}",
  }
end
credentials?() click to toggle source
# File lib/line/bot/client.rb, line 58
def credentials?
  credentials.values.all?
end
get(endpoint_path) click to toggle source

Fetch data, get content of specified URL.

@param endpoint_path [String]

@return [Net::HTTPResponse]

# File lib/line/bot/client.rb, line 159
def get(endpoint_path)
  raise Line::Bot::API::InvalidCredentialsError, 'Invalidates credentials' unless credentials?

  request = Request.new do |config|
    config.httpclient     = httpclient
    config.endpoint       = endpoint
    config.endpoint_path  = endpoint_path
    config.credentials    = credentials
  end

  request.get
end
get_message_content(identifier) click to toggle source

Get message content.

@param identifier [String] Message's identifier

@return [Net::HTTPResponse]

# File lib/line/bot/client.rb, line 139
def get_message_content(identifier)
  endpoint_path  = "/message/#{identifier}/content"
  get(endpoint_path)
end
get_profile(user_id) click to toggle source

Get an user's profile.

@param user_id [String] User's identifiers

@return [Net::HTTPResponse]

# File lib/line/bot/client.rb, line 149
def get_profile(user_id)
  endpoint_path  = "/profile/#{user_id}"
  get(endpoint_path)
end
leave_group(group_id) click to toggle source
# File lib/line/bot/client.rb, line 108
def leave_group(group_id)
  raise Line::Bot::API::InvalidCredentialsError, 'Invalidates credentials' unless credentials?

  request = Request.new do |config|
    config.httpclient     = httpclient
    config.endpoint       = endpoint
    config.endpoint_path  = "/group/#{group_id}/leave"
    config.credentials    = credentials
  end

  request.post
end
leave_room(room_id) click to toggle source
# File lib/line/bot/client.rb, line 121
def leave_room(room_id)
  raise Line::Bot::API::InvalidCredentialsError, 'Invalidates credentials' unless credentials?

  request = Request.new do |config|
    config.httpclient     = httpclient
    config.endpoint       = endpoint
    config.endpoint_path  = "/room/#{room_id}/leave"
    config.credentials    = credentials
  end

  request.post
end
parse_events_from(request_body) click to toggle source

Parse events from request.body

@param request_body [String]

@return [Array<Line::Bot::Event::Class>]

# File lib/line/bot/client.rb, line 177
def parse_events_from(request_body)
  json = JSON.parse(request_body)

  json['events'].map { |item|
    begin
      klass = Line::Bot::Event.const_get(item['type'].capitalize)
      klass.new(item)
    rescue NameError => e
      Line::Bot::Event::Base.new(item)
    end
  }
end
push_message(user_id, messages) click to toggle source

Push messages to line server and to users.

@param user_id [String] User's identifiers @param messages [Hash or Array]

@return [Net::HTTPResponse]

# File lib/line/bot/client.rb, line 68
def push_message(user_id, messages)
  raise Line::Bot::API::InvalidCredentialsError, 'Invalidates credentials' unless credentials?

  messages = [messages] if messages.is_a?(Hash)

  request = Request.new do |config|
    config.httpclient     = httpclient
    config.endpoint       = endpoint
    config.endpoint_path  = '/message/push'
    config.credentials    = credentials
    config.to             = user_id
    config.messages       = messages
  end

  request.post
end
reply_message(token, messages) click to toggle source

Reply messages to line server and to users.

@param token [String] @param messages [Hash or Array]

@return [Net::HTTPResponse]

# File lib/line/bot/client.rb, line 91
def reply_message(token, messages)
  raise Line::Bot::API::InvalidCredentialsError, 'Invalidates credentials' unless credentials?

  messages = [messages] if messages.is_a?(Hash)

  request = Request.new do |config|
    config.httpclient     = httpclient
    config.endpoint       = endpoint
    config.endpoint_path  = '/message/reply'
    config.credentials    = credentials
    config.reply_token    = token
    config.messages       = messages
  end

  request.post
end
validate_signature(content = "", channel_signature) click to toggle source

Validate signature

@param content [String] Request's body @param channel_signature [String] Request'header 'X-LINE-Signature' # HTTP_X_LINE_SIGNATURE

@return [Boolean]

# File lib/line/bot/client.rb, line 196
def validate_signature(content = "", channel_signature)
  return false if !channel_signature || !channel_secret

  hash = OpenSSL::HMAC::digest(OpenSSL::Digest::SHA256.new, channel_secret, content)
  signature = Base64.strict_encode64(hash)

  variable_secure_compare(channel_signature, signature)
end

Private Instance Methods

secure_compare(a, b) click to toggle source

@return [Boolean]

# File lib/line/bot/client.rb, line 216
def secure_compare(a, b)
  return false unless a.bytesize == b.bytesize

  l = a.unpack "C#{a.bytesize}"

  res = 0
  b.each_byte { |byte| res |= byte ^ l.shift }
  res == 0
end
variable_secure_compare(a, b) click to toggle source

Constant time string comparison.

via timing attacks. reference: github.com/rails/rails/blob/master/activesupport/lib/active_support/security_utils.rb @return [Boolean]

# File lib/line/bot/client.rb, line 211
def variable_secure_compare(a, b)
  secure_compare(::Digest::SHA256.hexdigest(a), ::Digest::SHA256.hexdigest(b))
end