qismo 0.1.8 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/qismo/client.rb CHANGED
@@ -1,131 +1,103 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "http"
4
- require "qismo/operations"
5
-
6
3
  module Qismo
7
- #
8
- # Qismo client object
9
- #
10
- # @!attribute app_id [String]
11
- # @!attribute secret_key [String]
12
- # @!attribute base_url [String]
13
- # @!attribute admin_email [String]
14
4
  class Client
15
- # @!parse
16
- # include Qismo::Helpers::BaseHelper
17
- include Qismo::Helpers::BaseHelper
18
-
19
- # @!parse
20
- # include Qismo::Operations
21
- include Qismo::Operations
22
-
23
- # @return [String] default base url constant
24
- DEFAULT_BASE_URL = "https://multichannel.qiscus.com"
25
-
26
- attr_accessor :app_id, :secret_key, :base_url, :admin_email, :proxy
27
-
28
- #
29
- # Initialize Qismo client
30
- #
31
- # @param options [Hash]
32
- # @option options [String] :app_id
33
- # @option options [String] :secret_key
34
- # @option options [String] :base_url
35
- #
36
- def initialize(options = {})
37
- options = options.compact
38
- options[:base_url] = DEFAULT_BASE_URL if options[:base_url].nil?
39
-
40
- options.each do |key, value|
41
- instance_variable_set("@#{key}", value)
42
- end
5
+ include Qismo::Model
6
+ include Qismo::Api
43
7
 
44
- if @admin_email.nil? && !@app_id.nil?
45
- @admin_email = "#{app_id}_admin@qismo.com"
46
- end
8
+ VALID_OPTIONS = [:app_id, :secret_key, :url, :logger, :instrumentation, :timeout, :proxy]
9
+
10
+ attr_accessor(*VALID_OPTIONS)
11
+
12
+ def initialize(**opt)
13
+ @app_id = opt[:app_id] || ENV["QISCUS_APP_ID"]
14
+ @secret_key = opt[:secret_key] || ENV["QISCUS_SECRET_KEY"]
15
+ @url = opt[:url] || ENV["QISCUS_OMNICHANNEL_URL"] || "https://qismo.qiscus.com"
16
+ @logger = opt[:logger]
17
+ @instrumentation = opt[:instrumentation]
18
+ @timeout = opt[:timeout]
19
+ @proxy = opt[:proxy]
47
20
  end
48
21
 
49
- #
50
- # Call HTTP request raw
51
- #
52
- # @param method [String]
53
- # @param url [String]
54
- # @param options [Hash]
55
- # @option options [Hash] :headers
56
- # @option options [Hash] :params
57
- # @option options [Hash] :json
58
- #
59
- # @return [Response]
60
- #
61
- def raw_request(method, url, options = {})
62
- resp = if Qismo.client.proxy.nil?
63
- HTTP.request(method, url, options)
64
- else
65
- proxy = Qismo.client.proxy
66
- proxy_args = [proxy[:host], proxy[:port], proxy[:username], proxy[:password]]
67
-
68
- HTTP.via(*proxy_args).request(method, url, options)
69
- end
22
+ def post(path, body = {})
23
+ request(:post, path, json: body)
24
+ end
70
25
 
71
- resp = Response.new(resp)
72
- resp.raise_for_error
26
+ def post_upload(path, body = {})
27
+ request(:post, form: body)
28
+ end
73
29
 
74
- resp
30
+ def get(path, **params)
31
+ request(:get, path, params)
75
32
  end
76
33
 
77
- #
78
- # Do HTTP request
79
- #
80
- # @param method [String]
81
- # @param path [String]
82
- # @param options [Hash]
83
- # @option options [Hash] :params
84
- # @option options [Hash] :json
85
- # @options options [Hash] :headers
86
- #
87
- # @return [Response]
88
- #
89
- def request(method, path, options = {})
90
- url = Qismo.client.base_url + path
91
-
92
- if !options[:headers].nil? && options[:headers].is_a?(Hash) && !options[:headers][:authorization].nil?
93
- options[:header].merge({
94
- qiscus_app_id: Qismo.client.app_id,
95
- qiscus_secret_key: Qismo.client.secret_key,
96
- })
97
- else
98
- options[:headers] = {
99
- qiscus_app_id: Qismo.client.app_id,
100
- qiscus_secret_key: Qismo.client.secret_key,
101
- }
34
+ def request(method, path, **opt)
35
+ res = connection.request(method, @url + path, opt.compact)
36
+ if res.status.success?
37
+ return JSON.parse(res.to_s, object_class: Data)
102
38
  end
