qismo 0.1.8 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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