sms_aero 0.0.11 → 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.
Files changed (73) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -6
  3. data/CHANGELOG.md +15 -10
  4. data/README.md +25 -30
  5. data/lib/sms_aero.rb +119 -34
  6. data/lib/sms_aero/birthday.rb +12 -0
  7. data/lib/sms_aero/callable.rb +6 -0
  8. data/lib/sms_aero/channel.rb +15 -0
  9. data/lib/sms_aero/digital.rb +7 -0
  10. data/lib/sms_aero/filled_string.rb +11 -0
  11. data/lib/sms_aero/future.rb +16 -0
  12. data/lib/sms_aero/group.rb +11 -0
  13. data/lib/sms_aero/optional.rb +15 -0
  14. data/lib/sms_aero/phone.rb +11 -0
  15. data/lib/sms_aero/response.rb +30 -0
  16. data/lib/sms_aero/response/with_balance.rb +5 -0
  17. data/lib/sms_aero/response/with_groups.rb +5 -0
  18. data/lib/sms_aero/response/with_id.rb +9 -0
  19. data/lib/sms_aero/response/with_senders.rb +5 -0
  20. data/lib/sms_aero/response/with_statuses.rb +5 -0
  21. data/lib/sms_aero/response/with_tariff.rb +5 -0
  22. data/lib/sms_aero/tariff.rb +8 -0
  23. data/sms_aero.gemspec +2 -4
  24. data/spec/{sms_aero/types → models}/birthday_spec.rb +2 -2
  25. data/spec/{sms_aero/types → models}/channel_spec.rb +2 -2
  26. data/spec/{sms_aero/types → models}/digital_spec.rb +1 -1
  27. data/spec/{sms_aero/types → models}/future_spec.rb +5 -5
  28. data/spec/{sms_aero/types → models}/phone_spec.rb +1 -1
  29. data/spec/{sms_aero/operations → operations}/add_blacklist_spec.rb +19 -3
  30. data/spec/{sms_aero/operations → operations}/add_group_spec.rb +4 -4
  31. data/spec/{sms_aero/operations → operations}/add_phone_spec.rb +39 -76
  32. data/spec/{sms_aero/operations → operations}/check_balance_spec.rb +2 -4
  33. data/spec/{sms_aero/operations → operations}/check_groups_spec.rb +0 -0
  34. data/spec/{sms_aero/operations → operations}/check_senders_spec.rb +5 -5
  35. data/spec/{sms_aero/operations → operations}/check_sending_spec.rb +3 -3
  36. data/spec/{sms_aero/operations → operations}/check_sign_spec.rb +2 -2
  37. data/spec/{sms_aero/operations → operations}/check_status_spec.rb +3 -3
  38. data/spec/{sms_aero/operations → operations}/check_tariff_spec.rb +1 -1
  39. data/spec/{sms_aero/operations → operations}/delete_group_spec.rb +3 -3
  40. data/spec/{sms_aero/operations → operations}/delete_phone_spec.rb +4 -4
  41. data/spec/{sms_aero/operations → operations}/send_sms_spec.rb +49 -11
  42. data/spec/spec_helper.rb +4 -1
  43. data/spec/support/en.yml +8 -0
  44. metadata +61 -101
  45. data/lib/sms_aero/models/answer.rb +0 -8
  46. data/lib/sms_aero/models/sms.rb +0 -16
  47. data/lib/sms_aero/models/tariff.rb +0 -8
  48. data/lib/sms_aero/operations/add_blacklist.rb +0 -11
  49. data/lib/sms_aero/operations/add_group.rb +0 -11
  50. data/lib/sms_aero/operations/add_phone.rb +0 -17
  51. data/lib/sms_aero/operations/check_balance.rb +0 -11
  52. data/lib/sms_aero/operations/check_groups.rb +0 -12
  53. data/lib/sms_aero/operations/check_senders.rb +0 -15
  54. data/lib/sms_aero/operations/check_sending.rb +0 -11
  55. data/lib/sms_aero/operations/check_sign.rb +0 -15
  56. data/lib/sms_aero/operations/check_status.rb +0 -11
  57. data/lib/sms_aero/operations/check_tariff.rb +0 -12
  58. data/lib/sms_aero/operations/delete_group.rb +0 -11
  59. data/lib/sms_aero/operations/delete_phone.rb +0 -12
  60. data/lib/sms_aero/operations/hlr.rb +0 -36
  61. data/lib/sms_aero/operations/send_sms.rb +0 -22
  62. data/lib/sms_aero/operations/send_to_group.rb +0 -15
  63. data/lib/sms_aero/types/birthday.rb +0 -20
  64. data/lib/sms_aero/types/channel.rb +0 -4
  65. data/lib/sms_aero/types/digital.rb +0 -8
  66. data/lib/sms_aero/types/filled_string.rb +0 -3
  67. data/lib/sms_aero/types/future.rb +0 -16
  68. data/lib/sms_aero/types/password.rb +0 -6
  69. data/lib/sms_aero/types/phone.rb +0 -12
  70. data/lib/sms_aero/types/sign_status.rb +0 -9
  71. data/spec/sms_aero/operations/hlr_spec.rb +0 -96
  72. data/spec/sms_aero/operations/send_to_group_spec.rb +0 -185
  73. data/spec/sms_aero/types/sign_status_spec.rb +0 -19
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b52fc948890d3313610388be5e1757e77212476
4
- data.tar.gz: 26936444af10df3a81997e8b78acbb18a8c480a7
3
+ metadata.gz: fdf410ad50fc28f563f44d7749d96e6a1d0c55a3
4
+ data.tar.gz: cdbbbb1536558b11a8d58f070785e0a67802bc75
5
5
  SHA512:
