novofon 1.0.1

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 07dc9c80b904fee74f95a5477d351182e456c704b17cc31f2af712aa6da490fa
4
+ data.tar.gz: 651f97c33655813ccb05c3616e400570c0a902ce74a27cf6d1cf0675004b57e4
5
+ SHA512:
6
+ metadata.gz: 105486b33fb55c82269e6c895ea8a6618deedfd8e68f0c507b7ffb83936306f4996f3640d50bd1f1a09329fb55b36441adccc645182693fe6450ae10b7beaf61
7
+ data.tar.gz: dfc8e79de0b4304d39e61ab19268eafccc7a3f21cd62bdd326e72c21f21666a8a65130daa32bb2f9c482ba15250d0d17cb403ff4ff65d5e4b7e5830b3cf4c396
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,19 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.6
3
+
4
+ Style/StringLiterals:
5
+ Enabled: true
6
+ EnforcedStyle: double_quotes
7
+
8
+ Style/StringLiteralsInInterpolation:
9
+ Enabled: true
10
+ EnforcedStyle: double_quotes
11
+
12
+ Style/Documentation:
13
+ Enabled: false
14
+
15
+ Metrics:
16
+ Enabled: false
17
+
18
+ Layout/LineLength:
19
+ Max: 120
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2023 Vladislav Kostikov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,27 @@
1
+ # Novofon
2
+
3
+ ## Installation
4
+
5
+ Add this line to your application's Gemfile:
6
+
7
+ gem "novofon"
8
+
9
+ And then execute:
10
+
11
+ $ bundle install
12
+
13
+ Or install it yourself as:
14
+
15
+ $ gem install novofon
16
+
17
+ ## Usage
18
+
19
+ Novofon.api_key = "YOUR_API_KEY"
20
+ Novofon.api_secret = "YOUR_API_SECRET"
21
+ Novofon.log_requests = false # default
22
+
23
+ Novofon::Client.balance
24
+ or
25
+
26
+ client = Novofon::Client.new("YOUR_API_KEY", "YOUR_API_SECRET")
27
+ client.balance
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest/md5"
4
+ require "openssl"
5
+ require "base64"
6
+ require "faraday"
7
+
8
+ module Novofon
9
+ class Client
10
+ include Methods
11
+
12
+ def initialize(api_key, api_secret)
13
+ @api_key = api_key
14
+ @api_secret = api_secret
15
+ end
16
+
17
+ def request(method, path, params = {})
18
+ raise "No auth data provided" unless @api_key && @api_secret
19
+
20
+ params.merge!(format: "json")
21
+
22
+ response = client.send(method, "/v1#{path}", params) do |request|
23
+ request.headers["Accept"] = "application/json"
24
+ request.headers["Authorization"] = "#{@api_key}:#{signature("/v1#{path}", params)}"
25
+ end
26
+
27
+ result = ActiveSupport::JSON.decode(response.body).with_indifferent_access
28
+ raise Novofon::Error, "Error [HTTP #{response.status}]: #{result[:message]} " unless result[:status] == "success"
29
+
30
+ result.except("status")
31
+ rescue ActiveSupport::JSON.parse_error
32
+ raise Novofon::Error, "Response is not JSON: #{response.body}"
33
+ end
34
+
35
+ protected
36
+
37
+ def client
38
+ @client ||= ::Faraday.new(url: "https://api.novofon.com") do |faraday|
39
+ faraday.request :url_encoded
40
+ faraday.response :logger if Novofon.log_requests
41
+ faraday.adapter Faraday.default_adapter
42
+ end
43
+ end
44
+
45
+ def signature(url, params)
46
+ query = Hash[params.sort].to_query
47
+ sign_str = url + query + Digest::MD5.hexdigest(query)
48
+ Base64.encode64(OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha1"), @api_secret, sign_str)).strip
49
+ end
50
+
51
+ # Class methods
52
+ class << self
53
+ include Methods
54
+
55
+ def request(method, path, params = {})
56
+ # Make instance and execute request
57
+ object = Novofon::Client.new(Novofon.api_key, Novofon.api_secret)
58
+ object.request(method, path, params)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Novofon
4
+ class Error < StandardError
5
+ end
6
+ end
@@ -0,0 +1,102 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Novofon
4
+ module Methods
5
+ def balance
6
+ request :get, "/info/balance/"
7
+ end
8
+
9
+ def price(number)
10
+ request :get, "/info/price/", number: number
11
+ end
12
+
13
+ def callback(from, to, params = {})
14
+ request :get, "/request/callback/", params.merge(from: from, to: to)
15
+ end
16
+
17
+ def sip
18
+ request :get, "/sip/"
19
+ end
20
+
21
+ def set_sip_caller(id, number)
22
+ request :put, "/sip/callerid/", id: id, number: number
23
+ end
24
+
25
+ def redirection(params = {})
26
+ request :get, "/sip/redirection/", params
27
+ end
28
+
29
+ def set_redirect(id, params)
30
+ request :put, "/sip/redirection/", params.merge(id: id)
31
+ end
32
+
33
+ def pbx_record_request(call_id: nil, pbx_call_id: nil, **params)
34
+ request :get, "/pbx/record/request/", params.merge(call_id: call_id, pbx_call_id: pbx_call_id)
35
+ end
36
+
37
+ def pbx_internal
38
+ request :get, "/pbx/internal/"
39
+ end
40
+
41
+ def pbx_record(id, status, params = {})
42
+ request :put, "/pbx/internal/recording/", params.merge(id: id, status: status)
43
+ end
44
+
45
+ def send_sms(number, message, params = {})
46
+ request :post, "/sms/send/", params.merge(number: number, message: message)
47
+ end
48
+
49
+ def statistics(time_start, time_end, params = {})
50
+ result = request :get, "/statistics/", params.merge(start: time_s(time_start), end: time_s(time_end))
51
+
52
+ result[:start] = Time.parse(result[:start])
53
+ result[:end] = Time.parse(result[:end])
54
+ result[:stats].each { |item| item[:callstart] = Time.parse(item[:callstart]) }
55
+
56
+ result
57
+ end
58
+
59
+ def pbx_statistics(time_start, time_end)
60
+ request :get, "/statistics/pbx/", start: time_s(time_start), end: time_s(time_end)
61
+ end
62
+
63
+ def direct_numbers
64
+ request :get, "/direct_numbers/"
65
+ end
66
+
67
+ def direct_numbers_available(direction_id)
68
+ request :get, "/direct_numbers/available/#{direction_id}/"
69
+ end
70
+
71
+ def direct_numbers_countries
72
+ request :get, "/direct_numbers/countries"
73
+ end
74
+
75
+ def direct_numbers_country(country_code)
76
+ request :get, "/direct_numbers/country", country: country_code
77
+ end
78
+
79
+ def direct_numbers_order(number_id,
80
+ period = nil,
81
+ direction_id = nil,
82
+ documents_group_id = nil,
83
+ purpose = nil,
84
+ receive_sms = nil,
85
+ user_id = nil)
86
+ params = { number_id: number_id,
87
+ period: period,
88
+ direction_id: direction_id,
89
+ documents_group_id: documents_group_id,
90
+ purpose: purpose,
91
+ receive_sms: receive_sms }
92
+ params[:user_id] = user_id unless user_id.nil?
93
+ request :post, "/direct_numbers/order", params
94
+ end
95
+
96
+ protected
97
+
98
+ def time_s(value)
99
+ value.to_time.strftime "%Y-%m-%d %H:%M:%S" if value.present?
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Novofon
4
+ VERSION = "1.0.1"
5
+ end
data/lib/novofon.rb ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support"
4
+ require "active_support/core_ext"
5
+ require "active_support/json"
6
+ require "active_support/hash_with_indifferent_access"
7
+
8
+ require_relative "novofon/version"
9
+
10
+ require "novofon/methods"
11
+ require "novofon/client"
12
+ require "novofon/error"
13
+
14
+ module Novofon
15
+ mattr_accessor :api_key, :api_secret, :log_requests
16
+ end
data/novofon.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/novofon/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "novofon"
7
+ spec.version = Novofon::VERSION
8
+ spec.date = "2023-10-18"
9
+ spec.authors = ["Vladislav Kostikov"]
10
+ spec.email = ["vlad@kostikov.ru"]
11
+
12
+ spec.summary = "novofon.com"
13
+ spec.homepage = "https://github.com/vladkostikov/novofon"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.6.0"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = spec.homepage
19
+
20
+ spec.files = Dir.chdir(__dir__) do
21
+ `git ls-files -z`.split("\x0").reject do |f|
22
+ (File.expand_path(f) == __FILE__) ||
23
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .circleci appveyor Gemfile])
24
+ end
25
+ end
26
+ spec.bindir = "exe"
27
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ["lib"]
29
+
30
+ spec.add_dependency "activesupport"
31
+ spec.add_dependency "faraday"
32
+ spec.add_dependency "json"
33
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: novofon
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Vladislav Kostikov
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2023-10-18 00:00:00.000000000 Z
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'
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: json
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description:
56
+ email:
57
+ - vlad@kostikov.ru
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".rspec"
63
+ - ".rubocop.yml"
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - lib/novofon.rb
68
+ - lib/novofon/client.rb
69
+ - lib/novofon/error.rb
70
+ - lib/novofon/methods.rb
71
+ - lib/novofon/version.rb
72
+ - novofon.gemspec
73
+ homepage: https://github.com/vladkostikov/novofon
74
+ licenses:
75
+ - MIT
76
+ metadata:
77
+ homepage_uri: https://github.com/vladkostikov/novofon
78
+ source_code_uri: https://github.com/vladkostikov/novofon
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: 2.6.0
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ version: '0'
93
+ requirements: []
94
+ rubygems_version: 3.4.21
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: novofon.com
98
+ test_files: []