103
39
 
104
- raw_request(method, url, options)
40
+ if res.status.server_error?
41
+ raise InternalServerError.new("Qiscus Omnichannel server error", status_code: res.code, response_body: res.to_s)
42
+ end
43
+
44
+ if res.status.client_error?
45
+ body = JSON.parse(res.to_s, object_class: Data)
46
+ error = body.errors
47
+ error = error.message if error.is_a?(Hash)
48
+
49
+ error_klass_map = {
50
+ 400 => BadRequestError,
51
+ 401 => UnauthorizedError,
52
+ 402 => PaymentRequiredError,
53
+ 403 => ForbiddenError,
54
+ 404 => NotFoundError,
55
+ 429 => TooManyRequestError,
56
+ }
57
+
58
+ error_klass = error_klass_map[res.code] || HTTPRequestError
59
+ raise error_klass.new(error, status_code: res.code, response_body: res.to_s)
60
+ end
105
61
  end
106
62
 
107
- #
108
- # Do HTTP request using GET method
109
- #
110
- # @param path [String]
111
- # @param params [Hash]
112
- #
113
- # @return [Response]
114
- #
115
- def get(path, params = {})
116
- request(:get, path, params: params)
63
+ def connection
64
+ http = HTTP
65
+
66
+ unless @logger.nil?
67
+ http = http.use(logging: @logger)
68
+ end
69
+
70
+ unless @instrumentation.nil?
71
+ http = http.use(instrumentation: @instrumentation)
72
+ end
73
+
74
+ unless @timeout.nil?
75
+ http = if @timeout.is_a?(Hash)
76
+ http.timeout(**@timeout)
77
+ else
78
+ http.timeout(@timeout)
79
+ end
80
+ end
81
+
82
+ unless @proxy.nil?
83
+ http = http.via(*@proxy)
84
+ end
85
+
86
+ http.headers({
87
+ "Qiscus-App-Id": @app_id,
88
+ "Qiscus-Secret-Key": @secret_key,
89
+ "User-Agent": user_agent.to_json,
90
+ })
117
91
  end
118
92
 
119
- #
120
- # Do HTTP request using POST method
121
- #
122
- # @param path [String]
123
- # @param body [Hash]
124
- #
125
- # @return [Response]
126
- #
127
- def post(path, body = {})
128
- request(:post, path, json: body)
93
+ def user_agent
94
+ {
95
+ lib_version: Qismo::VERSION,
96
+ lang: "ruby",
97
+ lang_version: RUBY_VERSION,
98
+ platform: RUBY_PLATFORM,
99
+ engine: defined?(RUBY_ENGINE) ? RUBY_ENGINE : "",
100
+ }
129
101
  end
130
102
  end
131
103
  end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Qismo
4
+ class Error < StandardError
5
+ attr_reader :message
6
+ end
7
+
8
+ class HTTPTimeoutError < Error
9
+ def initialize(message)
10
+ super(message)
11
+ end
12
+ end
13
+
14
+ class HTTPRequestError < Error
15
+ attr_reader :message, :status_code, :response_body
16
+
17
+ def initialize(message, status_code:, response_body:)
18
+ super(message.to_s)
19
+
20
+ @message = message
21
+ @status_code = status_code
22
+ @response_body = response_body
23
+ end
24
+ end
25
+
26
+ class InternalServerError < HTTPRequestError
27
+ end
28
+
29
+ # 400
30
+ class BadRequestError < HTTPRequestError
31
+ end
32
+
33
+ # 401
34
+ class UnauthorizedError < HTTPRequestError
35
+ end
36
+
37
+ # 402
38
+ class PaymentRequiredError < HTTPRequestError
39
+ end
40
+
41
+ # 403
42
+ class ForbiddenError < HTTPRequestError
43
+ end
44
+
45
+ # 404
46
+ class NotFoundError < HTTPRequestError
47
+ end
48
+
49
+ # 429
50
+ class TooManyRequestError < HTTPRequestError
51
+ end
52
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Qismo
4
+ module Model
5
+ class Data < OpenStruct # rubocop:disable Style/OpenStructUse
6
+ end
7
+
8
+ class Collection < Array
9
+ def initialize(data, prev_page: nil, next_page: nil, prev_func: -> { nil }, next_func: -> { nil })
10
+ super(data)
11
+
12
+ @prev_page = prev_page
13
+ @next_page = next_page
14
+ @prev_func = prev_func
15
+ @next_func = next_func
16
+ end
17
+
18
+ def has_next_page?
19
+ @next_page != nil
20
+ end
21
+
22
+ alias_method :next_page?, :has_next_page?
23
+
24
+ def has_prev_page?
25
+ @prev_page != nil
26
+ end
27
+
28
+ alias_method :prev_page?, :has_prev_page?
29
+
30
+ def next_page
31
+ @next_func.call
32
+ end
33
+
34
+ def prev_page
35
+ @prev_func.call
36
+ end
37
+ end
38
+
39
+ class Response
40
+ attr_reader :data, :meta
41
+
42
+ def initialize(data, meta = {})
43
+ @data = data
44
+ @meta = meta
45
+ end
46
+ end
47
+ end
48
+ end
data/lib/qismo/version.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Qismo
4
- # @return [String] gem version constant
5
- VERSION = "0.1.8"
4
+ VERSION = "0.5.0"
6
5
  end