6
- metadata.gz: 69ee02b04df901f37a568abf8debc38ca4ac3ad0fc3587a255866d85bd328a75e9e4b359445c209809084447cacfe3dedbbed39fd1421eec84af880b901c778d
7
- data.tar.gz: d90ab49c4c46fc3e8e40a2f8d9b0ed90be2017a21fe7bf30b5d7dcf03c171a5ba0437012fedbf5371874420cd6e1f8522124fd0ee58027746a643bb510114706
6
+ metadata.gz: 1cb59cd8f2900d1f72ca3ceeedfc41bcd75dce2f265f2d6316f4ba312d0204c21e2b36ad90463d111c2f4ef3261dc7119c8ea32b34f66653a496e9ebb3a51fb3
7
+ data.tar.gz: 71563a2b0af8242313d0f38b6b2e6eb684869d162e0cd1aa68c412fc798f52d076c472d61aa023c4dcc7e171407326c8fb3395bbfc9ae5f2ab268e6752b24adb
@@ -12,9 +12,6 @@ Metrics/LineLength:
12
12
  - http
13
13
  - https
14
14
 
15
- Layout/SpaceInLambdaLiteral:
16
- Enabled: false
17
-
18
15
  Style/Lambda:
19
16
  Enabled: false
20
17
 
@@ -24,14 +21,14 @@ Style/StringLiterals:
24
21
  Style/FrozenStringLiteralComment:
25
22
  Enabled: false
26
23
 
27
- Style/DateTime:
28
- Enabled: false
29
-
30
24
  Style/Documentation:
31
25
  Enabled: false
32
26
 
33
27
  Style/ClassAndModuleChildren:
34
28
  Enabled: false
35
29
 
30
+ Style/SpaceInLambdaLiteral:
31
+ Enabled: false
32
+
36
33
  Style/PercentLiteralDelimiters:
37
34
  Enabled: false
@@ -1,18 +1,25 @@
1
1
  # Change Log
2
+
2
3
  All notable changes to this project will be documented in this file.
3
4
 
4
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
6
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
7
 
7
- ## [0.0.11] - [2017-12-19]
8
+ ## [0.1.0] - [2017-08-11]
8
9
 
