active_sms 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Guardfile +4 -0
- data/README.md +186 -12
- data/active_sms.gemspec +4 -18
- data/lib/active_sms/backend/base.rb +14 -2
- data/lib/active_sms/backend/null_sender.rb +4 -0
- data/lib/active_sms/configuration.rb +19 -3
- data/lib/active_sms/response.rb +5 -1
- data/lib/active_sms/sending.rb +28 -7
- data/lib/active_sms/version.rb +1 -1
- metadata +17 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79322cdd7ad16ca0bf27f33d9d363fe19e5858d9
|
4
|
+
data.tar.gz: 059ec6de57e4b9162f2a7fa2821fea6b036cb274
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 213f02915314a030ab1ea55948a06153fc85db1204a39ce9785c93abb21b35c01346f8e9278b5185ff854832acb39a4ddfa1cba997c1033efaf63539215c0c24
|
7
|
+
data.tar.gz: ad8204fd9cc3084865499f351577c47253a17f459f44a4c2d11b9ce2eb3d8f69d10c1a2cd870f14b1736889b8dc16b775cd77e662f9524ca27517a736dcc50c8
|
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -1,34 +1,208 @@
|
|
1
1
|
# ActiveSMS
|
2
2
|
|
3
3
|
[![Build Status](https://travis-ci.org/Fedcomp/active_sms.svg?branch=master)](https://travis-ci.org/Fedcomp/active_sms)
|
4
|
+
[![Gem Version](https://badge.fury.io/rb/active_sms.svg)](https://badge.fury.io/rb/active_sms)
|
4
5
|
|
5
|
-
|
6
|
-
|
6
|
+
Unified way to send SMS in ruby!
|
7
|
+
Allows you to switch SMS services
|
8
|
+
without having to rewrite any code that actually sends SMS.
|
9
|
+
Supports multiple backends.
|
10
|
+
Sending SMS is not pain anymore!
|
7
11
|
|
8
|
-
## Installation
|
12
|
+
## Installation and usage
|
9
13
|
|
10
14
|
Add this line to your application's Gemfile:
|
11
15
|
|
12
16
|
```ruby
|
13
|
-
gem
|
17
|
+
gem "active_sms"
|
14
18
|
```
|
15
19
|
|
16
|
-
|
20
|
+
Then somewhere in your initialization code:
|
17
21
|
|
18
|
-
|
22
|
+
```ruby
|
23
|
+
ActiveSMS.configure do |config|
|
24
|
+
c.register_backend :my_backend_name, ActiveSMS::Backend::NullSender
|
25
|
+
c.default_backend = :my_backend_name
|
26
|
+
end
|
27
|
+
```
|
19
28
|
|
20
|
-
|
29
|
+
Now, whenever you need to send SMS, just do:
|
21
30
|
|
22
|
-
|
31
|
+
```ruby
|
32
|
+
phone = "799999999"
|
33
|
+
text = "My sms text"
|
23
34
|
|
24
|
-
|
35
|
+
ActiveSMS.send_sms(phone, text)
|
36
|
+
```
|
25
37
|
|
26
|
-
|
38
|
+
Now your code is capable of sending sms.
|
39
|
+
Later you may add any sms-backend you want, or even write your own.
|
27
40
|
|
28
|
-
|
41
|
+
### Adding real sms backend
|
42
|
+
|
43
|
+
If you followed steps above, you code still doesn't *really* send sms.
|
44
|
+
It uses `ActiveSMS::Backend::NullSender`
|
45
|
+
which actually does nothing when called.
|
46
|
+
To actually send sms you need to pick gem-provider
|
47
|
+
or write your own simple class.
|
48
|
+
|
49
|
+
At this moment i made ready to use implementation for only one service:
|
50
|
+
|
51
|
+
<table>
|
52
|
+
<tr>
|
53
|
+
<th>Gem name</th>
|
54
|
+
<th>Sms service name</th>
|
55
|
+
</tr>
|
56
|
+
<tr>
|
57
|
+
<td>
|
58
|
+
<a href="https://github.com/Fedcomp/active_sms-backend-smsru">
|
59
|
+
active_sms-backend-smsru
|
60
|
+
</a>
|
61
|
+
</td>
|
62
|
+
<td><a href="https://sms.ru">sms-ru</a></td>
|
63
|
+
</tr>
|
64
|
+
</table>
|
65
|
+
|
66
|
+
The gem documentation should be self explanatory.
|
67
|
+
|
68
|
+
### Writing your own sms backend
|
69
|
+
|
70
|
+
Here's simple class that can be used by ActiveSMS:
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
require "active_sms"
|
74
|
+
|
75
|
+
class ActiveSMS::Backend::MyCustomBackend < ActiveSMS::Backend::Base
|
76
|
+
def initialize(params = {})
|
77
|
+
# your initialization which parses params if needed.
|
78
|
+
# the params here is the ones you set in initializer
|
79
|
+
|
80
|
+
@token = params.delete(:token)
|
81
|
+
end
|
82
|
+
|
83
|
+
def send_sms(phone, sms_text)
|
84
|
+
# your code to call your sms service
|
85
|
+
# or somehow send actual sms
|
86
|
+
|
87
|
+
# if everything went fine, you may use helper from base class:
|
88
|
+
respond_with_status :success
|
89
|
+
|
90
|
+
# Or if you want to return failed status code:
|
91
|
+
respond_with_status :not_enough_funds
|
92
|
+
end
|
93
|
+
end
|
94
|
+
```
|
95
|
+
|
96
|
+
Then in initializer:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
ActiveSMS.configure do |c|
|
100
|
+
c.register_backend :my_custom_backend,
|
101
|
+
ActiveSMS::Backend::MyCustomBackend,
|
102
|
+
token: ENV["token"]
|
103
|
+
|
104
|
+
c.default_backend = :my_custom_backend
|
105
|
+
end
|
106
|
+
```
|
107
|
+
|
108
|
+
Usage:
|
109
|
+
|
110
|
+
```ruby
|
111
|
+
# somewhere in your code
|
112
|
+
result = ActiveSMS.send_sms(phone, text)
|
113
|
+
|
114
|
+
if result.success?
|
115
|
+
# do stuff
|
116
|
+
else
|
117
|
+
# request failed
|
118
|
+
fail_status = result.status
|
119
|
+
# :not_enough_funds for example
|
120
|
+
end
|
121
|
+
```
|
29
122
|
|
30
|
-
|
123
|
+
### Multiple backends
|
124
|
+
|
125
|
+
You can specify which backend to use per call:
|
126
|
+
|
127
|
+
```ruby
|
128
|
+
ActiveSMS.configure do |c|
|
129
|
+
c.register_backend :my_custom_backend,
|
130
|
+
ActiveSMS::Backend::MyCustomBackend,
|
131
|
+
token: ENV["token"]
|
132
|
+
|
133
|
+
c.register_backend :null_sender, ActiveSMS::Backend::NullSender
|
134
|
+
c.default_backend = :my_custom_backend
|
135
|
+
end
|
136
|
+
|
137
|
+
phone = "799999999"
|
138
|
+
text = "My sms text"
|
139
|
+
|
140
|
+
# Uses default backend
|
141
|
+
ActiveSMS.send_sms(phone, text)
|
142
|
+
|
143
|
+
# Uses backend you specify
|
144
|
+
ActiveSMS.send_sms(phone, text, backend: :null_sender)
|
145
|
+
```
|
146
|
+
|
147
|
+
### Real life example
|
148
|
+
|
149
|
+
If you develop application in group,
|
150
|
+
you probably don't want them all to send real SMS,
|
151
|
+
and instead you would prefer to emulate sending,
|
152
|
+
including SMS text preview (like SMS codes for registration).
|
153
|
+
|
154
|
+
However, on production you want
|
155
|
+
to actually send them using your service.
|
156
|
+
Here's how you can achieve that:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
ActiveSMS.configure do |c|
|
160
|
+
if development?
|
161
|
+
c.register_backend :my_custom_backend, ActiveSMS::Backend::NullSender
|
162
|
+
c.register_backend :my_custom_backend2, ActiveSMS::Backend::NullSender
|
163
|
+
end
|
164
|
+
|
165
|
+
if production?
|
166
|
+
c.register_backend :my_custom_backend,
|
167
|
+
ActiveSMS::Backend::MyCustomBackend,
|
168
|
+
token: ENV["token"]
|
169
|
+
|
170
|
+
c.register_backend :my_custom_backend2,
|
171
|
+
ActiveSMS::Backend::MyCustomBackend2,
|
172
|
+
token: ENV["token2"]
|
173
|
+
end
|
174
|
+
|
175
|
+
c.default_backend = :my_custom_backend
|
176
|
+
end
|
177
|
+
|
178
|
+
phone = "799999999"
|
179
|
+
text = "My sms text"
|
180
|
+
|
181
|
+
# Uses default backend
|
182
|
+
ActiveSMS.send_sms(phone, text)
|
183
|
+
|
184
|
+
# Uses backend you specify
|
185
|
+
ActiveSMS.send_sms(phone, text, backend: :my_custom_backend2)
|
186
|
+
|
187
|
+
# depending on your initializer it will use different backends
|
188
|
+
# in different environments.
|
189
|
+
```
|
190
|
+
|
191
|
+
Of course `development?` and `production?` is not real methods.
|
192
|
+
You have to detect environment yourself.
|
193
|
+
|
194
|
+
While possible, i strongly discourage to use more than two backends
|
195
|
+
(One default, another is required in certain situations for some reason).
|
196
|
+
It may make your code mess ;)
|
197
|
+
|
198
|
+
## Testing
|
199
|
+
|
200
|
+
I am planning to make rspec matcher to test if sms was sent.
|
201
|
+
For now you may just mock `ActiveSMS.send_sms` and check it was executed.
|
202
|
+
|
203
|
+
## Contributing
|
31
204
|
|
205
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/Fedcomp/active_sms
|
32
206
|
|
33
207
|
## License
|
34
208
|
|
data/active_sms.gemspec
CHANGED
@@ -10,31 +10,16 @@ Gem::Specification.new do |spec|
|
|
10
10
|
spec.email = ["aglergen@gmail.com"]
|
11
11
|
|
12
12
|
spec.summary = "Easily send sms using various sms backends!"
|
13
|
-
spec.description = <<-DESCRIPTION
|
14
|
-
Say you want to send sms in your app.
|
15
|
-
You think it's simple.
|
16
|
-
What (most likely) you do?
|
17
|
-
you create simple class to do it.
|
18
|
-
Then you need to mock it in tests,
|
19
|
-
and need to use different backend
|
20
|
-
in different environments, or even
|
21
|
-
use multiple backends in single environment.
|
22
|
-
This gems aims at solving most common cases
|
23
|
-
for sending sms in your app
|
24
|
-
DESCRIPTION
|
25
13
|
|
26
14
|
spec.homepage = "https://github.com/Fedcomp/active_sms"
|
27
15
|
spec.license = "MIT"
|
28
16
|
|
29
|
-
|
30
|
-
# To allow pushes either set the 'allowed_push_host'
|
31
|
-
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
32
|
-
if spec.respond_to?(:metadata)
|
33
|
-
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
34
|
-
else
|
17
|
+
unless spec.respond_to?(:metadata)
|
35
18
|
raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
|
36
19
|
end
|
37
20
|
|
21
|
+
spec.metadata["allowed_push_host"] = "https://rubygems.org"
|
22
|
+
|
38
23
|
spec.files = `git ls-files -z`
|
39
24
|
.split("\x0")
|
40
25
|
.reject { |f| f.match(%r{^(test|spec|features)/}) }
|
@@ -50,4 +35,5 @@ Gem::Specification.new do |spec|
|
|
50
35
|
spec.add_development_dependency "guard-rspec", "~> 4.7"
|
51
36
|
spec.add_development_dependency "pry-byebug", "~> 3.4"
|
52
37
|
spec.add_development_dependency "rubocop"
|
38
|
+
spec.add_development_dependency "guard-yard"
|
53
39
|
end
|
@@ -1,10 +1,22 @@
|
|
1
1
|
module ActiveSMS::Backend
|
2
|
-
#
|
3
|
-
#
|
2
|
+
# Base class for any sms provider service.
|
3
|
+
# Provides basic structure and helper methods.
|
4
|
+
# While not necessary to be subclassed now, may be necessary later.
|
4
5
|
class Base
|
6
|
+
# In initializer you may
|
7
|
+
# accept secrets which were defined in initializer
|
8
|
+
# or other configuration options if any.
|
9
|
+
#
|
10
|
+
# @params [Hash] List of arguments received from configure code.
|
5
11
|
def initialize(params = {})
|
6
12
|
end
|
7
13
|
|
14
|
+
# Interface for sending sms.
|
15
|
+
# Every subclass should implement method itself.
|
16
|
+
# Raises error in default implementation.
|
17
|
+
#
|
18
|
+
# @_phone [String] Phone number to send sms (not used in this implementation)
|
19
|
+
# @_text [String] Sms text (not used in this implementation)
|
8
20
|
def send_sms(_phone, _text)
|
9
21
|
raise NotImplementedError,
|
10
22
|
"You should create your own class for every sms service you use"
|
@@ -1,6 +1,10 @@
|
|
1
1
|
# Sms backend to not send anything.
|
2
2
|
# Purely for usage in tests
|
3
3
|
class ActiveSMS::Backend::NullSender < ActiveSMS::Backend::Base
|
4
|
+
# Method that emulates sms sending. Does nothing. Called by `ActiveSMS.send_sms`
|
5
|
+
#
|
6
|
+
# @_phone [String] Phone number to send sms (not used in this implementation)
|
7
|
+
# @_text [String] Sms text (not used in this implementation)
|
4
8
|
def send_sms(_phone, _text)
|
5
9
|
respond_with_status :success
|
6
10
|
end
|
@@ -1,21 +1,26 @@
|
|
1
|
-
#
|
1
|
+
# :nodoc:
|
2
2
|
module ActiveSMS
|
3
|
+
# @return [ActiveSMS::Configuration] object with configuration options
|
3
4
|
def self.config
|
4
5
|
@@config ||= Configuration.new
|
5
6
|
end
|
6
7
|
|
8
|
+
# Allows to configure ActiveSMS options and register backends
|
7
9
|
def self.configure
|
8
10
|
yield(config)
|
9
11
|
end
|
10
12
|
|
13
|
+
# resets ActiveSMS configuration to default
|
11
14
|
def self.reset!
|
12
15
|
@@config = nil
|
13
16
|
end
|
14
17
|
|
15
|
-
#
|
16
|
-
# rubocop:ignore Style/Documentation
|
18
|
+
# Configuration object for ActiveSMS
|
17
19
|
class Configuration
|
20
|
+
# returns key of the default sms backend
|
18
21
|
attr_reader :default_backend
|
22
|
+
|
23
|
+
# returns list of registered sms backends
|
19
24
|
attr_reader :backends
|
20
25
|
|
21
26
|
def initialize
|
@@ -23,6 +28,9 @@ module ActiveSMS
|
|
23
28
|
self.default_backend = :null_sender
|
24
29
|
end
|
25
30
|
|
31
|
+
# Specify default sms backend. It must be registered.
|
32
|
+
#
|
33
|
+
# @value [Symbol] Backend key which will be used as default
|
26
34
|
def default_backend=(value)
|
27
35
|
raise ArgumentError, "default_backend must be a symbol!" unless value.is_a? Symbol
|
28
36
|
|
@@ -33,6 +41,11 @@ module ActiveSMS
|
|
33
41
|
@default_backend = value
|
34
42
|
end
|
35
43
|
|
44
|
+
# Register sms provider backend
|
45
|
+
#
|
46
|
+
# @key [Symbol] Key for acessing backend in any part of ActiveSMS
|
47
|
+
# @classname [Class] Real class implementation of sms backend
|
48
|
+
# @params [Hash] Optional params for backend. Useful for passing tokens and options
|
36
49
|
def register_backend(key, classname, params = {})
|
37
50
|
raise ArgumentError, "backend key must be a symbol!" unless key.is_a? Symbol
|
38
51
|
|
@@ -47,6 +60,9 @@ module ActiveSMS
|
|
47
60
|
define_backend(key, classname, params)
|
48
61
|
end
|
49
62
|
|
63
|
+
# Removes registered sms backend
|
64
|
+
#
|
65
|
+
# @key [Symbol] Key of already registered backend
|
50
66
|
def remove_backend(key)
|
51
67
|
if key == default_backend
|
52
68
|
raise ArgumentError, "Removing default_backend is prohibited"
|
data/lib/active_sms/response.rb
CHANGED
@@ -1,15 +1,19 @@
|
|
1
|
-
#
|
1
|
+
# Response object.
|
2
|
+
# Generated on each ActiveSMS.send_sms by backend implementations.
|
2
3
|
class ActiveSMS::Response
|
4
|
+
# Sms sending status. Anything other than :success considered as failure.
|
3
5
|
attr_reader :status
|
4
6
|
|
5
7
|
def initialize(args = {})
|
6
8
|
@status = args.delete(:status)
|
7
9
|
end
|
8
10
|
|
11
|
+
# @return [Boolean] whether request was succesful or not.
|
9
12
|
def success?
|
10
13
|
@status == :success
|
11
14
|
end
|
12
15
|
|
16
|
+
# @return [Boolean] whether request has failed or not.
|
13
17
|
def failed?
|
14
18
|
!success?
|
15
19
|
end
|
data/lib/active_sms/sending.rb
CHANGED
@@ -1,18 +1,39 @@
|
|
1
|
-
#
|
1
|
+
# :nodoc:
|
2
2
|
module ActiveSMS
|
3
3
|
class << self
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
# Core of the gem, method responsible for sending sms
|
5
|
+
#
|
6
|
+
# @phone [String] Phone number for sms
|
7
|
+
# @text [String] Text for sms
|
8
|
+
# @args [Hash] Additional options for delivery. Currently only :backend
|
9
|
+
def send_sms(phone, text, args = {})
|
10
|
+
backend_name = args.delete(:backend)
|
11
|
+
backend_class(backend_name).new(backend_params(backend_name))
|
12
|
+
.send_sms(phone, text)
|
7
13
|
end
|
8
14
|
|
9
|
-
|
15
|
+
private
|
16
|
+
|
17
|
+
def backend_class(name)
|
18
|
+
return default_backend_class if name.nil?
|
19
|
+
|
20
|
+
if ActiveSMS.config.backends[name].nil?
|
21
|
+
raise ArgumentError, "#{name} backend is not registered"
|
22
|
+
end
|
23
|
+
|
24
|
+
ActiveSMS.config.backends[name][:class]
|
25
|
+
end
|
26
|
+
|
27
|
+
def default_backend_class
|
10
28
|
ActiveSMS.config.backends[ActiveSMS.config.default_backend][:class]
|
11
29
|
end
|
12
30
|
|
13
|
-
|
31
|
+
def backend_params(name)
|
32
|
+
return default_backend_params if name.nil?
|
33
|
+
ActiveSMS.config.backends[name][:params]
|
34
|
+
end
|
14
35
|
|
15
|
-
def
|
36
|
+
def default_backend_params
|
16
37
|
ActiveSMS.config.backends[ActiveSMS.config.default_backend][:params]
|
17
38
|
end
|
18
39
|
end
|
data/lib/active_sms/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_sms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Fedcomp
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -108,17 +108,21 @@ dependencies:
|
|
108
108
|
- - ">="
|
109
109
|
- !ruby/object:Gem::Version
|
110
110
|
version: '0'
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: guard-yard
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
description:
|
122
126
|
email:
|
123
127
|
- aglergen@gmail.com
|
124
128
|
executables: []
|