circuit-api 0.0.3 → 0.0.4

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 23247f5936db842f7b63bc6c00b5707397ad61e0177edd78bf50478bdfe7da75
4
- data.tar.gz: '085a1a9e8d2ba382c1802d07ce4711cc051131689a17fc6f256b71f8a7f77be6'
3
+ metadata.gz: 777069f8d87168c91006d0bb012a2a0322fe50efe16085dc4ab4f919298dccac
4
+ data.tar.gz: '092cd21c29a444334ca86e0aa0f160ad95b2a6bee309fa69bff85331e5d47495'
5
5
  SHA512:
6
- metadata.gz: 11073a56bfbacfec85a8e743423f4d33e85d419ed7af7cd8fe1c9ad4ee4d320b9c9e6cf48715e2216fdda18a87bcf1af18bf29161cc53923827a19887f08fd78
7
- data.tar.gz: a2c2c308dfcbcc1f507befc3924368ec18e8002da786e6258234454bea11ea0279bb0f95a712e58d4a96deecaa4163cc416563bf364688e2d4cada0a43b86fd2
6
+ metadata.gz: 6c0ec6716cc22280e738d7f16d956a35de7b7c515f5240d615b3b733a7e837aa8dc46d7dfe5806d63ca87e4fd27628c05dd015491e966d6a852f5545d0cb2821
7
+ data.tar.gz: 2fcf5a9fa29cd7364d33bcaa75ab57db98cca876e20408d750a71b89f61395c300d336b3e2f88772c5461575a8f702a130efb48b384263198646ed3e8b84dceb
@@ -0,0 +1,54 @@
1
+ module CircuitApi
2
+ class Client
3
+ attr_accessor :client_id, :client_secret, :sandbox, :token
4
+
5
+ def initialize(client_id: nil, client_secret: nil, sandbox: nil)
6
+ @client_id = client_id
7
+ @client_secret = client_secret
8
+ @sand_box = sandbox
9
+ end
10
+
11
+ def connect(token)
12
+ # TODO: fetch oauth token
13
+ @token = token
14
+ end
15
+
16
+ def base_url
17
+ return CircuitApi::API_SANDBOX_BASE_URL if sandbox
18
+
19
+ CircuitApi::API_BASE_URL
20
+ end
21
+
22
+ def api_url
23
+ URI.join(base_url, CircuitApi::API_PATH_BASE)
24
+ end
25
+
26
+ def conversations
27
+ CircuitApi::Resources::Conversation.new(self)
28
+ end
29
+
30
+ def labels
31
+ CircuitApi::Resources::Label.new(self)
32
+ end
33
+
34
+ def messages
35
+ CircuitApi::Resources::Message.new(self)
36
+ end
37
+
38
+ def presence
39
+ CircuitApi::Resources::Presence.new(self)
40
+ end
41
+
42
+ def rtc_sessions
43
+ CircuitApi::Resources::RtcSession.new(self)
44
+ end
45
+
46
+ def users
47
+ CircuitApi::Resources::User.new(self)
48
+ end
49
+
50
+ def webhooks
51
+ CircuitApi::Resources::Webhook.new(self)
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,42 @@
1
+ module CircuitApi
2
+ class Resource
3
+ attr_reader :circuit_resource_type
4
+
5
+ def initialize(circuit_resource_type, attributes)
6
+ @circuit_resource_type = circuit_resource_type
7
+ attributes.each do |name, value|
8
+ define_accessors(name)
9
+ send("#{name}=".to_sym, value)
10
+ end
11
+ end
12
+
13
+ def to_json(options = {})
14
+ instance_variables.each_with_object({}) do |variable, result|
15
+ result[variable.to_s.delete('@')] = instance_variable_get(variable)
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def define_accessors(name)
22
+ define_getter(name)
23
+ define_setter(name)
24
+ end
25
+
26
+ def define_setter(name)
27
+ return if self.respond_to?("#{name}=".to_sym)
28
+
29
+ self.class.send(:define_method, "#{name}=".to_sym) do |value|
30
+ instance_variable_set("@#{name.to_s}", value)
31
+ end
32
+ end
33
+
34
+ def define_getter(name)
35
+ return if self.respond_to?(name.to_sym)
36
+
37
+ self.class.send(:define_method, name.to_sym) do
38
+ instance_variable_get("@#{name.to_s}")
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,73 @@
1
+ module CircuitApi
2
+ module Resources
3
+ class Base
4
+ attr_reader :client
5
+
6
+ def initialize(client)
7
+ @client = client
8
+ end
9
+
10
+ def api_resource
11
+ raise NotImplementedError
12
+ end
13
+
14
+ def find(id)
15
+ result = connection("#{api_resource}/#{id}").get
16
+ response_to_object(result)
17
+ end
18
+
19
+ def all(params = {})
20
+ result = connection(api_resource, params).get
21
+ response_to_object(result)
22
+ end
23
+
24
+ def create(params)
25
+ result = connection(api_resource, params).post
26
+ response_to_object(result)
27
+ end
28
+
29
+ def update(id, params)
30
+ result = connection("#{api_resource}/#{id}", params ).put
31
+ response_to_object(result)
32
+ end
33
+
34
+ def delete(id, params = {})
35
+ result = connection("#{api_resource}/#{id}", params).delete
36
+ response_to_object(result)
37
+ end
38
+
39
+ def delete_all(params = {})
40
+ result = connection(api_resource, params).delete
41
+ response_to_object(result)
42
+ end
43
+
44
+ protected
45
+
46
+ def connection(resource_path, params = {})
47
+ CircuitApi::Utils::Connection.new(
48
+ client,
49
+ resource_path,
50
+ CircuitApi::Utils::Attributes.camelize_keys(params)
51
+ )
52
+ end
53
+
54
+ def response_to_object(response)
55
+ case response
56
+ when Hash
57
+ return nil if CircuitApi::Utils::Object.blank?(response)
58
+ to_object(response)
59
+ when Array
60
+ response.map do |item|
61
+ to_object(item)
62
+ end
63
+ end
64
+ end
65
+
66
+ def to_object(values)
67
+ attributes = CircuitApi::Utils::Attributes.snake_keys(values)
68
+ #binding.pry
69
+ CircuitApi::Resource.new('foo', attributes)
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,14 @@
1
+ module CircuitApi
2
+ module Resources
3
+ class Conversation < Base
4
+ def api_resource
5
+ 'conversations'
6
+ end
7
+
8
+ def create_direct(participant)
9
+ result = connection("#{api_resource}/direct", participant: participant).post
10
+ response_to_object(result)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module CircuitApi
2
+ module Resources
3
+ class Label < Base
4
+ def api_resource
5
+ 'users/labels'
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module CircuitApi
2
+ module Resources
3
+ class Message < Base
4
+ def api_resource
5
+ 'conversations/:id/message'
6
+ end
7
+
8
+ def create(conversation_id, params)
9
+ result = connection(
10
+ api_resource.sub(':id', conversation_id),
11
+ params
12
+ ).post
13
+ response_to_object(result)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ module CircuitApi
2
+ module Resources
3
+ class Presence < Base
4
+ def api_resource
5
+ 'users'
6
+ end
7
+
8
+ def update(params)
9
+ result = connection("#{api_resource}/presence", params).put
10
+ response_to_object(result)
11
+ end
12
+
13
+ def all(params)
14
+ result = connection("#{api_resource}/presence", params).get
15
+ response_to_object(result)
16
+ end
17
+
18
+ def find(user_id)
19
+ result = connection("#{api_resource}/#{user_id}/presence").get
20
+ response_to_object(result)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ module CircuitApi
2
+ module Resources
3
+ class RtcSession < Base
4
+ def api_resource
5
+ 'rtc/sessions'
6
+ end
7
+
8
+ def all
9
+ result = connection(api_resource).get
10
+ response_to_object(result)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,29 @@
1
+ module CircuitApi
2
+ module Resources
3
+ class User < Base
4
+ def api_resource
5
+ 'users'
6
+ end
7
+
8
+ def profile
9
+ result = connection("#{api_resource}/profile").get
10
+ response_to_object(result)
11
+ end
12
+
13
+ def update_profile(params)
14
+ result = connection("#{api_resource}/profile", params).put
15
+ response_to_object(result)
16
+ end
17
+
18
+ def find_by_email(email, params = {})
19
+ result = connection("#{api_resource}/#{email}/getUserByEmail", params).get
20
+ response_to_object(result)
21
+ end
22
+
23
+ def search(params)
24
+ result = connection("#{api_resource}/list", params).get
25
+ response_to_object(result)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,19 @@
1
+ module CircuitApi
2
+ module Resources
3
+ class Webhook < Base
4
+ def api_resource
5
+ 'webhooks'
6
+ end
7
+
8
+ def create_presence(params)
9
+ result = connection("#{api_resource}/presence", params).post
10
+ response_to_object(result)
11
+ end
12
+
13
+ def update_presence(id, params)
14
+ result = connection("#{api_resource}/presence/#{id}", params).put
15
+ response_to_object(result)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,58 @@
1
+ module CircuitApi
2
+ module Utils
3
+ module Attributes
4
+ def self.snake_keys(value)
5
+ case value
6
+ when Hash
7
+ snake_hash_keys(value)
8
+ when Array
9
+ value.map { |v| snake_keys(v) }
10
+ else
11
+ value
12
+ end
13
+ end
14
+
15
+ def self.snake_hash_keys(hash)
16
+ Hash[hash.map { |k, v| [underscore_key(k).to_sym, snake_keys(v)] }]
17
+ end
18
+
19
+ def self.underscore_key(key)
20
+ if key.is_a?(Symbol)
21
+ underscore(key.to_s).to_sym
22
+ elsif key.is_a?(String)
23
+ underscore(key)
24
+ else
25
+ key
26
+ end
27
+ end
28
+
29
+ def self.underscore(string)
30
+ string.gsub(/::/, '/')
31
+ .gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2')
32
+ .gsub(/([a-z\d])([A-Z])/,'\1_\2')
33
+ .tr("-", "_")
34
+ .downcase
35
+ end
36
+
37
+ def self.camelize_keys(value)
38
+ return value unless value.is_a?(Hash)
39
+ value.keys.each do |k|
40
+ new_key = camelize(k.to_s, false)
41
+ new_key = new_key.to_sym if k.is_a? Symbol
42
+ value[k].map { |current_array| self.camelize_keys(current_array) } if value[k].is_a?(Array)
43
+ value[new_key] = value.delete(k)
44
+ end
45
+ value
46
+ end
47
+
48
+ def self.camelize(str, uppercase_first_letter = true)
49
+ if uppercase_first_letter
50
+ str = str.sub(/^[a-z\d]*/) { $&.capitalize }
51
+ else
52
+ str = str.sub(/^(?:(?=\b|[A-Z_])|\w)/) { $&.downcase }
53
+ end
54
+ str.gsub(/(?:_|(\/))([a-z\d]*)/) { "#{$1}#{$2.capitalize}" }.gsub('/', '::')
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,79 @@
1
+ module CircuitApi
2
+ module Utils
3
+ class Connection
4
+ RESPONSE_SUCCESS_CODES = [200, 201, 202, 204].freeze
5
+
6
+ attr_reader :client, :action_url, :body
7
+
8
+ def initialize(client, action_url, body = nil)
9
+ @client = client
10
+ @action_url = action_url
11
+ @body = body
12
+ end
13
+
14
+ def get
15
+ perform_query(:get)
16
+ end
17
+
18
+ def post
19
+ perform_query(:post)
20
+ end
21
+
22
+ def put
23
+ perform_query(:put)
24
+ end
25
+
26
+ def delete
27
+ perform_query(:delete)
28
+ end
29
+
30
+ private
31
+
32
+ def http_client
33
+ @http_client ||= Net::HTTP.new(uri.hostname, uri.port)
34
+ .tap { |h| h.use_ssl = true }
35
+ end
36
+
37
+ def uri
38
+ @uri ||= URI.join(client.api_url, action_url)
39
+ end
40
+
41
+ def headers
42
+ {
43
+ 'Authorization' => "Bearer #{client.token}",
44
+ 'Content-Type' => 'application/json; charset=utf-8'
45
+ }
46
+ end
47
+
48
+ def perform_query(verb)
49
+ response = http_client.send_request(
50
+ verb.to_s.upcase,
51
+ uri.path,
52
+ CircuitApi::Utils::Object.blank?(body) ? '' : body.to_json,
53
+ headers
54
+ )
55
+
56
+ raise_error(response) unless RESPONSE_SUCCESS_CODES.include?(response.code.to_i)
57
+
58
+ CircuitApi::Utils::Object.blank?(response.body) ? {} : JSON.parse(response.body)
59
+ end
60
+
61
+ def raise_error(response)
62
+ error_class = case response.code.to_i
63
+ when 400
64
+ CircuitApi::BadRequest
65
+ when 401
66
+ CircuitApi::Unauthorized
67
+ when 500
68
+ CircuitApi::InternalServerError
69
+ when 503
70
+ CircuitApi::ServiceUnavailable
71
+ else
72
+ CircuitApi::HttpError
73
+ end
74
+
75
+ raise error_class.new(response.code, response.body)
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,19 @@
1
+ module CircuitApi
2
+ class HttpError < StandardError
3
+ attr_reader :error_code, :error_body
4
+
5
+ def initialize(code, body)
6
+ @error_code = code
7
+ @error_body = body
8
+ end
9
+
10
+ def message
11
+ "HTTP #{error_code}. Error: #{error_body}"
12
+ end
13
+ end
14
+
15
+ class BadRequest < HttpError; end;
16
+ class Unauthorized < HttpError; end;
17
+ class InternalServerError < HttpError; end;
18
+ class ServiceUnavailable < HttpError; end;
19
+ end
@@ -0,0 +1,13 @@
1
+ module CircuitApi
2
+ module Utils
3
+ module Object
4
+ def self.blank?(object)
5
+ object.respond_to?(:empty?) ? !!object.empty? : !object
6
+ end
7
+
8
+ def self.present?(object)
9
+ !blank?(object)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module CircuitApi
2
+ VERSION = '0.0.4'
3
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: circuit-api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vincent Pochet
@@ -87,6 +87,21 @@ extensions: []
87
87
  extra_rdoc_files: []
88
88
  files:
89
89
  - lib/circuit_api.rb
90
+ - lib/circuit_api/client.rb
91
+ - lib/circuit_api/resource.rb
92
+ - lib/circuit_api/resources/base.rb
93
+ - lib/circuit_api/resources/conversation.rb
94
+ - lib/circuit_api/resources/label.rb
95
+ - lib/circuit_api/resources/message.rb
96
+ - lib/circuit_api/resources/presence.rb
97
+ - lib/circuit_api/resources/rtc_session.rb
98
+ - lib/circuit_api/resources/user.rb
99
+ - lib/circuit_api/resources/webhook.rb
100
+ - lib/circuit_api/utils/attributes.rb
101
+ - lib/circuit_api/utils/connection.rb
102
+ - lib/circuit_api/utils/errors.rb
103
+ - lib/circuit_api/utils/object.rb
104
+ - lib/circuit_api/version.rb
90
105
  homepage:
91
106
  licenses:
92
107
  - MIT