sms-pilot-api-v1 0.0.3 → 0.0.6
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/.gitignore +2 -3
- data/.yardopts +8 -0
- data/CHANGELOG.md +17 -2
- data/Gemfile +1 -0
- data/Gemfile.lock +7 -24
- data/README.md +19 -8
- data/bin/console +2 -5
- data/lib/sms_pilot.rb +0 -1
- data/lib/sms_pilot/client.rb +315 -50
- data/lib/sms_pilot/errors.rb +6 -1
- data/lib/sms_pilot/version.rb +4 -1
- data/sms-pilot-api-v1.gemspec +5 -7
- metadata +7 -21
- data/sms-pilot-api-v1-0.0.2.gem +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: ef5f991fb1af59f48bbc7ccab3e1ab3b417c76fc22a584922fa5bca8879e294c
|
|
4
|
+
data.tar.gz: 83031cf779a24ed4b1d44de6d08f33ef611a0b9fdc63742c14ec792080c54fa5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 84a60a7e124256682fd89d4d411c7402feb6597b0541493c2bd08b88b95a515cdf4ae9c0fb435939d7b6f98a56b2d9dd513cd344023bb2f446fbcffc8507eac0
|
|
7
|
+
data.tar.gz: d0a91bb376ef6090356040cc8eddca2272ce1917e044a7a7cea43f6fe812d265ea1c548eb63e95b5c163a1baed78758bb35a5a0075dea096674bbd4649f0a4ab
|
data/.gitignore
CHANGED
data/.yardopts
ADDED
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
|
-
|
|
1
|
+
# Changelog
|
|
2
2
|
|
|
3
|
-
## [0.
|
|
3
|
+
## [0.0.6] - 9 May 2021
|
|
4
|
+
|
|
5
|
+
- Corrects cost type
|
|
6
|
+
- Switches to PRY in console
|
|
7
|
+
|
|
8
|
+
## [0.0.5] - 9 May 2021
|
|
9
|
+
|
|
10
|
+
- Adds locale support (RU / EN)
|
|
11
|
+
|
|
12
|
+
## [0.0.4] - 9 May 2021
|
|
13
|
+
|
|
14
|
+
- Drop dependence on HTTP.rb gem
|
|
15
|
+
- Corrects what `#send_sms` returns (could return String errors instead of Booleans)
|
|
16
|
+
- Adds extensive [documentation](https://rubydoc.info/github/sergeypedan/sms-pilot-api-v1/master/SmsPilot/Client) via YARD & RubyDoc
|
|
17
|
+
|
|
18
|
+
## [0.0.3] - 6 May 2021
|
|
4
19
|
|
|
5
20
|
- Initial release
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
|
@@ -1,32 +1,17 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
sms-pilot-api-v1 (0.
|
|
5
|
-
http (>= 4.4)
|
|
4
|
+
sms-pilot-api-v1 (0.0.5)
|
|
6
5
|
|
|
7
6
|
GEM
|
|
8
7
|
remote: https://rubygems.org/
|
|
9
8
|
specs:
|
|
10
|
-
|
|
11
|
-
public_suffix (>= 2.0.2, < 5.0)
|
|
9
|
+
coderay (1.1.3)
|
|
12
10
|
diff-lcs (1.4.4)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
ffi (>= 1.0.0)
|
|
18
|
-
rake
|
|
19
|
-
http (4.4.1)
|
|
20
|
-
addressable (~> 2.3)
|
|
21
|
-
http-cookie (~> 1.0)
|
|
22
|
-
http-form_data (~> 2.2)
|
|
23
|
-
http-parser (~> 1.2.0)
|
|
24
|
-
http-cookie (1.0.3)
|
|
25
|
-
domain_name (~> 0.5)
|
|
26
|
-
http-form_data (2.3.0)
|
|
27
|
-
http-parser (1.2.3)
|
|
28
|
-
ffi-compiler (>= 1.0, < 2.0)
|
|
29
|
-
public_suffix (4.0.6)
|
|
11
|
+
method_source (1.0.0)
|
|
12
|
+
pry (0.14.1)
|
|
13
|
+
coderay (~> 1.1)
|
|
14
|
+
method_source (~> 1.0)
|
|
30
15
|
rake (13.0.3)
|
|
31
16
|
rspec (3.10.0)
|
|
32
17
|
rspec-core (~> 3.10.0)
|
|
@@ -41,14 +26,12 @@ GEM
|
|
|
41
26
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
42
27
|
rspec-support (~> 3.10.0)
|
|
43
28
|
rspec-support (3.10.2)
|
|
44
|
-
unf (0.1.4)
|
|
45
|
-
unf_ext
|
|
46
|
-
unf_ext (0.0.7.7)
|
|
47
29
|
|
|
48
30
|
PLATFORMS
|
|
49
31
|
x86_64-darwin-17
|
|
50
32
|
|
|
51
33
|
DEPENDENCIES
|
|
34
|
+
pry
|
|
52
35
|
rake (~> 13.0)
|
|
53
36
|
rspec (~> 3.0)
|
|
54
37
|
sms-pilot-api-v1!
|
data/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# SmsPilot API v1 client
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://badge.fury.io/rb/sms-pilot-api-v1)
|
|
4
|
+
|
|
5
|
+
Simple wrapper around SMS pilot API v1. Version 1 because it returns more data within its standard response.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -16,7 +18,7 @@ from GitHub:
|
|
|
16
18
|
gem "sms-pilot-api-v1", git: "https://github.com/sergeypedan/sms-pilot-api-v1.git"
|
|
17
19
|
```
|
|
18
20
|
|
|
19
|
-
##
|
|
21
|
+
## Playground
|
|
20
22
|
|
|
21
23
|
Test sending SMS from console with a test API key (find it at the end of this page):
|
|
22
24
|
|
|
@@ -25,11 +27,18 @@ cd $(bundle info sms-pilot-api-v1 --path)
|
|
|
25
27
|
bin/console
|
|
26
28
|
```
|
|
27
29
|
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
28
33
|
### Initialize
|
|
29
34
|
|
|
30
35
|
```ruby
|
|
31
|
-
|
|
32
|
-
|
|
36
|
+
require "sms_pilot"
|
|
37
|
+
|
|
38
|
+
key = "XXXXXXXXXXXXYYYYYYYYYYYYZZZZZZZZXXXXXXXXXXXXYYYYYYYYYYYYZZZZZZZZ"
|
|
39
|
+
|
|
40
|
+
client = SmsPilot::Client.new(api_key: key)
|
|
41
|
+
client = SmsPilot::Client.new(api_key: key, locale: :en) # Available locales are [:en, :ru]
|
|
33
42
|
```
|
|
34
43
|
|
|
35
44
|
### Before sending
|
|
@@ -42,7 +51,7 @@ client.phone # => nil
|
|
|
42
51
|
client.rejected? # => false
|
|
43
52
|
client.response_body # => nil
|
|
44
53
|
client.response_data # => {}
|
|
45
|
-
client.response_headers # =>
|
|
54
|
+
client.response_headers # => {}
|
|
46
55
|
client.response_status # => nil
|
|
47
56
|
client.sender_blocked? # => false
|
|
48
57
|
client.sms_cost # => nil
|
|
@@ -54,7 +63,8 @@ client.url # => nil
|
|
|
54
63
|
### Sending SMS
|
|
55
64
|
|
|
56
65
|
```ruby
|
|
57
|
-
client.send_sms("+7 (902) 123-45-67", "Привет, мир!")
|
|
66
|
+
client.send_sms("+7 (902) 123-45-67", "Привет, мир!")
|
|
67
|
+
# => true
|
|
58
68
|
```
|
|
59
69
|
|
|
60
70
|
Returns result of `sms_sent?`, so it’s either `true` or `false`.
|
|
@@ -140,10 +150,11 @@ SMS sent:
|
|
|
140
150
|
|
|
141
151
|
```json
|
|
142
152
|
{
|
|
153
|
+
"balance": "11908.50",
|
|
154
|
+
"cost": "1.68",
|
|
143
155
|
"send": [
|
|
144
156
|
{ "server_id": "10000", "phone": "79021234567", "price": "1.68", "status": "0" }
|
|
145
|
-
]
|
|
146
|
-
"balance": "11908.50", "cost": "1.68"
|
|
157
|
+
]
|
|
147
158
|
}
|
|
148
159
|
```
|
|
149
160
|
|
data/bin/console
CHANGED
|
@@ -8,8 +8,5 @@ require "sms_pilot"
|
|
|
8
8
|
# with your gem easier. You can also use a different console, if you like.
|
|
9
9
|
|
|
10
10
|
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
require "irb"
|
|
15
|
-
IRB.start(__FILE__)
|
|
11
|
+
require "pry"
|
|
12
|
+
Pry.start
|
data/lib/sms_pilot.rb
CHANGED
data/lib/sms_pilot/client.rb
CHANGED
|
@@ -1,16 +1,97 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "
|
|
3
|
+
require "json"
|
|
4
|
+
require "net/https"
|
|
4
5
|
require "uri"
|
|
5
6
|
|
|
6
7
|
module SmsPilot
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
# @!attribute [r] api_key
|
|
10
|
+
# @return [String] Your API key
|
|
11
|
+
#
|
|
12
|
+
# @!attribute [r] error
|
|
13
|
+
# Error message returned from the API, combined with the error code
|
|
14
|
+
# @example
|
|
15
|
+
# client.error #=> "Пользователь временно блокирован (спорная ситуация) (error code: 122)"
|
|
16
|
+
# @return [nil, String]
|
|
17
|
+
# @see #error_code
|
|
18
|
+
# @see #error_description
|
|
19
|
+
#
|
|
20
|
+
# @!attribute [r] locale
|
|
21
|
+
# @return [Symbol] Chosen locale (affects only the language of errors)
|
|
22
|
+
#
|
|
23
|
+
# @!attribute [r] phone
|
|
24
|
+
# @return [nil, String] phone after normalization
|
|
25
|
+
#
|
|
26
|
+
# @!attribute [r] response_body
|
|
27
|
+
# Response format is JSON (because we request it that way in {#build_uri}.
|
|
28
|
+
# @example
|
|
29
|
+
# "{\"send\":[{\"server_id\":\"10000\",\"phone\":\"79021234567\",\"price\":\"1.68\",\"status\":\"0\"}],\"balance\":\"20006.97\",\"cost\":\"1.68\"}"
|
|
30
|
+
# @return [nil, String] Unmodified HTTP resonse body that API returned
|
|
31
|
+
# @see #response_data
|
|
32
|
+
# @see #response_headers
|
|
33
|
+
# @see #response_status
|
|
34
|
+
#
|
|
35
|
+
# @!attribute [r] response_data
|
|
36
|
+
# Parsed <tt>@response_body</tt>. May be an empty <tt>Hash</tt> if parsing fails.
|
|
37
|
+
# @example
|
|
38
|
+
# {
|
|
39
|
+
# "balance" => "20006.97",
|
|
40
|
+
# "cost" => "1.68",
|
|
41
|
+
# "send" => [
|
|
42
|
+
# {
|
|
43
|
+
# "phone" => "79021234567",
|
|
44
|
+
# "price" => "1.68",
|
|
45
|
+
# "server_id" => "10000",
|
|
46
|
+
# "status" => "0"
|
|
47
|
+
# }
|
|
48
|
+
# ]
|
|
49
|
+
# }
|
|
50
|
+
# @return [Hash]
|
|
51
|
+
# @see #response_body
|
|
52
|
+
# @see #response_headers
|
|
53
|
+
# @see #response_status
|
|
54
|
+
#
|
|
55
|
+
# @!attribute [r] response_headers
|
|
56
|
+
# @example
|
|
57
|
+
# {
|
|
58
|
+
# "Access-Control-Allow-Origin" => "*",
|
|
59
|
+
# "Connection" => "close",
|
|
60
|
+
# "Content-Length" => "179",
|
|
61
|
+
# "Content-Type" => "application/json; charset=utf-8",
|
|
62
|
+
# "Date" => "Thu, 06 May 2021 04:52:58 GMT",
|
|
63
|
+
# "Server" => "nginx"
|
|
64
|
+
# }
|
|
65
|
+
# @return [nil, String] Unmodified HTTP resonse headers that API returned.
|
|
66
|
+
# @see #response_body
|
|
67
|
+
# @see #response_data
|
|
68
|
+
# @see #response_status
|
|
69
|
+
#
|
|
70
|
+
# @!attribute [r] response_status
|
|
71
|
+
# HTTP status of the request to the API. 200 in case of success.
|
|
72
|
+
# @example
|
|
73
|
+
# client.response_status #=> 200
|
|
74
|
+
#
|
|
75
|
+
# @return [nil, Integer]
|
|
76
|
+
# @see #response_body
|
|
77
|
+
# @see #response_data
|
|
78
|
+
# @see #response_headers
|
|
79
|
+
#
|
|
80
|
+
# @!attribute [r] url
|
|
81
|
+
# @example
|
|
82
|
+
# client.url #=> "https://smspilot.ru/api.php?api_key=XXX&format=json&send=TEXT&to=79021234567"
|
|
83
|
+
# @return [String] URL generated by combining <tt>API_ENDPOINT</tt>, your API key, SMS text & phone
|
|
84
|
+
#
|
|
10
85
|
class Client
|
|
11
86
|
|
|
87
|
+
# Check current API endpoint URL at {https://smspilot.ru/apikey.php#api1}
|
|
88
|
+
#
|
|
89
|
+
API_ENDPOINT = "https://smspilot.ru/api.php".freeze
|
|
90
|
+
AVAILABLE_LOCALES = [:ru, :en].freeze
|
|
91
|
+
|
|
12
92
|
attr_reader :api_key
|
|
13
93
|
attr_reader :error
|
|
94
|
+
attr_reader :locale
|
|
14
95
|
attr_reader :phone
|
|
15
96
|
attr_reader :response_body
|
|
16
97
|
attr_reader :response_data
|
|
@@ -19,128 +100,312 @@ module SmsPilot
|
|
|
19
100
|
attr_reader :url
|
|
20
101
|
|
|
21
102
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
103
|
+
# @param api_key [String]
|
|
104
|
+
# @param locale [Symbol]
|
|
105
|
+
#
|
|
106
|
+
# @return [SmsPilot::Client]
|
|
107
|
+
# @raise [SmsPilot::InvalidAPIkeyError] if you pass anything but a non-empty String
|
|
108
|
+
# @raise [SmsPilot::InvalidLocaleError] if you pass anything but <tt>:ru</tt> or <tt>:en</tt>
|
|
109
|
+
#
|
|
110
|
+
# @see https://smspilot.ru/my-settings.php Get your production API key here
|
|
111
|
+
# @see https://smspilot.ru/apikey.php Get your development API key here
|
|
112
|
+
# @note Current development API key is <tt>"XXXXXXXXXXXXYYYYYYYYYYYYZZZZZZZZXXXXXXXXXXXXYYYYYYYYYYYYZZZZZZZZ"</tt>
|
|
113
|
+
#
|
|
114
|
+
# @example
|
|
115
|
+
# client = SmsPilot::Client.new(api_key: ENV["SMS_PILOT_API_KEY"])
|
|
116
|
+
# client = SmsPilot::Client.new(api_key: ENV["SMS_PILOT_API_KEY"], locale: :en)
|
|
117
|
+
#
|
|
118
|
+
def initialize(api_key:, locale: AVAILABLE_LOCALES[0])
|
|
119
|
+
@api_key = validate_api_key!(api_key)
|
|
27
120
|
@error = nil
|
|
121
|
+
@locale = validate_locale!(locale)
|
|
28
122
|
@response_status = nil
|
|
29
|
-
@response_headers =
|
|
123
|
+
@response_headers = {}
|
|
30
124
|
@response_body = nil
|
|
31
125
|
@response_data = {}
|
|
32
126
|
@url = nil
|
|
33
127
|
end
|
|
34
128
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
129
|
+
|
|
130
|
+
# @!group Main
|
|
131
|
+
|
|
132
|
+
# Send HTTP request to the API to ask them to transmit your SMS
|
|
133
|
+
#
|
|
134
|
+
# @return [Boolean] <tt>true</tt> if the SMS has been sent, <tt>false</tt> otherwise
|
|
135
|
+
#
|
|
136
|
+
# @param [String] phone The phone to send the SMS to. In free-form, will be sanitized.
|
|
137
|
+
# @param [String] message The text of your message.
|
|
138
|
+
#
|
|
139
|
+
# @raise [SmsPilot::InvalidPhoneError] if you pass anythig but a String with the <tt>phone</tt> argument
|
|
140
|
+
# @raise [SmsPilot::InvalidMessageError] if you pass anythig but a String with the <tt>message</tt> argument
|
|
141
|
+
# @raise [SmsPilot::InvalidMessageError] if your message is empty
|
|
142
|
+
# @raise [SmsPilot::InvalidPhoneError] if your phone is empty
|
|
143
|
+
# @raise [SmsPilot::InvalidPhoneError] if your phone has no digits
|
|
144
|
+
#
|
|
145
|
+
# @example
|
|
146
|
+
# client.send_sms("+7 (902) 123-45-67", "Привет, мир!") # => true
|
|
147
|
+
#
|
|
148
|
+
def send_sms(phone, message)
|
|
149
|
+
validate_phone! phone
|
|
150
|
+
validate_message! message
|
|
41
151
|
|
|
42
152
|
@phone = normalize_phone(phone)
|
|
43
|
-
|
|
153
|
+
uri = build_uri(@phone, message)
|
|
154
|
+
@url = uri.to_s
|
|
155
|
+
|
|
156
|
+
response = Net::HTTP.get_response(uri)
|
|
44
157
|
|
|
45
|
-
|
|
46
|
-
@response_status = response.
|
|
47
|
-
@response_headers = response.
|
|
48
|
-
@response_body = response.body.to_s
|
|
158
|
+
@response_body = response.body
|
|
159
|
+
@response_status = response.code.to_i
|
|
160
|
+
@response_headers = response.each_capitalized.to_h
|
|
49
161
|
|
|
50
|
-
unless response.
|
|
51
|
-
@error = "HTTP request failed with code #{response.
|
|
162
|
+
unless response.is_a?(Net::HTTPSuccess)
|
|
163
|
+
@error = "HTTP request failed with code #{response.code}"
|
|
52
164
|
return false
|
|
53
165
|
end
|
|
54
166
|
|
|
55
167
|
@response_data = JSON.parse @response_body
|
|
56
168
|
|
|
57
|
-
|
|
169
|
+
if rejected?
|
|
170
|
+
@error = "#{error_description} (error code: #{error_code})"
|
|
171
|
+
return false
|
|
172
|
+
end
|
|
173
|
+
|
|
58
174
|
return true
|
|
59
175
|
|
|
60
176
|
rescue JSON::ParserError => error
|
|
61
177
|
@error = "API returned invalid JSON. #{error.message}"
|
|
178
|
+
return false
|
|
62
179
|
|
|
63
|
-
rescue
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
rescue => error
|
|
180
|
+
rescue SocketError, EOFError, IOError, SystemCallError,
|
|
181
|
+
Timeout::Error, Net::HTTPBadResponse, Net::HTTPHeaderSyntaxError,
|
|
182
|
+
Net::ProtocolError, OpenSSL::SSL::SSLError => error
|
|
67
183
|
@error = error.message
|
|
184
|
+
return false
|
|
68
185
|
end
|
|
69
186
|
|
|
187
|
+
# @!endgroup
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
# @!group State accessors
|
|
70
191
|
|
|
192
|
+
# Your current balance, remaining after sending that latest SMS.
|
|
193
|
+
#
|
|
194
|
+
# @return [nil, Float] Always <tt>nil</tt> before you send SMS and if the SMS was not sent, always Float after successfull SMS transmission.
|
|
195
|
+
# @example
|
|
196
|
+
# client.balance #=> 20215.25
|
|
197
|
+
#
|
|
71
198
|
def balance
|
|
72
199
|
@response_data["balance"]&.to_f if sms_sent?
|
|
73
200
|
end
|
|
74
201
|
|
|
75
202
|
|
|
76
|
-
#
|
|
77
|
-
#
|
|
203
|
+
# Numerical code of the error that occured when sending the SMS. In the range from 0 to 715 (which may change).
|
|
204
|
+
#
|
|
205
|
+
# @return [nil, Integer] <tt>nil</tt> is returned before sending SMS. Otherwise <tt>Integer</tt>
|
|
206
|
+
# @example
|
|
207
|
+
# client.error_code #=> 122
|
|
208
|
+
# @see #error
|
|
209
|
+
# @see #error_description
|
|
210
|
+
# @see https://smspilot.ru/apikey.php#err Error codes at the API documentation website
|
|
78
211
|
#
|
|
79
212
|
def error_code
|
|
80
213
|
@response_data.dig("error", "code")&.to_i if rejected?
|
|
81
214
|
end
|
|
82
215
|
|
|
83
216
|
|
|
84
|
-
#
|
|
85
|
-
#
|
|
217
|
+
# Description of the error that occured when sending the SMS
|
|
218
|
+
#
|
|
219
|
+
# @return [nil, String] <tt>nil</tt> is returned before sending SMS. Otherwise <tt>String</tt>
|
|
220
|
+
# @example
|
|
221
|
+
# client.error_description #=> "Пользователь временно блокирован (спорная ситуация)"
|
|
222
|
+
# @see #error
|
|
223
|
+
# @see #error_code
|
|
224
|
+
# @see https://smspilot.ru/apikey.php#err Error codes at the API documentation website
|
|
86
225
|
#
|
|
87
226
|
def error_description
|
|
88
|
-
@
|
|
227
|
+
method_name = (@locale == :ru) ? "description_ru" : "description"
|
|
228
|
+
@response_data.dig("error", method_name) if rejected?
|
|
89
229
|
end
|
|
90
230
|
|
|
91
231
|
|
|
92
|
-
#
|
|
232
|
+
# Did the API reject your request to send that SMS
|
|
233
|
+
#
|
|
234
|
+
# @return [Boolean] <tt>false</tt> is returned before sending SMS. Otherwise the <tt>Boolean</tt> corresponds to whether your request to send an SMS was rejected.
|
|
235
|
+
# @example
|
|
236
|
+
# client.rejected? #=> false
|
|
237
|
+
#
|
|
93
238
|
def rejected?
|
|
94
239
|
return false if sms_sent?
|
|
95
240
|
@response_data["error"].is_a? Hash
|
|
96
241
|
end
|
|
97
242
|
|
|
98
243
|
|
|
99
|
-
#
|
|
244
|
+
# Did the API block you
|
|
100
245
|
#
|
|
101
|
-
#
|
|
102
|
-
#
|
|
103
|
-
#
|
|
104
|
-
#
|
|
246
|
+
# Error code | Description
|
|
247
|
+
# :---|:------------------
|
|
248
|
+
# 105 | из-за низкого баланса
|
|
249
|
+
# 106 | за спам/ошибки
|
|
250
|
+
# 107 | за недостоверные учетные данные / недоступна эл. почта / проблемы с телефоном
|
|
251
|
+
# 122 | спорная ситуация
|
|
105
252
|
#
|
|
106
|
-
#
|
|
253
|
+
# @return [Boolean] <tt>nil</tt> is returned before sending SMS. Otherwise the <tt>Boolean</tt> corresponds to whether the API has blocked you.
|
|
254
|
+
# @example
|
|
255
|
+
# client.sender_blocked? #=> false
|
|
256
|
+
# @see #error
|
|
257
|
+
# @see https://smspilot.ru/apikey.php#err Error codes at the API documentation website
|
|
107
258
|
#
|
|
108
259
|
def sender_blocked?
|
|
109
260
|
[105, 106, 107, 122].include? error_code
|
|
110
261
|
end
|
|
111
262
|
|
|
112
263
|
|
|
113
|
-
#
|
|
264
|
+
# The cost of the SMS that has just been sent, in RUB
|
|
265
|
+
#
|
|
266
|
+
# @return [nil, Float]
|
|
267
|
+
# @example
|
|
268
|
+
# client.sms_cost #=> 2.63
|
|
269
|
+
#
|
|
114
270
|
def sms_cost
|
|
115
|
-
@response_data["cost"] if sms_sent?
|
|
271
|
+
@response_data["cost"]&.to_f if sms_sent?
|
|
116
272
|
end
|
|
117
273
|
|
|
118
274
|
|
|
119
|
-
#
|
|
275
|
+
# Has the SMS transmission been a success.
|
|
276
|
+
#
|
|
277
|
+
# @return [Boolean] <tt>nil</tt> is returned before sending SMS. Otherwise the <tt>Boolean</tt> corresponds to the result of SMS transmission.
|
|
278
|
+
# @see #sms_status
|
|
279
|
+
# @see #rejected?
|
|
280
|
+
# @see #error
|
|
281
|
+
#
|
|
282
|
+
# @example
|
|
283
|
+
# client.sms_sent? #=> true
|
|
284
|
+
#
|
|
120
285
|
def sms_sent?
|
|
121
286
|
@response_data["send"] != nil
|
|
122
287
|
end
|
|
123
288
|
|
|
124
289
|
|
|
125
|
-
#
|
|
126
|
-
#
|
|
290
|
+
# SMS delivery status, as returned by the API
|
|
291
|
+
#
|
|
292
|
+
# @return [nil, Integer] <tt>nil</tt> is returned before sending SMS or if the request was rejected. Otherwise an <tt>Integer</tt> in the range of [-2..3] is returned.
|
|
293
|
+
# @see https://smspilot.ru/apikey.php#status List of available statuses at API documentation website
|
|
294
|
+
#
|
|
295
|
+
# Code | Name | Final? | Description
|
|
296
|
+
# ----:|:--------------|:-------|:-------------
|
|
297
|
+
# -2 | Ошибка | Да | Ошибка, неправильные параметры запроса
|
|
298
|
+
# -1 | Не доставлено | Да | Сообщение не доставлено (не в сети, заблокирован, не взял трубку), PING — не в сети, HLR — не обслуживается (заблокирован)
|
|
299
|
+
# 0 | Новое | Нет | Новое сообщение/запрос, ожидает обработки у нас на сервере
|
|
300
|
+
# 1 | В очереди | Нет | Сообщение или запрос ожидают отправки на сервере оператора
|
|
301
|
+
# 2 | Доставлено | Да | Доставлено, звонок совершен, PING — в сети, HLR — обслуживается
|
|
302
|
+
# 3 | Отложено | Нет | Отложенная отправка, отправка сообщения/запроса запланирована на другое время
|
|
303
|
+
#
|
|
304
|
+
# @example
|
|
305
|
+
# client.sms_status #=> 2
|
|
127
306
|
#
|
|
128
307
|
def sms_status
|
|
129
308
|
@response_data.dig("send", 0, "status")&.to_i if sms_sent?
|
|
130
309
|
end
|
|
131
310
|
|
|
311
|
+
# @!endgroup
|
|
132
312
|
|
|
133
|
-
private
|
|
134
313
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
314
|
+
# The URI we will send an HTTP request to
|
|
315
|
+
#
|
|
316
|
+
# @private
|
|
317
|
+
# @return [URI]
|
|
318
|
+
# @raise [URI::InvalidURIError] but is very unlikely because we provide the URL ourselves
|
|
319
|
+
#
|
|
320
|
+
# @example
|
|
321
|
+
# build_uri("79021234567", "Hello, World!")
|
|
322
|
+
# #=> #<URI::HTTPS https://smspilot.ru/api.php?apikey=XXX…&format=json&send=Hello%2C+World%21&to=79021234567>
|
|
323
|
+
#
|
|
324
|
+
private def build_uri(phone, text)
|
|
325
|
+
URI.parse(API_ENDPOINT).tap do |uri|
|
|
326
|
+
uri.query = URI.encode_www_form({ apikey: @api_key, format: :json, send: text, to: phone })
|
|
327
|
+
end
|
|
139
328
|
end
|
|
140
329
|
|
|
141
|
-
|
|
330
|
+
|
|
331
|
+
# Cleans up your phone from anything but digits. Also replaces 8 to 7 if it is the first digit.
|
|
332
|
+
#
|
|
333
|
+
# @private
|
|
334
|
+
# @return [String]
|
|
335
|
+
#
|
|
336
|
+
# @example
|
|
337
|
+
# normalize_phone("8 (902) 123-45-67") #=> 79021234567
|
|
338
|
+
# normalize_phone("+7-902-123-45-67") #=> 79021234567
|
|
339
|
+
#
|
|
340
|
+
private def normalize_phone(phone)
|
|
142
341
|
phone.gsub(/[^0-9]/, '').sub(/^8/, '7').gsub('+7', '8')
|
|
143
342
|
end
|
|
144
343
|
|
|
344
|
+
|
|
345
|
+
# @!group Validations
|
|
346
|
+
|
|
347
|
+
# Validates api_key
|
|
348
|
+
#
|
|
349
|
+
# @private
|
|
350
|
+
# @return [String] the original value passed into the method, only if it was valid
|
|
351
|
+
# @param [String] api_key
|
|
352
|
+
|
|
353
|
+
# @raise [SmsPilot::InvalidError] if api_key is not a String
|
|
354
|
+
# @raise [SmsPilot::InvalidError] if api_key is an empty String
|
|
355
|
+
#
|
|
356
|
+
private def validate_api_key!(api_key)
|
|
357
|
+
fail SmsPilot::InvalidAPIkeyError, "API key must be a String, you pass a #{api_key.class} (#{api_key})" unless api_key.is_a? String
|
|
358
|
+
fail SmsPilot::InvalidAPIkeyError, "API key cannot be empty" if api_key == ""
|
|
359
|
+
return api_key
|
|
360
|
+
end
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
# Validates locale
|
|
364
|
+
#
|
|
365
|
+
# @private
|
|
366
|
+
# @return [Symbol] the original value passed into the method, only if it was valid
|
|
367
|
+
# @param [Symbol] locale
|
|
368
|
+
|
|
369
|
+
# @raise [SmsPilot::InvalidError] if locale is not a Symbol
|
|
370
|
+
# @raise [SmsPilot::InvalidError] if locale is unrecognized
|
|
371
|
+
#
|
|
372
|
+
private def validate_locale!(locale)
|
|
373
|
+
fail SmsPilot::InvalidLocaleError, "locale must be a Symbol" unless locale.is_a? Symbol
|
|
374
|
+
fail SmsPilot::InvalidLocaleError, "API does not support locale :#{locale}; choose one of #{AVAILABLE_LOCALES.inspect}" unless AVAILABLE_LOCALES.include? locale
|
|
375
|
+
return locale
|
|
376
|
+
end
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
# Validates message
|
|
380
|
+
#
|
|
381
|
+
# @private
|
|
382
|
+
# @return [nil]
|
|
383
|
+
#
|
|
384
|
+
# @raise [SmsPilot::InvalidMessageError] if you pass anythig but a String with the <tt>message</tt> argument
|
|
385
|
+
# @raise [SmsPilot::InvalidMessageError] if your message is empty
|
|
386
|
+
#
|
|
387
|
+
private def validate_message!(message)
|
|
388
|
+
fail SmsPilot::InvalidMessageError, "SMS message must be a String, you pass a #{ message.class} (#{ message})" unless message.is_a? String
|
|
389
|
+
fail SmsPilot::InvalidMessageError, "SMS message cannot be empty" if message == ""
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
# Validates phone
|
|
394
|
+
#
|
|
395
|
+
# @private
|
|
396
|
+
# @return [nil]
|
|
397
|
+
#
|
|
398
|
+
# @raise [SmsPilot::InvalidPhoneError] if you pass anythig but a String with the <tt>phone</tt> argument
|
|
399
|
+
# @raise [SmsPilot::InvalidPhoneError] if your phone is empty
|
|
400
|
+
# @raise [SmsPilot::InvalidPhoneError] if your phone has no digits
|
|
401
|
+
#
|
|
402
|
+
private def validate_phone!(phone)
|
|
403
|
+
fail SmsPilot::InvalidPhoneError, "phone must be a String, you pass a #{phone.class} (#{phone})" unless phone.is_a? String
|
|
404
|
+
fail SmsPilot::InvalidPhoneError, "phone cannot be empty" if phone == ""
|
|
405
|
+
fail SmsPilot::InvalidPhoneError, "phone must contain digits" if phone.scan(/\d/).none?
|
|
406
|
+
end
|
|
407
|
+
|
|
408
|
+
# @!endgroup
|
|
409
|
+
|
|
145
410
|
end
|
|
146
411
|
end
|
data/lib/sms_pilot/errors.rb
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module SmsPilot
|
|
4
|
-
|
|
4
|
+
|
|
5
|
+
class InvalidAPIkeyError < ArgumentError; end
|
|
6
|
+
class InvalidMessageError < ArgumentError; end
|
|
7
|
+
class InvalidPhoneError < ArgumentError; end
|
|
8
|
+
class InvalidLocaleError < ArgumentError; end
|
|
9
|
+
|
|
5
10
|
end
|
data/lib/sms_pilot/version.rb
CHANGED
data/sms-pilot-api-v1.gemspec
CHANGED
|
@@ -3,20 +3,20 @@
|
|
|
3
3
|
require_relative "lib/sms_pilot/version"
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "sms-pilot-api-v1"
|
|
6
7
|
spec.authors = ["Sergey Pedan"]
|
|
7
8
|
spec.summary = "Simple wrapper around SMS pilot API v1"
|
|
8
9
|
spec.description = "#{spec.summary}. Version 1 because it returns more data within its standard response"
|
|
9
10
|
spec.email = ["sergey.pedan@gmail.com"]
|
|
10
|
-
spec.homepage = "https://github.com/sergeypedan
|
|
11
|
+
spec.homepage = "https://github.com/sergeypedan/#{spec.name}"
|
|
11
12
|
spec.license = "MIT"
|
|
12
|
-
spec.name = "sms-pilot-api-v1"
|
|
13
13
|
spec.version = SmsPilot::VERSION
|
|
14
14
|
|
|
15
15
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
|
|
16
16
|
|
|
17
17
|
spec.metadata = {
|
|
18
|
-
"changelog_uri" => "#{spec.homepage}/blob/master/
|
|
19
|
-
"documentation_uri" => "
|
|
18
|
+
"changelog_uri" => "#{spec.homepage}/blob/master/CHANGELOG.md",
|
|
19
|
+
"documentation_uri" => "https://rubydoc.info/github/sergeypedan/#{spec.name}/master/",
|
|
20
20
|
"homepage_uri" => spec.homepage,
|
|
21
21
|
"source_code_uri" => spec.homepage
|
|
22
22
|
}
|
|
@@ -24,12 +24,10 @@ Gem::Specification.new do |spec|
|
|
|
24
24
|
# Specify which files should be added to the gem when it is released.
|
|
25
25
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
|
26
26
|
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
|
27
|
-
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
|
27
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features|pkg|doc)/}) }
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
spec.bindir = "bin"
|
|
31
31
|
spec.require_paths = ["lib"]
|
|
32
32
|
|
|
33
|
-
spec.add_runtime_dependency "http", "~> 4"
|
|
34
|
-
|
|
35
33
|
end
|
metadata
CHANGED
|
@@ -1,29 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sms-pilot-api-v1
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.0.
|
|
4
|
+
version: 0.0.6
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sergey Pedan
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2021-05-
|
|
12
|
-
dependencies:
|
|
13
|
-
- !ruby/object:Gem::Dependency
|
|
14
|
-
name: http
|
|
15
|
-
requirement: !ruby/object:Gem::Requirement
|
|
16
|
-
requirements:
|
|
17
|
-
- - "~>"
|
|
18
|
-
- !ruby/object:Gem::Version
|
|
19
|
-
version: '4'
|
|
20
|
-
type: :runtime
|
|
21
|
-
prerelease: false
|
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
-
requirements:
|
|
24
|
-
- - "~>"
|
|
25
|
-
- !ruby/object:Gem::Version
|
|
26
|
-
version: '4'
|
|
11
|
+
date: 2021-05-08 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
27
13
|
description: Simple wrapper around SMS pilot API v1. Version 1 because it returns
|
|
28
14
|
more data within its standard response
|
|
29
15
|
email:
|
|
@@ -34,6 +20,7 @@ extra_rdoc_files: []
|
|
|
34
20
|
files:
|
|
35
21
|
- ".gitignore"
|
|
36
22
|
- ".rspec"
|
|
23
|
+
- ".yardopts"
|
|
37
24
|
- CHANGELOG.md
|
|
38
25
|
- Gemfile
|
|
39
26
|
- Gemfile.lock
|
|
@@ -45,14 +32,13 @@ files:
|
|
|
45
32
|
- lib/sms_pilot/client.rb
|
|
46
33
|
- lib/sms_pilot/errors.rb
|
|
47
34
|
- lib/sms_pilot/version.rb
|
|
48
|
-
- sms-pilot-api-v1-0.0.2.gem
|
|
49
35
|
- sms-pilot-api-v1.gemspec
|
|
50
36
|
homepage: https://github.com/sergeypedan/sms-pilot-api-v1
|
|
51
37
|
licenses:
|
|
52
38
|
- MIT
|
|
53
39
|
metadata:
|
|
54
|
-
changelog_uri: https://github.com/sergeypedan/sms-pilot-api-v1/blob/master/
|
|
55
|
-
documentation_uri: https://
|
|
40
|
+
changelog_uri: https://github.com/sergeypedan/sms-pilot-api-v1/blob/master/CHANGELOG.md
|
|
41
|
+
documentation_uri: https://rubydoc.info/github/sergeypedan/sms-pilot-api-v1/master/
|
|
56
42
|
homepage_uri: https://github.com/sergeypedan/sms-pilot-api-v1
|
|
57
43
|
source_code_uri: https://github.com/sergeypedan/sms-pilot-api-v1
|
|
58
44
|
post_install_message:
|
|
@@ -70,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
70
56
|
- !ruby/object:Gem::Version
|
|
71
57
|
version: '0'
|
|
72
58
|
requirements: []
|
|
73
|
-
rubygems_version: 3.2.
|
|
59
|
+
rubygems_version: 3.2.8
|
|
74
60
|
signing_key:
|
|
75
61
|
specification_version: 4
|
|
76
62
|
summary: Simple wrapper around SMS pilot API v1
|
data/sms-pilot-api-v1-0.0.2.gem
DELETED
|
Binary file
|