didww-v3 1.0.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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +313 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/LICENSE.txt +21 -0
- data/README.md +57 -0
- data/Rakefile +6 -0
- data/bin/console +19 -0
- data/bin/setup +8 -0
- data/didww-v3.gemspec +46 -0
- data/lib/didww.rb +3 -0
- data/lib/didww/client.rb +120 -0
- data/lib/didww/complex_objects/base.rb +89 -0
- data/lib/didww/complex_objects/cdr_export_filter.rb +23 -0
- data/lib/didww/complex_objects/configurations.rb +11 -0
- data/lib/didww/complex_objects/configurations/base.rb +11 -0
- data/lib/didww/complex_objects/configurations/const.rb +149 -0
- data/lib/didww/complex_objects/configurations/h323_configuration.rb +35 -0
- data/lib/didww/complex_objects/configurations/iax2_configuration.rb +45 -0
- data/lib/didww/complex_objects/configurations/pstn_configuration.rb +16 -0
- data/lib/didww/complex_objects/configurations/sip_configuration.rb +203 -0
- data/lib/didww/complex_objects/did_order_item.rb +14 -0
- data/lib/didww/middleware.rb +18 -0
- data/lib/didww/resources/balance.rb +20 -0
- data/lib/didww/resources/base.rb +29 -0
- data/lib/didww/resources/cdr_export.rb +47 -0
- data/lib/didww/resources/city.rb +9 -0
- data/lib/didww/resources/country.rb +17 -0
- data/lib/didww/resources/did.rb +49 -0
- data/lib/didww/resources/did_group.rb +66 -0
- data/lib/didww/resources/did_group_type.rb +9 -0
- data/lib/didww/resources/order.rb +67 -0
- data/lib/didww/resources/region.rb +9 -0
- data/lib/didww/resources/stock_keeping_unit.rb +19 -0
- data/lib/didww/resources/trunk.rb +70 -0
- data/lib/didww/resources/trunk/const.rb +61 -0
- data/lib/didww/resources/trunk_group.rb +23 -0
- data/lib/didww/version.rb +3 -0
- metadata +307 -0
data/bin/setup
ADDED
data/didww-v3.gemspec
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'didww/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = 'didww-v3'
|
8
|
+
spec.version = DIDWW::VERSION
|
9
|
+
spec.authors = ['Alex Korobeinikov']
|
10
|
+
spec.email = ['alex.k@didww.com']
|
11
|
+
|
12
|
+
spec.summary = %q{Ruby client for DIDWW API v3}
|
13
|
+
spec.description = %q{Ruby client for DIDWW API v3}
|
14
|
+
spec.homepage = 'https://github.com/didww/didww-v3-ruby'
|
15
|
+
spec.license = 'MIT'
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
18
|
+
f.match(%r{^(test|spec|features)/})
|
19
|
+
end
|
20
|
+
spec.bindir = 'exe'
|
21
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
+
spec.require_paths = ['lib']
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
|
28
|
+
# development
|
29
|
+
spec.add_development_dependency 'pry'
|
30
|
+
spec.add_development_dependency 'byebug'
|
31
|
+
spec.add_development_dependency 'awesome_print'
|
32
|
+
spec.add_development_dependency 'http_logger'
|
33
|
+
spec.add_development_dependency 'rubocop'
|
34
|
+
|
35
|
+
# test
|
36
|
+
spec.add_development_dependency 'simplecov'
|
37
|
+
spec.add_development_dependency 'smart_rspec'
|
38
|
+
spec.add_development_dependency 'webmock'
|
39
|
+
|
40
|
+
spec.add_dependency 'activesupport'
|
41
|
+
spec.add_dependency 'faraday'
|
42
|
+
spec.add_dependency 'json_api_client'
|
43
|
+
spec.add_dependency 'http'
|
44
|
+
spec.add_dependency 'down'
|
45
|
+
|
46
|
+
end
|
data/lib/didww.rb
ADDED
data/lib/didww/client.rb
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'active_support/core_ext/module/attribute_accessors'
|
2
|
+
require 'json_api_client'
|
3
|
+
|
4
|
+
require 'didww/resources/base'
|
5
|
+
|
6
|
+
module DIDWW
|
7
|
+
module Client
|
8
|
+
BASE_URLS = {
|
9
|
+
sandbox: 'https://sandbox-api.didww.com/v3/' .freeze,
|
10
|
+
production: 'https://api.didww.com/v3/' .freeze
|
11
|
+
}.freeze
|
12
|
+
DEFAULT_MODE = :sandbox
|
13
|
+
|
14
|
+
mattr_accessor :api_key, :api_mode, :http_verbose
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def configure
|
18
|
+
yield self if block_given?
|
19
|
+
connect!
|
20
|
+
require_didww_resources
|
21
|
+
self
|
22
|
+
end
|
23
|
+
|
24
|
+
def api_mode
|
25
|
+
@@api_mode || DEFAULT_MODE
|
26
|
+
end
|
27
|
+
|
28
|
+
def api_key
|
29
|
+
@@api_key
|
30
|
+
end
|
31
|
+
|
32
|
+
def api_base_url
|
33
|
+
BASE_URLS[api_mode]
|
34
|
+
end
|
35
|
+
|
36
|
+
def balance
|
37
|
+
Resource::Balance.all.first
|
38
|
+
end
|
39
|
+
|
40
|
+
def cities
|
41
|
+
Resource::City
|
42
|
+
end
|
43
|
+
|
44
|
+
def countries
|
45
|
+
Resource::Country
|
46
|
+
end
|
47
|
+
|
48
|
+
def did_group_types
|
49
|
+
Resource::DidGroupType
|
50
|
+
end
|
51
|
+
|
52
|
+
def did_groups
|
53
|
+
Resource::DidGroup
|
54
|
+
end
|
55
|
+
|
56
|
+
def dids
|
57
|
+
Resource::Did
|
58
|
+
end
|
59
|
+
|
60
|
+
def orders
|
61
|
+
Resource::Order
|
62
|
+
end
|
63
|
+
|
64
|
+
def regions
|
65
|
+
Resource::Region
|
66
|
+
end
|
67
|
+
|
68
|
+
def trunk_groups
|
69
|
+
Resource::TrunkGroup
|
70
|
+
end
|
71
|
+
|
72
|
+
def trunks
|
73
|
+
Resource::Trunk
|
74
|
+
end
|
75
|
+
|
76
|
+
def cdr_exports
|
77
|
+
Resource::CdrExport
|
78
|
+
end
|
79
|
+
|
80
|
+
def api_mode=(arg)
|
81
|
+
unless BASE_URLS.keys.include?(arg)
|
82
|
+
raise ArgumentError.new("Mode should be in #{BASE_URLS.keys} (given '#{arg}').")
|
83
|
+
end
|
84
|
+
@@api_mode = arg
|
85
|
+
end
|
86
|
+
|
87
|
+
private
|
88
|
+
|
89
|
+
def http_verbose?
|
90
|
+
ENV['HTTP_VERBOSE'] == 'true' || http_verbose
|
91
|
+
end
|
92
|
+
|
93
|
+
def connect!
|
94
|
+
DIDWW::Resource::Base.site = api_base_url
|
95
|
+
DIDWW::Resource::Base.connection do |connection|
|
96
|
+
connection.use Faraday::Response::Logger if http_verbose?
|
97
|
+
connection.use DIDWW::Middleware
|
98
|
+
end
|
99
|
+
JsonApiClient::Paginating::Paginator.page_param = 'number'
|
100
|
+
JsonApiClient::Paginating::Paginator.per_page_param = 'size'
|
101
|
+
end
|
102
|
+
|
103
|
+
def require_didww_resources
|
104
|
+
require 'didww/resources/balance'
|
105
|
+
require 'didww/resources/city'
|
106
|
+
require 'didww/resources/country'
|
107
|
+
require 'didww/resources/did_group_type'
|
108
|
+
require 'didww/resources/did_group'
|
109
|
+
require 'didww/resources/did'
|
110
|
+
require 'didww/resources/order'
|
111
|
+
require 'didww/resources/region'
|
112
|
+
require 'didww/resources/trunk_group'
|
113
|
+
require 'didww/resources/trunk'
|
114
|
+
require 'didww/resources/stock_keeping_unit'
|
115
|
+
require 'didww/resources/cdr_export'
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
require 'json_api_client/schema'
|
2
|
+
|
3
|
+
module DIDWW
|
4
|
+
module ComplexObject
|
5
|
+
class Base
|
6
|
+
class << self
|
7
|
+
# Specifies the JSON API resource type. By default this is inferred
|
8
|
+
# from the resource class name.
|
9
|
+
def type
|
10
|
+
name.demodulize.underscore.pluralize
|
11
|
+
end
|
12
|
+
|
13
|
+
def property(name, options = {})
|
14
|
+
property = schema.add(name, options)
|
15
|
+
define_method(name) { attributes[name] }
|
16
|
+
define_method("#{name}=".to_sym) do |val|
|
17
|
+
attributes[name] = property.cast(val)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def schema
|
22
|
+
@schema ||= JsonApiClient::Schema.new
|
23
|
+
end
|
24
|
+
|
25
|
+
# Type casting for JsonApiClient parser/setters
|
26
|
+
def cast(value, default)
|
27
|
+
case value
|
28
|
+
when self
|
29
|
+
value
|
30
|
+
when Hash
|
31
|
+
cast_single_object(value)
|
32
|
+
when Array
|
33
|
+
value.map { |item| cast(item, item) }
|
34
|
+
else
|
35
|
+
default
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
|
41
|
+
def cast_single_object(hash)
|
42
|
+
hash = hash.with_indifferent_access
|
43
|
+
klass = class_for_type(hash[:type])
|
44
|
+
klass ? klass.new(hash[:attributes] || {}) : hash
|
45
|
+
end
|
46
|
+
|
47
|
+
# Returns a ComplexObject class if given JSON API type matches any
|
48
|
+
def class_for_type(type)
|
49
|
+
"#{parent.name}::#{type.classify}".safe_constantize
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def type
|
54
|
+
self.class.type
|
55
|
+
end
|
56
|
+
|
57
|
+
def attributes
|
58
|
+
@attributes ||= ActiveSupport::HashWithIndifferentAccess.new
|
59
|
+
end
|
60
|
+
|
61
|
+
def initialize(params = {})
|
62
|
+
params.each { |k, v| self[k] = v }
|
63
|
+
self.class.schema.each_property do |property|
|
64
|
+
attributes[property.name] = property.default unless attributes.has_key?(property.name) || property.default.nil?
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def [](key)
|
69
|
+
attributes[key]
|
70
|
+
end
|
71
|
+
|
72
|
+
def []=(key, value)
|
73
|
+
public_send("#{key}=", value)
|
74
|
+
end
|
75
|
+
|
76
|
+
# When we represent this resource for serialization (create/update), we do so
|
77
|
+
# with this implementation
|
78
|
+
def as_json(*)
|
79
|
+
{ type: type }.with_indifferent_access.tap do |h|
|
80
|
+
h[:attributes] = attributes.as_json
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def as_json_api(*); as_json end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
JsonApiClient::Schema.register complex_object: DIDWW::ComplexObject::Base
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'json_api_client/schema'
|
2
|
+
|
3
|
+
module DIDWW
|
4
|
+
module ComplexObject
|
5
|
+
class CdrExportFilter < Base
|
6
|
+
# Type casting for JsonApiClient parser/setters
|
7
|
+
def self.cast_single_object(hash)
|
8
|
+
new(hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
property :year, type: :integer
|
12
|
+
property :month, type: :integer
|
13
|
+
property :did_number, type: :string
|
14
|
+
|
15
|
+
def as_json(*)
|
16
|
+
super[:attributes]
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
JsonApiClient::Schema.register cdr_export_filter: DIDWW::ComplexObject::CdrExportFilter
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'didww/complex_objects/configurations/base'
|
2
|
+
require 'didww/complex_objects/configurations/sip_configuration'
|
3
|
+
require 'didww/complex_objects/configurations/iax2_configuration'
|
4
|
+
require 'didww/complex_objects/configurations/pstn_configuration'
|
5
|
+
require 'didww/complex_objects/configurations/h323_configuration'
|
6
|
+
|
7
|
+
module DIDWW
|
8
|
+
module ComplexObject
|
9
|
+
include Configuration
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
module DIDWW
|
2
|
+
module ComplexObject
|
3
|
+
module Configuration
|
4
|
+
module CONST
|
5
|
+
RX_DTMF_FORMATS = {
|
6
|
+
1 => 'RFC 2833' .freeze,
|
7
|
+
2 => 'SIP INFO application/dtmf-relay OR application/dtmf'.freeze,
|
8
|
+
3 => 'RFC 2833 OR SIP INFO' .freeze
|
9
|
+
}.freeze
|
10
|
+
|
11
|
+
TX_DTMF_FORMATS = {
|
12
|
+
0 => 'Disable sending' .freeze,
|
13
|
+
1 => 'RFC 2833' .freeze,
|
14
|
+
2 => 'SIP INFO application/dtmf-relay' .freeze,
|
15
|
+
4 => 'SIP INFO application/dtmf' .freeze
|
16
|
+
}.freeze
|
17
|
+
|
18
|
+
SST_REFRESH_METHODS = {
|
19
|
+
1 => 'Invite' .freeze,
|
20
|
+
2 => 'Update' .freeze,
|
21
|
+
3 => 'Update fallback Invite' .freeze
|
22
|
+
}.freeze
|
23
|
+
|
24
|
+
TRANSPORT_PROTOCOLS = {
|
25
|
+
1 => 'UDP' .freeze,
|
26
|
+
2 => 'TCP' .freeze
|
27
|
+
}.freeze
|
28
|
+
|
29
|
+
REROUTING_DISCONNECT_CODES = {
|
30
|
+
56 => '400 | Bad Request' .freeze,
|
31
|
+
57 => '401 | Unauthorized' .freeze,
|
32
|
+
58 => '402 | Payment Required' .freeze,
|
33
|
+
59 => '403 | Forbidden' .freeze,
|
34
|
+
60 => '404 | Not Found' .freeze,
|
35
|
+
64 => '408 | Request Timeout' .freeze,
|
36
|
+
65 => '409 | Conflict' .freeze,
|
37
|
+
66 => '410 | Gone' .freeze,
|
38
|
+
67 => '412 | Conditional Request Failed' .freeze,
|
39
|
+
68 => '413 | Request Entity Too Large' .freeze,
|
40
|
+
69 => '414 | Request-URI Too Long' .freeze,
|
41
|
+
70 => '415 | Unsupported Media Type' .freeze,
|
42
|
+
71 => '416 | Unsupported URI Scheme' .freeze,
|
43
|
+
72 => '417 | Unknown Resource-Priority' .freeze,
|
44
|
+
73 => '420 | Bad Extension' .freeze,
|
45
|
+
74 => '421 | Extension Required' .freeze,
|
46
|
+
75 => '422 | Session Interval Too Small' .freeze,
|
47
|
+
76 => '423 | Interval Too Brief' .freeze,
|
48
|
+
77 => '424 | Bad Location Information' .freeze,
|
49
|
+
78 => '428 | Use Identity Header' .freeze,
|
50
|
+
79 => '429 | Provide Referrer Identity' .freeze,
|
51
|
+
80 => '433 | Anonymity Disallowed' .freeze,
|
52
|
+
81 => '436 | Bad Identity-Info' .freeze,
|
53
|
+
82 => '437 | Unsupported Certificate' .freeze,
|
54
|
+
83 => '438 | Invalid Identity Header' .freeze,
|
55
|
+
84 => '480 | Temporarily Unavailable' .freeze,
|
56
|
+
86 => '482 | Loop Detected' .freeze,
|
57
|
+
87 => '483 | Too Many Hops' .freeze,
|
58
|
+
88 => '484 | Address Incomplete' .freeze,
|
59
|
+
89 => '485 | Ambiguous' .freeze,
|
60
|
+
90 => '486 | Busy Here' .freeze,
|
61
|
+
91 => '487 | Request Terminated' .freeze,
|
62
|
+
92 => '488 | Not Acceptable Here' .freeze,
|
63
|
+
96 => '494 | Security Agreement Required' .freeze,
|
64
|
+
97 => '500 | Server Internal Error' .freeze,
|
65
|
+
98 => '501 | Not Implemented' .freeze,
|
66
|
+
99 => '502 | Bad Gateway' .freeze,
|
67
|
+
100 => '503 | Service Unavailable' .freeze,
|
68
|
+
101 => '504 | Server Time-out' .freeze,
|
69
|
+
102 => '505 | Version Not Supported' .freeze,
|
70
|
+
103 => '513 | Message Too Large' .freeze,
|
71
|
+
104 => '580 | Precondition Failure' .freeze,
|
72
|
+
105 => '600 | Busy Everywhere' .freeze,
|
73
|
+
106 => '603 | Decline' .freeze,
|
74
|
+
107 => '604 | Does Not Exist Anywhere' .freeze,
|
75
|
+
108 => '606 | Not Acceptable' .freeze,
|
76
|
+
1505 => 'Ringing timeout' .freeze
|
77
|
+
}.freeze
|
78
|
+
|
79
|
+
CODECS = {
|
80
|
+
6 => 'telephone-event' .freeze,
|
81
|
+
7 => 'G723' .freeze,
|
82
|
+
8 => 'G729' .freeze,
|
83
|
+
9 => 'PCMU' .freeze,
|
84
|
+
10 => 'PCMA' .freeze,
|
85
|
+
12 => 'speex' .freeze,
|
86
|
+
13 => 'GSM' .freeze,
|
87
|
+
14 => 'G726-32' .freeze,
|
88
|
+
15 => 'G721' .freeze,
|
89
|
+
16 => 'G726-24' .freeze,
|
90
|
+
17 => 'G726-40' .freeze,
|
91
|
+
18 => 'G726-16' .freeze,
|
92
|
+
19 => 'L16' .freeze
|
93
|
+
}.freeze
|
94
|
+
|
95
|
+
DEFAULT_REROUTING_DISCONNECT_CODE_IDS = [
|
96
|
+
56,
|
97
|
+
58,
|
98
|
+
59,
|
99
|
+
60,
|
100
|
+
64,
|
101
|
+
65,
|
102
|
+
66,
|
103
|
+
67,
|
104
|
+
68,
|
105
|
+
69,
|
106
|
+
70,
|
107
|
+
71,
|
108
|
+
72,
|
109
|
+
73,
|
110
|
+
74,
|
111
|
+
75,
|
112
|
+
76,
|
113
|
+
77,
|
114
|
+
78,
|
115
|
+
79,
|
116
|
+
80,
|
117
|
+
81,
|
118
|
+
82,
|
119
|
+
83,
|
120
|
+
84,
|
121
|
+
86,
|
122
|
+
87,
|
123
|
+
88,
|
124
|
+
89,
|
125
|
+
90,
|
126
|
+
91,
|
127
|
+
92,
|
128
|
+
96,
|
129
|
+
97,
|
130
|
+
98,
|
131
|
+
99,
|
132
|
+
101,
|
133
|
+
102,
|
134
|
+
103,
|
135
|
+
104,
|
136
|
+
105,
|
137
|
+
106,
|
138
|
+
107,
|
139
|
+
108,
|
140
|
+
1505
|
141
|
+
].freeze
|
142
|
+
|
143
|
+
DEFAULT_CODEC_IDS = [ 9, 10, 8, 7, 6 ].freeze
|
144
|
+
|
145
|
+
DID_PLACEHOLDER = '{DID}'.freeze
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|