data/lib/qismo.rb CHANGED
@@ -1,70 +1,44 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Helpers
4
- require "qismo/helpers/base_helper"
3
+ require "http"
5
4
 
6
- # Base
7
5
  require "qismo/version"
8
- require "qismo/errors"
9
- require "qismo/response"
6
+ require "qismo/error"
7
+ require "qismo/model"
8
+ require "qismo/api"
10
9
  require "qismo/client"
11
10
 
12
- # Resources
13
- require "qismo/resources/agent_resource"
14
- require "qismo/resources/room_resource"
15
- require "qismo/resources/office_setting_resource"
16
- require "qismo/resources/user_resource"
17
- require "qismo/resources/bot_resource"
18
-
19
- # Models
20
- require "qismo/models/base"
21
- require "qismo/models/agent"
22
- require "qismo/models/room"
23
- require "qismo/models/office_setting"
24
- require "qismo/models/office_hour"
25
- require "qismo/models/user"
26
- require "qismo/models/bot"
27
-
28
- #
29
- # Base module of Qismo ruby
30
- #
11
+ # Qismo
31
12
  module Qismo
32
13
  class << self
33
- attr_writer :client
14
+ attr_reader(*Qismo::Client::VALID_OPTIONS)
34
15
 
35
- #
36
- # Configure client using block
37
- #
38
- # @yieldparam [Client]
39
- #
40
- # @yieldreturn [Client]
41
- #
42
- def init
43
- yield(client)
16
+ def configure
17
+ yield client
44
18
 
45
- client
19
+ Qismo::Client::VALID_OPTIONS.each do |opt|
20
+ instance_variable_set("@#{opt}", client.send(opt))
21
+ end
46
22
  end
47
23
 
48
- alias_method :configure, :init
24
+ if Gem::Version.new(RUBY_VERSION).release >= Gem::Version.new("3.0.0")
25
+ def method_missing(method, *args, **kwargs, &block)
26
+ return super unless client.respond_to?(method)
27
+
28
+ client.send(method, *args, **kwargs, &block)
29
+ end
30
+ else
31
+ def method_missing(method, *args, &block)
32
+ return super unless client.respond_to?(method)
33
+
34
+ client.send(method, *args, &block)
35
+ end
36
+ end
49
37
 
50
- #
51
- # Configure client
52
- #
53
- # @param app_id [String]
54
- # @param secret_key [String]
55
- # @param base_url [String]
56
- #
57
- # @return [Client]
58
- #
59
- def new(app_id:, secret_key:, base_url: Client::DEFAULT_BASE_URL)
60
- @client = Client.new(app_id: app_id, secret_key: secret_key, base_url: base_url)
38
+ def respond_to_missing?(method_name, *args)
39
+ Qismo::Client.instance_methods.include?(method_name)
61
40
  end
62
41
 
63
- #
64
- # Qismo ruby client
65
- #
66
- # @return [Qismo::Client]
67
- #
68
42
  def client
69
43
  @client ||= Client.new
70
44
  end
metadata CHANGED
@@ -1,87 +1,139 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qismo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.8
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
- - Nurcholis Art
8
- - Qiscus
7
+ - Qiscus Integration
9
8
  autorequire:
10
- bindir: exe
9
+ bindir: bin
11
10
  cert_chain: []