9
- ### Added
10
- - Always add #success to response from #hlr (@Earendil95)
10
+ The gem is re-written on top of newer version of [evil-client]
11
+ Some changes in the interface has been made as well.
11
12
 
12
- ## [0.0.10] - [2017-12-03]
13
+ ### Changed
13
14
 
14
- ### Added
15
- - checking existance & availability of phone number using methods `#hlr` and `#hlr_status id` (@Earendil95)
15
+ - The root option `:test` renamed to `:testsend` for internal reasons of [evil-client][evil-client] implementation (nepalez)
16
+ - Version of [evil-client][evil-client] used under the hood: 0.3.3 -> 1.1.0 (nepalez)
17
+
18
+ ### Deleted
19
+
20
+ - Method `send_to_group` removed in favor or `group:` option of `send_sms` (nepalez)
21
+ - Validation of responses returned by a remote server (nepalez)
22
+ - Dependency from [dry-types][dry-types] (nepalez)
16
23
 
17
24
  ## [0.0.9] - [2017-06-23]
18
25
 
@@ -24,10 +31,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
24
31
  ### Added
25
32
  - Weakened dependency from [dry-types], allowing v0.0.9 (@nepalez)
26
33
 
27
- Between v0.9.0 and v0.9.1 an `optional` property has been broken.
28
-
34
+ [evil-client]: https://github.com/evilmartians/evil-client
29
35
  [dry-types]: https://github.com/dry-rb/dry-types
30
36
  [0.0.8]: https://github.com/nepalez/sms_aero/compare/v0.0.7...v0.0.8
31
37
  [0.0.9]: https://github.com/nepalez/sms_aero/compare/v0.0.8...v0.0.9
32
- [0.0.10]: https://github.com/nepalez/sms_aero/compare/v0.0.9...v0.0.10
33
- [0.0.11]: https://github.com/nepalez/sms_aero/compare/v0.0.10...v0.0.11
38
+ [0.1.0]: https://github.com/nepalez/sms_aero/compare/v0.0.9...v0.1.0
data/README.md CHANGED
@@ -5,17 +5,11 @@
5
5
  [![Dependency Status][gemnasium-badger]][gemnasium]
6
6
  [![Code Climate][codeclimate-badger]][codeclimate]
7
7
 
8
- HTTP(s) client to [SMS Aero service API][sms-aero].
8
+ HTTP(s) client to [SMS Aero service API][sms-aero]
9
+ written on top of [evil-client][evil-client] "framework".
9
10
 
10
- [sms-aero]: https://smsaero.ru/api/description/
11
- [codeclimate-badger]: https://img.shields.io/codeclimate/github/nepalez/sms_aero.svg?style=flat
12
- [codeclimate]: https://codeclimate.com/github/nepalez/sms_aero
13
- [gem-badger]: https://img.shields.io/gem/v/sms_aero.svg?style=flat
14
- [gem]: https://rubygems.org/gems/sms_aero
15
- [gemnasium-badger]: https://img.shields.io/gemnasium/nepalez/sms_aero.svg?style=flat
16
- [gemnasium]: https://gemnasium.com/nepalez/sms_aero
17
- [travis-badger]: https://img.shields.io/travis/nepalez/sms_aero/master.svg?style=flat
18
- [travis]: https://travis-ci.org/nepalez/sms_aero
11
+ <a href="https://evilmartians.com/">
12
+ <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
19
13
 
20
14
  ## Synopsis
21
15
 
@@ -28,7 +22,7 @@ Initialize a client with user and password:
28
22
  ```ruby
29
23
  client = SmsAero.new user: "joe", # required
30
24
  password: "foobar", # required
31
- test: true # optional - to send test SMS by default
25
+ testsend: true # optional - to send test SMS
32
26
  ```
33
27
 
34
28
  Then send requests:
@@ -39,9 +33,9 @@ answer = client.send_sms text: "Hello!",
39
33
  date: "2100/01/12", # Date, Time, DateTime are accepted as well
40
34
  type: 3 # see API docs for details
41
35
 
