lib/locasms/rest_client.rb
# frozen_string_literal: true
require 'json'
require 'net/http'
module LocaSMS
# Class that handle http calls to LocaSMS api
# @see https://github.com/mcorp/locasms/wiki/A-API-de-envio
# List of avaiable services
class RestClient
attr_accessor :base_url, :base_params
# Creates a new instance of the RestClient class
# @param [String] base_url a well formed url
# @param [Hash] base_params base params to send on every call
def initialize(base_url, base_params = {})
@base_url = base_url
@base_params = base_params
end
# Performs a GET call for an action
# @param [String, Symbol] action the given action to perform
# @param [Hash] params given parameters to send
# @return [Hash] json parsed response
#
# @example Calling with no extra parameters
#
# client = LocaSMS::RestClient('http://localhost:3000', lgn: 'LOGIN', pwd: 'PASSWORD')
# # => GET http://localhost:3000?lgn=LOGIN&pws=PASSWORD&action=getballance
# client.get :getballance
# # => {"status"=>1,"data"=>341,"msg"=>nil}
#
# @example Calling with extra parameters
#
# client = LocaSMS::RestClient('http://localhost:3000', lgn: 'LOGIN', pwd: 'PASSWORD')
# # => GET http://localhost:3000?lgn=LOGIN&pws=PASSWORD&action=holdsms&id=345678
# client.get :holdsms, id: 345678
# # => {"status"=>1,"data"=>nil,"msg"=>"SUCESSO"}
#
# @see https://github.com/mcorp/locasms/wiki/A-API-de-envio#lista-das-a%C3%A7%C3%B5es-dispon%C3%ADveis
# List of avaiable actions
# @raise [LocaSMS::InvalidOperation] when asked for an invalid operation
# @raise [LocaSMS::InvalidLogin] when the given credentials are invalid
def get(action, params = {})
params = params_for action, params
uri = URI.parse(base_url)
uri.query = URI.encode_www_form(params)
response = Net::HTTP.get_response(uri).body
parse_response(action, response)
end
# Composes the parameters hash
# @param [String, Symbol] action the given action to perform
# @param [Hash] params given parameters to send
# @return [Hash]
#
# @example
#
# client = LocaSMS::RestClient('http://localhost:3000', lgn: 'LOGIN', pwd: 'PASSWORD')
# client.params_for :ACTION, a: 1, b: 2
# # => { action: :ACTION, lgn: 'LOGIN', pwd: 'PASSWORD', a: 1, b: 2 }
#
# @see https://github.com/mcorp/locasms/wiki/A-API-de-envio#lista-das-a%C3%A7%C3%B5es-dispon%C3%ADveis
# List of avaiable actions
def params_for(action, params = {})
{ action: action }.merge(base_params).merge(params).select { |_k, v| v }
end
# Parses a result trying to get it in json
# @param [String, Symbol] action the given action to perform
# @param [String] response body
# @return [Hash] json parsed response
# @raise [LocaSMS::InvalidOperation] when asked for an invalid operation
# @raise [LocaSMS::InvalidLogin] when the given credentials are invalid
def parse_response(action, response)
raise InvalidOperation.new(action: action) if response.match?(/^0:OPERACAO INVALIDA$/i)
j = begin
MultiJson.load(response)
rescue StandardError
{ 'status' => 1, 'data' => response, 'msg' => nil }
end
return j if (j['status'] == 1) || (action == :getstatus)
raise InvalidLogin.new(action: action) if j['msg'].match?(/^falha ao realizar login$/i)
raise LocaSMS::Exception.new(message: j['msg'], raw: response, action: action)
end
end
end