12
- date: 2022-03-07 00:00:00.000000000 Z
11
+ date: 2022-12-04 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
14
27
  - !ruby/object:Gem::Dependency
15
28
  name: http
16
29
  requirement: !ruby/object:Gem::Requirement
17
30
  requirements:
18
- - - "~>"
31
+ - - ">="
19
32
  - !ruby/object:Gem::Version
20
- version: '5.0'
33
+ version: '0'
21
34
  type: :runtime
22
35
  prerelease: false
23
36
  version_requirements: !ruby/object:Gem::Requirement
24
37
  requirements:
25
- - - "~>"
38
+ - - ">="
26
39
  - !ruby/object:Gem::Version
27
- version: '5.0'
40
+ version: '0'
28
41
  - !ruby/object:Gem::Dependency
29
- name: rubocop-shopify
42
+ name: byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
30
71
  requirement: !ruby/object:Gem::Requirement
31
72
  requirements:
32
73
  - - "~>"
33
74
  - !ruby/object:Gem::Version
34
- version: '2.3'
75
+ version: '3.0'
35
76
  type: :development
36
77
  prerelease: false
37
78
  version_requirements: !ruby/object:Gem::Requirement
38
79
  requirements:
39
80
  - - "~>"
40
81
  - !ruby/object:Gem::Version
41
- version: '2.3'
42
- description:
82
+ version: '3.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rubocop-shopify
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: ruby-lsp
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: Ruby wrapper for Qiscus Omnichannel public API
43
112
  email:
44
- - nurcholis@qiscus.com
113
+ - developer@qiscus.net
45
114
  executables: []
46
115
  extensions: []
47
116
  extra_rdoc_files: []
48
117
  files:
49
- - ".editorconfig"
50
- - ".gitignore"
51
118
  - ".rspec"
52
119
  - ".rubocop.yml"
53
120
  - ".ruby-version"
54
- - CODE_OF_CONDUCT.md
55
121
  - Gemfile
56
122
  - Gemfile.lock
57
- - LICENSE.txt
58
123
  - README.md
59
124
  - Rakefile
60
125
  - lib/qismo.rb
126
+ - lib/qismo/api.rb
61
127
  - lib/qismo/client.rb
62
- - lib/qismo/errors.rb
63
- - lib/qismo/helpers/base_helper.rb
64
- - lib/qismo/models/agent.rb
65
- - lib/qismo/models/base.rb
66
- - lib/qismo/models/bot.rb
67
- - lib/qismo/models/null_object.rb
68
- - lib/qismo/models/office_hour.rb
69
- - lib/qismo/models/office_setting.rb
70
- - lib/qismo/models/room.rb
71
- - lib/qismo/models/user.rb
72
- - lib/qismo/operations.rb
73
- - lib/qismo/resources/agent_resource.rb
74
- - lib/qismo/resources/bot_resource.rb
75
- - lib/qismo/resources/office_setting_resource.rb
76
- - lib/qismo/resources/room_resource.rb
77
- - lib/qismo/resources/user_resource.rb
78
- - lib/qismo/response.rb
128
+ - lib/qismo/error.rb
129
+ - lib/qismo/model.rb
79
130
  - lib/qismo/version.rb
80
- - qismo.gemspec
81
- homepage: https://multichannel.qiscus.com
131
+ homepage: https://qiscus.com
82
132
  licenses:
83
133
  - MIT
84
- metadata: {}
134
+ metadata:
135
+ allowed_push_host: https://rubygems.org
136
+ source_code_uri: https://bitbucket.org/qiscus/qismo-rb
85
137
  post_install_message:
86
138
  rdoc_options: []
87
139
  require_paths:
@@ -100,5 +152,5 @@ requirements: []
100
152
  rubygems_version: 3.1.6
101
153
  signing_key:
102
154
  specification_version: 4
103
- summary: Qiscus Multichannel Ruby Client
155
+ summary: Qiscus Omnichannel Ruby Gem
104
156
  test_files: []
data/.editorconfig DELETED
@@ -1,9 +0,0 @@
1
- root = true
2
-
3
- [*]
4
- indent_style = space
5
- indent_size = 2
6
- end_of_line = lf
7
- charset = utf-8
8
- trim_trailing_whitespace = true
9
- insert_final_newline = true
data/.gitignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /spec/reports/
8
- /tmp/
9
-
10
- # rspec failure tracking
11
- .rspec_status
12
- *.gem