42
- answer.result # => "accepted"
43
- answer.id # => "38293"
44
- answer.success # => true (checks whether id was returned)
36
+ answer.result # => "accepted"
37
+ answer.id # => "38293"
38
+ answer.success? # => true (checks whether an id has been returned)
45
39
  ```
46
40
 
47
41
  ```ruby
@@ -50,13 +44,14 @@ answer.result # => "pending"
50
44
  ```
51
45
 
52
46
  ```ruby
53
- answer = client.send_to_group text: "Hello!",
54
- group: "customers",
55
- date: "2100/01/12",
56
- type: 1
47
+ answer = client.send_sms text: "Hello!",
48
+ group: "customers",
49
+ date: Date.new("2100/01/12"),
50
+ type: 1
57
51
 
58
- answer.result # => "accepted"
59
- answer.id # => "894924"
52
+ answer.result # => "accepted"
53
+ answer.id # => "894924"
54
+ answer.success? # => true (checks whether an id has been returned)
60
55
  ```
61
56
 
62
57
  ```ruby
@@ -128,13 +123,13 @@ answer = client.delete_phone phone: "+7 (999) 123-4567",
128
123
  answer.result # => "accepted"
129
124
  ```
130
125
 
131
- ```ruby
132
- # checking existance & availability of phone number
133
- answer = client.hlr phone: "+7 (999) 123-4567"
134
- answer.result # => "accepted"
135
- id = answer.id # => "12345", id of request
136
-
137
- answer = client.hlr_status id
138
- answer.result # => "accepted"
139
- answer.status # => any of :available, :unavailable or :nonexistent
140
- ```
126
+ [sms-aero]: https://smsaero.ru/api/description/
127
+ [codeclimate-badger]: https://img.shields.io/codeclimate/github/nepalez/sms_aero.svg?style=flat
128
+ [codeclimate]: https://codeclimate.com/github/nepalez/sms_aero
129
+ [gem-badger]: https://img.shields.io/gem/v/sms_aero.svg?style=flat
130
+ [gem]: https://rubygems.org/gems/sms_aero
131
+ [gemnasium-badger]: https://img.shields.io/gemnasium/nepalez/sms_aero.svg?style=flat
132
+ [gemnasium]: https://gemnasium.com/nepalez/sms_aero
133
+ [travis-badger]: https://img.shields.io/travis/nepalez/sms_aero/master.svg?style=flat
134
+ [travis]: https://travis-ci.org/nepalez/sms_aero
135
+ [evil-client]: https://github.com/evilmartians/evil-client
@@ -1,56 +1,141 @@
1
1
  require "evil/client"
2
- require "dry-types"
3
2
 
4
3
  # HTTP(s) client to the "SMS Aero" online service
5
- class SmsAero
6
- extend Evil::Client::DSL
4
+ class SmsAero < Evil::Client
5
+ require_relative "sms_aero/callable"
6
+ require_relative "sms_aero/optional"
7
+ require_relative "sms_aero/filled_string"
8
+ require_relative "sms_aero/future"
9
+ require_relative "sms_aero/digital"
10
+ require_relative "sms_aero/phone"
11
+ require_relative "sms_aero/birthday"
12
+ require_relative "sms_aero/group"
13
+ require_relative "sms_aero/channel"
14
+ require_relative "sms_aero/tariff"
15
+ require_relative "sms_aero/response"
7
16
 
8
- # Collection of dry-types with gem-specific additions
9
- Types = Module.new { |types| types.include Dry::Types.module }
17
+ option :user, FilledString
18
+ option :password, optional: true
19
+ option :token, default: -> { OpenSSL::Digest::MD5.new.hexdigest(password) }
20
+ option :use_ssl, true.method(:&), default: proc { true }
21
+ option :use_post, true.method(:&), default: proc { true }
22
+ option :testsend, true.method(:&), default: proc { false }
10
23
 
11
- # Definitions for types, models, and API operations
12
- %w(types models operations).each do |folder|
13
- path = File.expand_path("../sms_aero/#{folder}/*.rb", __FILE__)
14
- Dir[path].each { |file| require(file) }
24
+ path { "http#{'s' if use_ssl}://gate.smsaero.ru/" }
25
+ http_method { use_post ? :post : :get }
26
+ query { { user: user, password: token, answer: "json" } }
27
+ response(200) { |*res| Response.build(*res) }
28
+ headers "X-Ruby-Client" => "https://github.com/nepalez/sms_aero",
29
+ "X-Ruby-Framework" => "https://github.com/evilmartians/evil-client"
30
+
31
+ operation :add_blacklist do
32
+ option :phone, Phone
33
+
34
+ path "addblacklist"
35
+ query { { phone: phone } }
15
36
  end
16
37
 
17
- settings do
18
- option :user, Types::FilledString
19
- option :password, Types::Password
20
- option :use_ssl, Types::Form::Bool, default: proc { true }
21
- option :use_post, Types::Form::Bool, default: proc { true }
22
- option :test, Types::Form::Bool, default: proc { false }
38
+ operation :add_group do
39
+ option :group, Group
40
+
41
+ path "addgroup"
42
+ query { { group: group } }
23
43
  end
24
44
 
25
- base_url do |settings|
26
- "http#{'s' if settings.use_ssl}://gate.smsaero.ru/"
45
+ operation :add_phone do
46
+ option :phone, Phone
47
+ option :group, optional: true, type: Group
48
+ option :bday, optional: true, type: Birthday
49
+ option :lname, optional: true
50
+ option :fname, optional: true
51
+ option :sname, optional: true
52
+ option :param, optional: true
53
+ option :param2, optional: true
54
+ option :param3, optional: true
55
+
56
+ path "addphone"
57
+ query { options.except :password, :token, :use_ssl, :use_post, :testsend }
27
58
  end
28
59
 
29
- operation do |settings|
30
- documentation "https://smsaero.ru/api/description/"
60
+ operation :check_balance do
61
+ path "balance"
62
+ response(200) { |*res| Response::WithBalance.build(*res) }
63
+ end
31
64
 
32
- http_method(settings.use_post ? :post : :get)
65
+ operation :check_groups do
66
+ path "checkgroup"
67
+ response(200) { |*res| Response::WithGroups.build(*res) }
68
+ end
33
69
 
34
- security do
35
- key_auth :user, settings.user, using: :query
36
- key_auth :password, settings.password, using: :query
37
- key_auth :answer, "json", using: :query
38
- end
70
+ operation :check_senders do
71
+ option :sign, FilledString
72
+
73
+ path "senders"
74
+ query { { sign: sign } }
75
+ response(200) { |*res| Response::WithSenders.build(*res) }
76
+ end
77
+
78
+ operation :check_sending do
79
+ option :id, FilledString
80
+
81
+ path "checksending"
82
+ query { { id: id } }
83
+ end
84
+
85
+ operation :check_sign do
86
+ option :sign, FilledString
39
87
 
40
- responses format: :json do
41
- response :success, 200, model: Answer
42
- response :failure, 200, model: Answer
88
+ path "sign"
89
+ query { { sign: sign } }
90
+
91
+ response(200) do |_, _, body|
92
+ data = JSON.parse(body.first)
93
+ Response::WithStatuses.new(data: data)
43
94
  end
44
95
  end
45
96
 
46
- private
97
+ operation :check_status do
98
+ option :id, FilledString
99
+
100
+ path "status"
101
+ query { { id: id } }
102
+ end
103
+
104
+ operation :check_tariff do
105
+ path "checktarif"
106
+
107
+ response(200) { |*res| Response::WithTariff.build(*res) }
108
+ end
109
+
110
+ operation :delete_group do
111
+ option :group, FilledString
47
112
 
48
- def method_missing(name, *args)
49
- op = operations[name.to_sym]
50
- op ? op.call(*args) : super
113
+ path "delgroup"
114
+ query { options.select { |key| key == :group } }
51
115
  end
52
116
 
53
- def respond_to_missing?(name, *)
54
- operations.key? name.to_sym
117
+ operation :delete_phone do
118
+ option :phone, Phone
119
+ option :group, FilledString, optional: true
120
+
121
+ path "delphone"
122
+ query { options.select { |key| %i[phone group].include? key } }
123
+ end
124
+
125
+ operation :send_sms do
126
+ option :to, Phone, optional: true
127
+ option :group, Group, optional: true
128
+ option :from, FilledString
129
+ option :text, FilledString
130
+ option :date, Future, optional: true
131
+ option :digital, Digital, optional: true
132
+ option :type, Channel, default: -> { 2 unless digital == 1 }
133
+
134
+ validate(:address_given) { !to ^ !group }
135
+
136
+ path { group && "sendtogroup" || testsend && "testsend" || "send" }
137
+ query { options.slice(:to, :group, :from, :text, :date, :digital, :type) }
138
+
139
+ response(200) { |*res| Response::WithId.build(*res) }
55
140
  end
56
141
  end
@@ -0,0 +1,12 @@
1
+ class SmsAero::Birthday < String
2
+ extend SmsAero::Callable
3
+
4
+ private
5
+
6
+ def initialize(value)
7
+ date = value.respond_to?(:to_date) ? value.to_date : Date.parse(value)
8
+ super date.strftime "%Y-%m-%d"
9
+ rescue
10
+ raise "#{value} is not a valid value for a birthday"
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ module SmsAero::Callable
2
+ def call(*args)
3
+ new(*args)
4
+ end
5
+ alias [] call
6
+ end
@@ -0,0 +1,15 @@
1
+ class SmsAero::Channel < String
2
+ extend SmsAero::Callable
3
+
4
+ def self.new(value)
5
+ value ? super(value) : Dry::Initializer::UNDEFINED
6
+ end
7
+
8
+ private
9
+
10
+ def initialize(value)
11
+ channel = value.to_s
12
+ return super(channel) if %w(1 2 3 4 6).include? channel
13
+ raise "Incorrect value #{channel} for channel"
14
+ end
15
+ end
@@ -0,0 +1,7 @@
1
+ module SmsAero::Digital
2
+ extend SmsAero::Callable
3
+
4
+ def self.new(value)
5
+ value ? 1 : 0
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ class SmsAero::FilledString < String
2
+ extend SmsAero::Callable
3
+
4
+ private
5
+
6
+ def initialize(value)
7
+ string = value.to_s
8
+ raise "blank value" if string == ""
9
+ super string
10
+ end
11
+ end
@@ -0,0 +1,16 @@
1
+ # Coercible Unix time in future
2
+ class SmsAero::Future < String
3
+ extend SmsAero::Callable
4
+
5
+ private
6
+
7
+ def initialize(value)
8
+ time = value.to_time if value.respond_to? :to_time
9
+ time ||= ::Time.parse(value) unless value.is_a? Numeric
10
+ number = time.to_i
11
+ return super(number.to_s) if number > ::Time.now.to_i
12
+ raise "#{value} is a time in the past, not in the future"
13
+ rescue
14
+ raise "#{value} is not a valid time"
15
+ end
16
+ end
@@ -0,0 +1,11 @@
1
+ class SmsAero::Group < String
2
+ extend SmsAero::Callable
3
+
4
+ private
5
+
6
+ def initialize(value)
7
+ group = value.to_s
8
+ raise "'#{value}' is not a valid group name" unless group[/^\w{1,20}$/]
9
+ super group
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module SmsAero::Optional
2
+ private
3
+
4
+ def initialize(opts)
5
+ super opts.each_with_object({}) { |(key, val), obj| obj[key.to_sym] = val }
6
+ end
7
+
8
+ def respond_to_missing?(name, *)
9
+ @__options__.respond_to? name
10
+ end
11
+
12
+ def method_missing(*args, &block)
13
+ respond_to_missing?(*args) ? @__options__.send(*args, &block) : super
14
+ end
15
+ end