sms77 0.0.2 → 0.1.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 +4 -4
- data/README.md +2 -2
- data/lib/sms77/base.rb +75 -0
- data/lib/sms77/client.rb +14 -52
- data/lib/sms77/{contacts_action.rb → contacts.rb} +2 -2
- data/lib/sms77/endpoint.rb +11 -12
- data/lib/sms77/hooks.rb +58 -0
- data/lib/sms77/{lookup_type.rb → lookup.rb} +2 -2
- data/lib/sms77/util.rb +28 -0
- data/lib/sms77/version.rb +1 -1
- data/sms77.gemspec +12 -15
- data/spec/sms77/balance_spec.rb +1 -6
- data/spec/sms77/client_spec.rb +18 -0
- data/spec/sms77/contacts_spec.rb +21 -20
- data/spec/sms77/hooks_spec.rb +95 -0
- data/spec/sms77/lookup_spec.rb +68 -82
- data/spec/sms77/pricing_spec.rb +23 -27
- data/spec/sms77/sms_spec.rb +17 -17
- data/spec/sms77/validate_for_voice_spec.rb +3 -3
- data/spec/sms77/voice_spec.rb +8 -5
- data/spec/sms77_spec.rb +0 -8
- data/spec/spec_helper.rb +31 -23
- metadata +38 -25
- data/lib/sms77/header.rb +0 -7
- data/spec/sms77/http_spec.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 621b698c5ea5c6f08f25ebb60d427a949fe8a011de54e82623234d4af10e0c7f
|
4
|
+
data.tar.gz: 11e68e54c358e93aacb25e6da5289d2fe904b8def5ef86ce9cdd2b1aac68ae35
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b86d9e8884dad820fc01892f002c5e90de2162a40dd326c8c95c2cda8a404304924aeb02fc460f79f25aa78089d703662530a5e2995060ff2c8d3c9d4bfb6891
|
7
|
+
data.tar.gz: b3650f5844d714e1d925aaf31c8fd8e2b73b49c955220096654044239ef0fa978e3b00a3ae6ced2f8b9818825e8da3aa80ab908f79945204112add325abf78b2
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@
|
|
11
11
|
```ruby
|
12
12
|
require 'sms77'
|
13
13
|
|
14
|
-
client = Sms77::Client.new(ENV['SMS77_API_KEY']
|
14
|
+
client = Sms77::Client.new(ENV['SMS77_API_KEY'])
|
15
15
|
|
16
|
-
puts "Balance: #{client.balance
|
16
|
+
puts "Balance: #{client.balance}"
|
17
17
|
```
|
data/lib/sms77/base.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cgi'
|
4
|
+
require 'json'
|
5
|
+
require 'faraday'
|
6
|
+
require 'sms77/endpoint'
|
7
|
+
|
8
|
+
module Sms77
|
9
|
+
class Base
|
10
|
+
BASE_PATH = '/api/'
|
11
|
+
CONN = Faraday.new("https://gateway.sms77.io#{BASE_PATH}")
|
12
|
+
HTTP_GET = CONN.method(:get).freeze
|
13
|
+
HTTP_POST = CONN.method(:post).freeze
|
14
|
+
CONN.freeze
|
15
|
+
HTTP_METHODS = [HTTP_GET, HTTP_POST].freeze
|
16
|
+
BUILDER = CONN.builder
|
17
|
+
|
18
|
+
def initialize(api_key, sent_with = 'ruby')
|
19
|
+
raise 'missing api_key in config' if api_key.to_s.empty?
|
20
|
+
raise 'missing sent_with in config' if sent_with.to_s.empty?
|
21
|
+
|
22
|
+
@api_key = api_key
|
23
|
+
@sent_with = sent_with
|
24
|
+
|
25
|
+
HTTP_METHODS.each do |method|
|
26
|
+
define_singleton_method(method.name) { |*args| request(method, *args) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
attr_reader :api_key, :sent_with
|
31
|
+
|
32
|
+
protected
|
33
|
+
|
34
|
+
def request(method, path, payload = {})
|
35
|
+
if !payload.empty? && HTTP_GET == method
|
36
|
+
path = "#{path}?#{URI.encode_www_form(payload)}"
|
37
|
+
|
38
|
+
payload = {}
|
39
|
+
end
|
40
|
+
|
41
|
+
method = method.name
|
42
|
+
headers = Hash[
|
43
|
+
Faraday::Request::Authorization::KEY, "Bearer #{@api_key}",
|
44
|
+
'sentWith', @sent_with
|
45
|
+
]
|
46
|
+
|
47
|
+
res = CONN.run_request(method, path, payload, headers)
|
48
|
+
|
49
|
+
puts JSON.pretty_generate(res.to_hash.merge({
|
50
|
+
:method => method,
|
51
|
+
:path => path,
|
52
|
+
:payload => payload,
|
53
|
+
:req_headers => headers
|
54
|
+
}).compact) if ENV['SMS77_DEBUG']
|
55
|
+
|
56
|
+
raise "Error requesting (#{self.class.name}) with code #{res.status}" unless 200 == res.status
|
57
|
+
|
58
|
+
raise 'Unexpected response' unless res.is_a?(Faraday::Response)
|
59
|
+
|
60
|
+
body = res.body
|
61
|
+
|
62
|
+
if body.is_a?(String)
|
63
|
+
begin
|
64
|
+
body = JSON.parse(body, :symbolize_names => true)
|
65
|
+
rescue StandardError
|
66
|
+
# Ignored
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
body.map! { |hash| hash.transform_keys(&:to_sym) } if body.is_a?(Array)
|
71
|
+
|
72
|
+
body
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/sms77/client.rb
CHANGED
@@ -4,27 +4,11 @@ require 'cgi'
|
|
4
4
|
require 'json'
|
5
5
|
require 'faraday'
|
6
6
|
require 'sms77/endpoint'
|
7
|
-
require 'sms77/
|
8
|
-
require 'sms77/
|
7
|
+
require 'sms77/contacts'
|
8
|
+
require 'sms77/base'
|
9
9
|
|
10
10
|
module Sms77
|
11
|
-
class Client
|
12
|
-
def initialize(api_key, conn, sent_with = 'ruby')
|
13
|
-
@api_key = api_key
|
14
|
-
@conn = conn
|
15
|
-
@sent_with = sent_with
|
16
|
-
|
17
|
-
raise 'missing api_key in config' if !@api_key || @api_key.empty?
|
18
|
-
raise 'missing conn in config' unless @conn
|
19
|
-
|
20
|
-
@conn.headers['sentWith'] = @sent_with
|
21
|
-
@conn.authorization :Bearer, @api_key
|
22
|
-
end
|
23
|
-
|
24
|
-
BASE_URI = 'https://gateway.sms77.io'
|
25
|
-
API_SUFFIX = '/api/'
|
26
|
-
API_URI = "#{BASE_URI}#{API_SUFFIX}"
|
27
|
-
|
11
|
+
class Client < Sms77::Base
|
28
12
|
def analytics(params = {})
|
29
13
|
get(Sms77::Endpoint::ANALYTICS, params)
|
30
14
|
end
|
@@ -34,11 +18,17 @@ module Sms77
|
|
34
18
|
end
|
35
19
|
|
36
20
|
def contacts(params)
|
37
|
-
|
21
|
+
get_or_post(Sms77::Contacts::Action::READ == params[:action], Sms77::Endpoint::CONTACTS, params)
|
22
|
+
end
|
23
|
+
|
24
|
+
def hooks(params)
|
25
|
+
Sms77::Hooks::Validator::validate(params)
|
26
|
+
|
27
|
+
get_or_post(Sms77::Hooks::Action::READ == params[:action], Sms77::Endpoint::HOOKS, params)
|
38
28
|
end
|
39
29
|
|
40
30
|
def lookup(params)
|
41
|
-
|
31
|
+
post(Sms77::Endpoint::LOOKUP, params)
|
42
32
|
end
|
43
33
|
|
44
34
|
def pricing(params = {})
|
@@ -54,7 +44,7 @@ module Sms77
|
|
54
44
|
end
|
55
45
|
|
56
46
|
def validate_for_voice(params)
|
57
|
-
|
47
|
+
post(Sms77::Endpoint::VALIDATE_FOR_VOICE, params)
|
58
48
|
end
|
59
49
|
|
60
50
|
def voice(params)
|
@@ -63,36 +53,8 @@ module Sms77
|
|
63
53
|
|
64
54
|
private
|
65
55
|
|
66
|
-
def
|
67
|
-
|
68
|
-
end
|
69
|
-
|
70
|
-
def post(endpoint, params)
|
71
|
-
request(endpoint, 'post', params)
|
72
|
-
end
|
73
|
-
|
74
|
-
def request(endpoint, method, params)
|
75
|
-
url = "#{API_SUFFIX}#{endpoint}"
|
76
|
-
|
77
|
-
if ENV['SMS77_DEBUG']
|
78
|
-
puts "requesting url: #{url}"
|
79
|
-
puts "headers: #{@conn.headers.inspect}"
|
80
|
-
end
|
81
|
-
|
82
|
-
response = if method == 'get'
|
83
|
-
@conn.get(url, params)
|
84
|
-
else
|
85
|
-
@conn.post do |req|
|
86
|
-
req.path = url
|
87
|
-
req.params = params
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
raise "Error requesting (#{self.class.name}) with code: #{response.status}" if response.status != 200
|
92
|
-
|
93
|
-
puts "received body: #{response.body}" if ENV['SMS77_DEBUG']
|
94
|
-
|
95
|
-
response
|
56
|
+
def get_or_post(bool, *args)
|
57
|
+
method(bool ? :get : :post).call(*args)
|
96
58
|
end
|
97
59
|
end
|
98
60
|
end
|
data/lib/sms77/endpoint.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
module Sms77
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
3
|
+
module Sms77::Endpoint
|
4
|
+
ANALYTICS = 'analytics'
|
5
|
+
BALANCE = 'balance'
|
6
|
+
CONTACTS = 'contacts'
|
7
|
+
HOOKS = 'hooks'
|
8
|
+
LOOKUP = 'lookup'
|
9
|
+
PRICING = 'pricing'
|
10
|
+
SMS = 'sms'
|
11
|
+
STATUS = 'status'
|
12
|
+
VALIDATE_FOR_VOICE = 'validate_for_voice'
|
13
|
+
VOICE = 'voice'
|
15
14
|
end
|
data/lib/sms77/hooks.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Sms77::Hooks
|
4
|
+
module Action
|
5
|
+
READ = 'read'
|
6
|
+
SUBSCRIBE = 'subscribe'
|
7
|
+
UNSUBSCRIBE = 'unsubscribe'
|
8
|
+
end
|
9
|
+
|
10
|
+
module EventType
|
11
|
+
NEW_INBOUND_SMS = 'sms_mo'
|
12
|
+
SMS_STATUS_UPDATE = 'dlr'
|
13
|
+
VOICE_STATUS_UPDATE = 'voice_status'
|
14
|
+
end
|
15
|
+
|
16
|
+
module RequestMethod
|
17
|
+
GET = 'GET'
|
18
|
+
POST = 'POST'
|
19
|
+
end
|
20
|
+
|
21
|
+
module Validator
|
22
|
+
def self.validate(params)
|
23
|
+
action = params[:action]
|
24
|
+
|
25
|
+
raise "Unknown action #{action}" unless Sms77::Hooks::Validator::is_action?(action)
|
26
|
+
|
27
|
+
if Sms77::Hooks::Action::SUBSCRIBE == action
|
28
|
+
raise 'Parameter validation failed' unless Sms77::Hooks::Validator::subscribe(params)
|
29
|
+
elsif Sms77::Hooks::Action::UNSUBSCRIBE == action
|
30
|
+
raise 'ID must be a positive integer' unless Sms77::Util::is_positive_integer?(params[:id])
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.subscribe(params)
|
35
|
+
{ :request_method => Sms77::Hooks::RequestMethod::POST }.merge!(params)
|
36
|
+
|
37
|
+
self.event_type?(params[:event_type]) &&
|
38
|
+
self.request_method?(params[:request_method]) &&
|
39
|
+
self.target_url?(params[:target_url])
|
40
|
+
end
|
41
|
+
|
42
|
+
def self.is_action?(str)
|
43
|
+
Sms77::Util::in_module_constants?(str, Sms77::Hooks::Action)
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.event_type?(str)
|
47
|
+
Sms77::Util::in_module_constants?(str, Sms77::Hooks::EventType)
|
48
|
+
end
|
49
|
+
|
50
|
+
def self.request_method?(str)
|
51
|
+
Sms77::Util::in_module_constants?(str, Sms77::Hooks::RequestMethod)
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.target_url?(str)
|
55
|
+
Sms77::Util::is_valid_url?(str)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/lib/sms77/util.rb
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'date'
|
2
|
+
|
3
|
+
module Sms77::Util
|
4
|
+
def self.get_module_constant_values(mod)
|
5
|
+
mod.constants(false).map &mod.method(:const_get)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.is_valid_url?(str)
|
9
|
+
str =~ URI::regexp
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.is_valid_datetime?(str)
|
13
|
+
begin
|
14
|
+
DateTime.parse(str)
|
15
|
+
true
|
16
|
+
rescue ArgumentError
|
17
|
+
false
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.is_positive_integer?(val)
|
22
|
+
/\A\d+\z/.match?(val.to_s)
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.in_module_constants?(needle, mod)
|
26
|
+
get_module_constant_values(mod).include?(needle)
|
27
|
+
end
|
28
|
+
end
|
data/lib/sms77/version.rb
CHANGED
data/sms77.gemspec
CHANGED
@@ -4,22 +4,19 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
4
|
require 'sms77/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
|
-
spec.
|
8
|
-
spec.
|
9
|
-
spec.
|
7
|
+
spec.add_development_dependency 'bundler', '~> 2.1'
|
8
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
9
|
+
spec.add_development_dependency 'rspec', '~> 3.9'
|
10
|
+
spec.add_runtime_dependency 'faraday', '~> 1.1'
|
11
|
+
spec.author = 'sms77 e.K.'
|
10
12
|
spec.description = 'Send SMS & Text2Voice messages via the Sms77.io SMS Gateway.'
|
11
|
-
spec.
|
12
|
-
spec.
|
13
|
+
spec.email = 'support@sms77.io'
|
14
|
+
spec.files = `git ls-files`.split("\n")
|
13
15
|
spec.homepage = 'https://github.com/sms77io/ruby-client'
|
14
16
|
spec.license = 'MIT'
|
15
|
-
spec.
|
16
|
-
spec.
|
17
|
-
spec.
|
18
|
-
spec.test_files = Dir['
|
19
|
-
|
20
|
-
spec.add_runtime_dependency 'faraday', '~> 1'
|
21
|
-
|
22
|
-
spec.add_development_dependency 'bundler', '~> 2.1'
|
23
|
-
spec.add_development_dependency 'rake', '~> 13'
|
24
|
-
spec.add_development_dependency 'rspec', '~> 3.0'
|
17
|
+
spec.name = 'sms77'
|
18
|
+
spec.required_ruby_version = '>= 2.6.0'
|
19
|
+
spec.summary = 'Official API Client for the Sms77.io SMS Gateway'
|
20
|
+
spec.test_files = Dir['spec/**/*']
|
21
|
+
spec.version = Sms77::VERSION
|
25
22
|
end
|
data/spec/sms77/balance_spec.rb
CHANGED
@@ -5,11 +5,6 @@ require 'sms77/endpoint'
|
|
5
5
|
|
6
6
|
RSpec.describe Sms77, 'balance' do
|
7
7
|
it 'returns the account balance' do
|
8
|
-
Helper.
|
9
|
-
|
10
|
-
response = Helper.client.balance
|
11
|
-
|
12
|
-
expect(response.class).to eq(Faraday::Response)
|
13
|
-
expect(response.body.to_f).to be_kind_of(Float)
|
8
|
+
expect(Helper.get(Sms77::Endpoint::BALANCE, 12.34)).to be_a(Float)
|
14
9
|
end
|
15
10
|
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'sms77/endpoint'
|
5
|
+
|
6
|
+
RSpec.describe Sms77, 'client' do
|
7
|
+
it 'checks api key' do
|
8
|
+
expect(Helper.client.api_key).to be_lengthy(String)
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'checks sentWith' do
|
12
|
+
expect(Helper.client.sent_with).to be_lengthy(String)
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'fails authentication' do
|
16
|
+
expect { Sms77::Client.new('') }.to raise_error(RuntimeError)
|
17
|
+
end
|
18
|
+
end
|
data/spec/sms77/contacts_spec.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'spec_helper'
|
4
4
|
require 'sms77/endpoint'
|
5
|
-
require 'sms77/
|
5
|
+
require 'sms77/contacts'
|
6
6
|
|
7
7
|
RSpec.describe Sms77, 'contacts' do
|
8
8
|
$new_contact_id = nil
|
@@ -12,8 +12,8 @@ RSpec.describe Sms77, 'contacts' do
|
|
12
12
|
code, $new_contact_id = response_body.split("\n")
|
13
13
|
$new_contact_id = $new_contact_id.to_i
|
14
14
|
else
|
15
|
-
code = response_body[
|
16
|
-
$new_contact_id = response_body[
|
15
|
+
code = response_body[:return]
|
16
|
+
$new_contact_id = response_body[:id]
|
17
17
|
end
|
18
18
|
|
19
19
|
expect(code).to be_numeric
|
@@ -28,9 +28,9 @@ RSpec.describe Sms77, 'contacts' do
|
|
28
28
|
name = name.gsub('"', '')
|
29
29
|
number = number.gsub('"', '')
|
30
30
|
else
|
31
|
-
id = contact[
|
32
|
-
name = contact[
|
33
|
-
number = contact[
|
31
|
+
id = contact[:ID]
|
32
|
+
name = contact[:Name]
|
33
|
+
number = contact[:Number]
|
34
34
|
end
|
35
35
|
|
36
36
|
expect(id).to be_numeric
|
@@ -39,7 +39,8 @@ RSpec.describe Sms77, 'contacts' do
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def request(action, stub, extra_params = {})
|
42
|
-
Helper.
|
42
|
+
Helper.method(Sms77::Contacts::Action::READ == action ? :get : :post)
|
43
|
+
.call(Sms77::Endpoint::CONTACTS, stub, { action: action }.merge(extra_params))
|
43
44
|
end
|
44
45
|
|
45
46
|
it 'returns all contacts as CSV' do
|
@@ -54,16 +55,16 @@ RSpec.describe Sms77, 'contacts' do
|
|
54
55
|
"2925186";"Tom Tester";"004901234567890"
|
55
56
|
CSV
|
56
57
|
|
57
|
-
body = request(Sms77::
|
58
|
+
body = request(Sms77::Contacts::Action::READ, stub)
|
58
59
|
|
59
|
-
expect(body).to
|
60
|
+
expect(body).to be_a(String)
|
60
61
|
|
61
62
|
body.split("\n").each do |contact|
|
62
63
|
assert_contact(contact)
|
63
64
|
end
|
64
65
|
end
|
65
66
|
|
66
|
-
it 'returns all contacts as
|
67
|
+
it 'returns all contacts as JSON' do
|
67
68
|
stub = [
|
68
69
|
{ ID: '4848436', Name: '', Number: '' },
|
69
70
|
{ ID: '4848437', Name: '', Number: '' },
|
@@ -75,9 +76,9 @@ RSpec.describe Sms77, 'contacts' do
|
|
75
76
|
{ ID: '2925186', Name: 'Tom Tester', Number: '004901234567890' }
|
76
77
|
]
|
77
78
|
|
78
|
-
body = request(Sms77::
|
79
|
+
body = request(Sms77::Contacts::Action::READ, stub, { json: 1 })
|
79
80
|
|
80
|
-
expect(body).to
|
81
|
+
expect(body).to be_a(Array)
|
81
82
|
|
82
83
|
body.each do |contact|
|
83
84
|
assert_contact(contact)
|
@@ -90,29 +91,29 @@ RSpec.describe Sms77, 'contacts' do
|
|
90
91
|
4868400
|
91
92
|
TEXT
|
92
93
|
|
93
|
-
body = request(Sms77::
|
94
|
+
body = request(Sms77::Contacts::Action::WRITE, stub)
|
94
95
|
|
95
|
-
expect(body).to
|
96
|
+
expect(body).to be_a(String)
|
96
97
|
|
97
98
|
assert_new(body)
|
98
99
|
end
|
99
100
|
|
100
101
|
it 'deletes a contact with given ID and return code' do
|
101
|
-
expect(request(Sms77::
|
102
|
+
expect(request(Sms77::Contacts::Action::DEL, 152, { id: $new_contact_id })).to be_a(Integer)
|
102
103
|
end
|
103
104
|
|
104
105
|
it 'creates a contact and returns its ID as JSON' do
|
105
|
-
body = request(Sms77::
|
106
|
+
body = request(Sms77::Contacts::Action::WRITE, { id: 4868401, return: '152' }, { json: 1 })
|
106
107
|
|
107
|
-
expect(body).to
|
108
|
+
expect(body).to be_a(Hash)
|
108
109
|
|
109
110
|
assert_new(body)
|
110
111
|
end
|
111
112
|
|
112
113
|
it 'deletes a contact with given ID and return code as JSON' do
|
113
|
-
body = request(Sms77::
|
114
|
+
body = request(Sms77::Contacts::Action::DEL, { return: '152' }, { id: $new_contact_id, json: 1 })
|
114
115
|
|
115
|
-
expect(body).to
|
116
|
-
expect(body[
|
116
|
+
expect(body).to be_a(Hash)
|
117
|
+
expect(body[:return]).to be_a(String)
|
117
118
|
end
|
118
119
|
end
|