# frozen_string_literal: true require "logger" module Qismo # Qismo ruby client # class Client include Qismo::Api # @return [String] DEFAULT_APP_ID = ENV["QISCUS_APP_ID"] # @return [String] DEFAULT_SECRET_KEY = ENV["QISCUS_SECRET_KEY"] # @return [String] DEFAULT_URL = (ENV["QISCUS_OMNICHANNEL_URL"] || "https://multichannel.qiscus.com") # @return [String] attr_accessor :app_id # @return [String] attr_accessor :secret_key # @return [Addressable::URI] attr_accessor :url # @return [Logger] attr_accessor :logger # @return [ActiveSupport::Notifications::Instrumenter] attr_accessor :instrumentation # @return [Integer,Hash] attr_accessor :timeout # @return [Array] attr_accessor :proxy # @return [String,Proc] attr_accessor :admin_email # Initiate Qismo Ruby client # # @param app_id [String] # Your account's app id. Can be checked in Qiscus Omnichannel dashboard. # We will use ENV["QISCUS_APP_ID"] value as default value. # @param secret_key [String] # Your account's secret key. Can be checked in Qiscus Omnichannel dashboard. # We will use ENV["QISCUS_SECRET_KEY"] value as default value. # @param url [String] # Custom base url for Qiscus Omnichannel client. # We will use ENV["QISCUS_OMNICHANNEL_URL"] value as default value. # If its not provided, we will use https://multichannel.qiscus.com as default value # @param logger [Logger] # Http client logging. Default is nil # @param instrumentation [ActiveSupport::Notifications::Instrumenter] # Http client instrumenter. Use ActiveSupport Instrumenter # @param timeout [Integer, Hash] # Http client timout. Default is 5 seconds # @param proxy [Array] # Http client proxy # @param admin_email [String,Proc] # Your account's admin email. Can be checked in Qiscus Omnichannel dashboard def initialize( app_id: DEFAULT_APP_ID, secret_key: DEFAULT_SECRET_KEY, url: DEFAULT_URL, logger: Logger.new($stdout), instrumentation: nil, timeout: 5, proxy: nil, admin_email: nil ) @app_id = app_id @secret_key = secret_key # @type [Addressable::URI] @url = Addressable::URI.parse(url) @logger = logger @instrumentation = instrumentation @timeout = timeout @proxy = proxy @admin_email = (admin_email || -> { "#{@app_id}_admin@qismo.com" }) end # Send http request with post method # # @param path [String] # @param body [Hash] # @return [Qismo::ObjectifiedHash] def post(path, body = {}) request(:post, path, json: body.compact) end # Send HTTP request with post method to upload file # # @param path [String] # @param body [Hash] # @return [Qismo::SingleObject] def post_upload(path, body = {}) request(:post, path, form: body.compact) end # Send HTTP request with get method # # @param path [String] # @param params [Hash] # @return [Qismo::ObjectifiedHash] def get(path, params = {}) request(:get, path, params: params.compact) end # Send HTTP request with delete method # # @param path [String] # @param params [Hash] # @return [Qismo::ObjectifiedHash] def delete(path, params = {}) request(:delete, path, params: params.compact) end # Send HTTP request # # @param method [Symbol, String] # @param path [String] # @param headers [Hash] # @param params [Hash] # @param json [Hash] # @return [Qismo::ObjectifiedHash] def request(method, path, options = {}) res = connection.request(method, @url.join(path), options.compact) if res.status.success? begin return JSON.parse(res.to_s, object_class: Qismo::ObjectifiedHash) rescue JSON::ParserError return res.to_s end end if res.status.server_error? raise InternalServerError.new("Qiscus Omnichannel server error", status_code: res.code, response_body: res.to_s) end if res.status.client_error? body = JSON.parse(res.to_s, object_class: Qismo::ObjectifiedHash) error = body.errors error = error.message if error.is_a?(Hash) error_klass_map = { 400 => BadRequestError, 401 => UnauthorizedError, 402 => PaymentRequiredError, 403 => ForbiddenError, 404 => NotFoundError, 429 => TooManyRequestError } error_klass = error_klass_map[res.code] || HTTPRequestError raise error_klass.new(error, status_code: res.code, response_body: res.to_s) end end # Http connection config # # @return [HTTP::Chainable] def connection http = HTTP http = http.use(logging: @logger) if @logger.present? http = http.use(instrumentation: @instrumentation) if @instrumentation.present? http = http.via(*@proxy) if @timeout.present? http = if @timeout.is_a?(Hash) http.timeout(**@timeout) else http.timeout(@timeout) end end http.headers({ "Qiscus-App-Id": @app_id, "Qiscus-Secret-Key": @secret_key, "User-Agent": user_agent }) end # Http user agent config # # @return [Hash] def user_agent format = { lib_name: "Qismo Ruby", lib_version: Qismo::VERSION, lang: "ruby", lang_version: RUBY_VERSION, platform: RUBY_PLATFORM, engine: defined?(RUBY_ENGINE) ? RUBY_ENGINE : "" } "#{format[:lib_name]}/#{format[:lib_version]} (#{format[:platform]}; #{format[:lang]}; v#{format[:lang_version]}) app_id:#{@app_id}" end # Default broadcast name for using in send broadcast api # # @return [String] def default_broadcast_name Time.current.strftime("%d/%m/%Y, %H:%I %z") end end end