creatary-sdk 1.3.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.
- data/.gitignore +4 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.mkd +66 -0
- data/Rakefile +40 -0
- data/creatary-sdk.gemspec +45 -0
- data/lib/creatary.rb +17 -0
- data/lib/creatary/api.rb +74 -0
- data/lib/creatary/api/charging.rb +36 -0
- data/lib/creatary/api/location.rb +26 -0
- data/lib/creatary/api/oauth.rb +55 -0
- data/lib/creatary/api/sms.rb +47 -0
- data/lib/creatary/configuration.rb +83 -0
- data/lib/creatary/error.rb +40 -0
- data/lib/creatary/railtie.rb +30 -0
- data/lib/creatary/user.rb +16 -0
- data/lib/creatary/version.rb +4 -0
- data/spec/fixtures/getcoord_success.json +11 -0
- data/spec/fixtures/send_sms_success.json +6 -0
- data/spec/location_get_spec.rb +46 -0
- data/spec/sms_receive_spec.rb +68 -0
- data/spec/sms_send_spec.rb +71 -0
- data/spec/spec_helper.rb +14 -0
- metadata +177 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Nokia Siemens Networks
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.mkd
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
The Creatary Ruby gem
|
2
|
+
====================================
|
3
|
+
A Ruby wrapper for the Creatary REST APIs
|
4
|
+
|
5
|
+
Installation
|
6
|
+
------------
|
7
|
+
gem install creatary-sdk
|
8
|
+
|
9
|
+
Documentation
|
10
|
+
-------------
|
11
|
+
<https://creatary.com>
|
12
|
+
|
13
|
+
How to Use
|
14
|
+
----------
|
15
|
+
If you are using rails then:
|
16
|
+
|
17
|
+
1. Add the creatary-sdk gem to your Gemfile
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'creatary-sdk'
|
21
|
+
```
|
22
|
+
|
23
|
+
2. Create a creatary.yml file in config with following contents:
|
24
|
+
|
25
|
+
```yaml
|
26
|
+
development: &defaults
|
27
|
+
consumer_key: # the consumer key generated in telcoassetmarketplace.com for you application
|
28
|
+
consumer_secret: # the consumer secret generated in telcoassetmarketplace.com for you application
|
29
|
+
consumer_handler: # the of the class that implements the Creatary handler logic
|
30
|
+
test:
|
31
|
+
<<: *defaults
|
32
|
+
production:
|
33
|
+
<<: *defaults
|
34
|
+
```
|
35
|
+
|
36
|
+
3. Add following route to your routes.rb
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
match '/creatary/(:string)' => Creatary::API # you can replace 'creatary' with any other namespace
|
40
|
+
```
|
41
|
+
|
42
|
+
4. Implement the Creatary handler logic (e.g.: creatary_handler.rb in helpers)
|
43
|
+
|
44
|
+
```ruby
|
45
|
+
class CreataryHandler
|
46
|
+
def authorized(user, session)
|
47
|
+
# should return the URL to which Creatary should redirect
|
48
|
+
end
|
49
|
+
|
50
|
+
def denied(session)
|
51
|
+
# should return the URL to which Creatary should redirect
|
52
|
+
end
|
53
|
+
|
54
|
+
def receive_sms(from_user, to_app, body)
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
```
|
59
|
+
|
60
|
+
5. The routes exposed by the gem in your rails application are:
|
61
|
+
|
62
|
+
```ruby
|
63
|
+
/creatary/authorize
|
64
|
+
/creatary/receive_sms # use this one (complement to form absolute path) as SMS URL when registering your application in telcoassetmarketplace.com
|
65
|
+
/creatary/oauth_callback # use this one (complement to form absolute path) as OAUTH callback URL when registering your application in telcoassetmarketplace.com
|
66
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
begin
|
2
|
+
require "bundler"
|
3
|
+
Bundler.setup
|
4
|
+
rescue LoadError
|
5
|
+
$stderr.puts "You need to have Bundler installed to be able build this gem."
|
6
|
+
end
|
7
|
+
|
8
|
+
gemspec = eval(File.read(Dir["*.gemspec"].first))
|
9
|
+
|
10
|
+
|
11
|
+
desc "Validate the gemspec"
|
12
|
+
task :gemspec do
|
13
|
+
gemspec.validate
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Build gem locally"
|
17
|
+
task :build => :gemspec do
|
18
|
+
system "gem build #{gemspec.name}.gemspec"
|
19
|
+
FileUtils.mkdir_p "pkg"
|
20
|
+
FileUtils.mv "#{gemspec.name}-#{gemspec.version}.gem", "pkg"
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "Install gem locally"
|
24
|
+
task :install => :build do
|
25
|
+
system "gem install pkg/#{gemspec.name}-#{gemspec.version}"
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "Clean automatically generated files"
|
29
|
+
task :clean do
|
30
|
+
FileUtils.rm_rf "pkg"
|
31
|
+
end
|
32
|
+
|
33
|
+
require 'spec/rake/spectask'
|
34
|
+
|
35
|
+
Spec::Rake::SpecTask.new(:spec) do |t|
|
36
|
+
t.spec_files = Dir.glob('spec/**/*_spec.rb')
|
37
|
+
end
|
38
|
+
|
39
|
+
desc "Run tests"
|
40
|
+
task :default => :spec
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# coding: UTF-8
|
2
|
+
require File.expand_path('../lib/creatary/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.add_runtime_dependency('sinatra', '~> 1.2.1')
|
6
|
+
s.add_runtime_dependency('json', '~> 1.5')
|
7
|
+
s.add_runtime_dependency('oauth', '~> 0.4.3')
|
8
|
+
|
9
|
+
s.add_development_dependency('rake', '= 0.9.2')
|
10
|
+
s.add_development_dependency('rspec', '= 1.3.2')
|
11
|
+
s.add_development_dependency('rack-test', "~> 0.6.1")
|
12
|
+
s.add_development_dependency('mocha', '~> 0.9.0')
|
13
|
+
s.add_development_dependency('webmock', '~> 1.7.0')
|
14
|
+
s.add_development_dependency('simplecov', '~> 0.5.0')
|
15
|
+
|
16
|
+
s.name = "creatary-sdk"
|
17
|
+
s.version = Creatary::VERSION.dup
|
18
|
+
s.platform = Gem::Platform::RUBY
|
19
|
+
s.authors = ["Carlos Manzanares"]
|
20
|
+
s.email = ["developers@creatary.com"]
|
21
|
+
s.homepage = "https://github.com/creatary/creatary-ruby-sdk"
|
22
|
+
s.description = %q{The Ruby gem for the Creatary REST APIs}
|
23
|
+
s.summary = "Creatary Ruby gem"
|
24
|
+
s.rubyforge_project = s.name
|
25
|
+
|
26
|
+
s.required_rubygems_version = Gem::Requirement.new('>= 1.3.6') if s.respond_to? :required_rubygems_version=
|
27
|
+
|
28
|
+
s.require_path = 'lib'
|
29
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
30
|
+
s.files = `git ls-files`.split("\n")
|
31
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
32
|
+
|
33
|
+
s.post_install_message =<<eos
|
34
|
+
********************************************************************************
|
35
|
+
|
36
|
+
Visit our community pages for up-to-date information on
|
37
|
+
Creatary:
|
38
|
+
https://creatary.com/
|
39
|
+
Notice that in order to use this gem you will also need to register as a
|
40
|
+
developer in Creatary:
|
41
|
+
https://telcoassetmarketplace.com
|
42
|
+
|
43
|
+
********************************************************************************
|
44
|
+
eos
|
45
|
+
end
|
data/lib/creatary.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'creatary/railtie' if defined? ::Rails::Railtie
|
2
|
+
require 'creatary/configuration'
|
3
|
+
require 'creatary/api'
|
4
|
+
|
5
|
+
module Creatary
|
6
|
+
extend Configuration
|
7
|
+
|
8
|
+
# If in rails environment then we use the rails default logger
|
9
|
+
# otherwise we create one that points to the standard output
|
10
|
+
LOGGER =
|
11
|
+
if defined? Rails
|
12
|
+
Rails.logger
|
13
|
+
else
|
14
|
+
Logger.new(STDOUT)
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
data/lib/creatary/api.rb
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'oauth'
|
3
|
+
require 'creatary/error'
|
4
|
+
require 'creatary/user'
|
5
|
+
|
6
|
+
module Creatary
|
7
|
+
# Wrapper for the Creatary REST API
|
8
|
+
#
|
9
|
+
# @note All methods have been separated into modules and follow the same grouping used in {https://creatary.com the Creatary API Documentation}.
|
10
|
+
# @see http://creatary.com
|
11
|
+
class API < Sinatra::Base
|
12
|
+
# Require api method modules after initializing the API class in
|
13
|
+
# order to avoid a superclass mismatch error, allowing those modules to be
|
14
|
+
# API-namespaced.
|
15
|
+
require 'creatary/api/oauth'
|
16
|
+
require 'creatary/api/sms'
|
17
|
+
require 'creatary/api/location'
|
18
|
+
require 'creatary/api/charging'
|
19
|
+
|
20
|
+
# Dispatches the request to the Creatary handler configured by
|
21
|
+
# this gem client
|
22
|
+
def dispatch_to_handler(method, *args)
|
23
|
+
if Creatary.consumer_handler.nil?
|
24
|
+
LOGGER.error 'Application has not configured the Creatary consumer_handler'
|
25
|
+
raise InvalidConsumerHandler.new 'Application has not configured the Creatary consumer_handler'
|
26
|
+
end
|
27
|
+
|
28
|
+
if Creatary.consumer_handler.respond_to?(method)
|
29
|
+
begin
|
30
|
+
return Creatary.consumer_handler.send(method, *args)
|
31
|
+
rescue Creatary::Error => error
|
32
|
+
LOGGER.error 'Application has suffered an internal error: ' + error.message + ', ' + error.body
|
33
|
+
raise error
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
|
39
|
+
# Dispatches the request to the Creatary REST API
|
40
|
+
def self.dispatch_to_server(http_method, endpoint, user, payload='')
|
41
|
+
consumer = create_oauth_consumer
|
42
|
+
access_token = OAuth::AccessToken.new(consumer, user.access_token, user.token_secret)
|
43
|
+
|
44
|
+
if (http_method == :get)
|
45
|
+
response = access_token.send(http_method, endpoint, {'Content-Type' => 'application/json'})
|
46
|
+
else
|
47
|
+
response = access_token.send(http_method, endpoint, payload, {'Content-Type' => 'application/json'})
|
48
|
+
end
|
49
|
+
|
50
|
+
if response.class == Net::HTTPOK
|
51
|
+
return response.body
|
52
|
+
elsif response.class == Net::HTTPUnauthorized
|
53
|
+
LOGGER.error 'Request not authorized ' + response.message + ', ' + response.body
|
54
|
+
raise RequestNotAuthorized.new(response.message, response.body)
|
55
|
+
elsif response.class == Net::HTTPBadRequest
|
56
|
+
if response.body.include? 'consumer_key_unknown'
|
57
|
+
LOGGER.error 'Configured Creatary consumer_key is not valid: ' + response.message + ', ' + response.body
|
58
|
+
raise InvalidConsumerKey.new(response.message, response.body)
|
59
|
+
elsif response.body.include? 'signature_invalid'
|
60
|
+
LOGGER.error 'Configured Creatary consumer_secret is not valid: ' + response.message + ', ' + response.body
|
61
|
+
raise InvalidConsumerSecret.new(response.message, response.body)
|
62
|
+
else
|
63
|
+
raise UnexpectedError.new(response.message, response.body)
|
64
|
+
end
|
65
|
+
elsif response.class == Net::HTTPServiceUnavailable
|
66
|
+
LOGGER.error 'Creatary service ' + endpoint + ' not available'
|
67
|
+
raise ServiceUnavailable.new(response.message, response.body)
|
68
|
+
else
|
69
|
+
raise UnexpectedError.new(response.message, response.body)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'creatary/user'
|
3
|
+
require 'creatary/error'
|
4
|
+
|
5
|
+
# Charging part of the Creatary REST API
|
6
|
+
module Creatary
|
7
|
+
class API
|
8
|
+
# Requests for charging or payment to the subscriber account in the operator billing system by amount.
|
9
|
+
#
|
10
|
+
# @return [Hash]
|
11
|
+
# {"status"=>{"code"=>0, "message"=>"Request was handled succesfully"}}
|
12
|
+
def self.charge_by_amount(user, amount)
|
13
|
+
begin
|
14
|
+
payload = JSON.generate({'method' => 'AMOUNT', 'amount' => amount.to_s})
|
15
|
+
response = dispatch_to_server(:post, '/api/1/charge/request', user, payload)
|
16
|
+
JSON.parse response
|
17
|
+
rescue Creatary::ServiceUnavailable
|
18
|
+
raise Creatary::ServiceUnavailable.new 'The charging service is not available. If you are using the service on a persona, i.e.: through the sandbox, then remember to set the balance of that persona'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Requests for charging or payment to the subscriber account in the operator billing system byt charging code.
|
23
|
+
#
|
24
|
+
# @return [Hash]
|
25
|
+
# {"status"=>{"code"=>0, "message"=>"Request was handled succesfully"}}
|
26
|
+
def self.charge_by_code(user, code)
|
27
|
+
begin
|
28
|
+
payload = JSON.generate({'method' => 'CODE', 'charging_code' => code.to_s})
|
29
|
+
response = dispatch_to_server(:post, '/api/1/charge/request', user, payload)
|
30
|
+
JSON.parse response
|
31
|
+
rescue Creatary::ServiceUnavailable
|
32
|
+
raise Creatary::ServiceUnavailable.new 'The charging service is not available. If you are using the service on a persona, i.e.: through the sandbox, then remember to set the balance of that persona'
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'creatary/user'
|
3
|
+
require 'creatary/error'
|
4
|
+
|
5
|
+
# SMS part of the Creatary REST API
|
6
|
+
module Creatary
|
7
|
+
class API
|
8
|
+
# Find the location (coordinates) of a user
|
9
|
+
#
|
10
|
+
# @return [Hash]
|
11
|
+
# {"body"=>
|
12
|
+
# {"latitude"=>51.618,
|
13
|
+
# "timestamp"=>1302185772456,
|
14
|
+
# "accuracy"=>100,
|
15
|
+
# "longitude"=>23.9063},
|
16
|
+
# "status"=>{"code"=>0, "message"=>"Request was handled succesfully"}}
|
17
|
+
def self.getcoord(user)
|
18
|
+
begin
|
19
|
+
response = dispatch_to_server(:get, '/api/1/location/getcoord', user)
|
20
|
+
JSON.parse response
|
21
|
+
rescue Creatary::ServiceUnavailable
|
22
|
+
raise Creatary::ServiceUnavailable.new 'The location service is not available. If you are using the service on a persona, i.e.: through the sandbox, then remember to set the location of the persona'
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'oauth'
|
3
|
+
require 'creatary/error'
|
4
|
+
require 'creatary/user'
|
5
|
+
|
6
|
+
# OAUTH part of the Creatary REST API
|
7
|
+
module Creatary
|
8
|
+
class API
|
9
|
+
enable :sessions
|
10
|
+
|
11
|
+
# Authorizes a user of Creatary to use your application
|
12
|
+
# After the OAUTH flow is finished then the configured consumer_handler.authorized(user, session)
|
13
|
+
# or consumer_handler.denied(session) are invoked
|
14
|
+
get '/*/authorize' do
|
15
|
+
consumer = Creatary::API.create_oauth_consumer
|
16
|
+
request_token = consumer.get_request_token
|
17
|
+
session[:request_token] = request_token
|
18
|
+
|
19
|
+
oauth_callback_url = url('/' + Creatary.callback_path + '/oauth_callback')
|
20
|
+
redirect request_token.authorize_url(:oauth_callback => oauth_callback_url)
|
21
|
+
end
|
22
|
+
|
23
|
+
# OAUTH callback for Creatary
|
24
|
+
# @private
|
25
|
+
get '/*/oauth_callback' do
|
26
|
+
if params[:denied].nil?
|
27
|
+
consumer = Creatary::API.create_oauth_consumer
|
28
|
+
request_token = session[:request_token]
|
29
|
+
verifier = params[:oauth_verifier]
|
30
|
+
access_token = request_token.get_access_token(:oauth_verifier => verifier)
|
31
|
+
user = User.new(access_token.token, access_token.secret)
|
32
|
+
redirect url(dispatch_to_handler('authorized', user, session))
|
33
|
+
else
|
34
|
+
redirect url(dispatch_to_handler('denied', session))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
def self.create_oauth_consumer
|
40
|
+
if Creatary.consumer_key.nil? or Creatary.consumer_secret.nil?
|
41
|
+
raise OAuthConsumerAttributesMissing.new
|
42
|
+
end
|
43
|
+
|
44
|
+
OAuth::Consumer.new(Creatary.consumer_key, Creatary.consumer_secret,
|
45
|
+
{
|
46
|
+
:site => Creatary.site,
|
47
|
+
:request_token_path => Creatary.request_token_path,
|
48
|
+
:access_token_path => Creatary.access_token_path,
|
49
|
+
:authorize_path => Creatary.authorize_path,
|
50
|
+
:scheme => Creatary.oauth_scheme,
|
51
|
+
:http_method => Creatary.oauth_http_method
|
52
|
+
})
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'sinatra'
|
2
|
+
require 'oauth'
|
3
|
+
require 'json'
|
4
|
+
require 'creatary/user'
|
5
|
+
|
6
|
+
# SMS part of the Creatary REST API
|
7
|
+
module Creatary
|
8
|
+
class API
|
9
|
+
# URL handler for receiving SMS
|
10
|
+
# After receiving an SMS, the configured
|
11
|
+
# consumer_handler.receive_sms(from_user, to_app, body)
|
12
|
+
# is invoked
|
13
|
+
#
|
14
|
+
# @private
|
15
|
+
post "/*/receive_sms" do
|
16
|
+
request.body.rewind # in case someone already read it
|
17
|
+
|
18
|
+
data = JSON.parse request.body.read
|
19
|
+
|
20
|
+
access_token = data["access_token"]
|
21
|
+
token_secret = data["token_secret"]
|
22
|
+
from_user = User.new(access_token, token_secret)
|
23
|
+
to_app = data["to"]
|
24
|
+
body = data["body"]
|
25
|
+
transaction_id = data["transaction_id"]
|
26
|
+
|
27
|
+
begin
|
28
|
+
dispatch_to_handler('receive_sms', from_user, to_app, body, transaction_id)
|
29
|
+
response.status = 200
|
30
|
+
return ''
|
31
|
+
rescue Error => error
|
32
|
+
response.status = 500
|
33
|
+
return error.message
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Sends an SMS
|
38
|
+
def self.send_sms(from_app, to_user, body, transaction_id = nil)
|
39
|
+
payload = {'body' => body, 'from' => from_app}
|
40
|
+
if transaction_id
|
41
|
+
payload["transaction_id"] = transaction_id
|
42
|
+
end
|
43
|
+
response = dispatch_to_server(:post, '/api/1/sms/send', to_user, JSON.generate(payload))
|
44
|
+
JSON.parse response
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Creatary
|
2
|
+
# Defines constants and methods related to configuration
|
3
|
+
module Configuration
|
4
|
+
# An array of valid keys in the options hash when configuring a {Creatary::API}
|
5
|
+
VALID_OPTIONS_KEYS = [
|
6
|
+
:consumer_key,
|
7
|
+
:consumer_secret,
|
8
|
+
:consumer_handler,
|
9
|
+
:site,
|
10
|
+
:request_token_path,
|
11
|
+
:access_token_path,
|
12
|
+
:authorize_path,
|
13
|
+
:oauth_scheme,
|
14
|
+
:oauth_http_method,
|
15
|
+
:callback_path].freeze
|
16
|
+
|
17
|
+
# @private
|
18
|
+
attr_accessor *VALID_OPTIONS_KEYS
|
19
|
+
|
20
|
+
def consumer_handler=(consumer_handler)
|
21
|
+
if consumer_handler.class == String
|
22
|
+
begin
|
23
|
+
@consumer_handler = Object.const_get(consumer_handler).new
|
24
|
+
rescue NameError => error
|
25
|
+
LOGGER.error 'Application has provided an invalid Creatary consumer_handler: ' + Creatary.consumer_handler
|
26
|
+
raise InvalidConsumerHandler.new 'Application has provided an invalid Creatary consumer_handler: ' + Creatary.consumer_handler
|
27
|
+
end
|
28
|
+
else
|
29
|
+
@consumer_handler = consumer_handler
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def consumer_handler
|
34
|
+
@consumer_handler
|
35
|
+
end
|
36
|
+
|
37
|
+
# When this module is extended, set all configuration options to their default values
|
38
|
+
def self.extended(base)
|
39
|
+
base.reset
|
40
|
+
end
|
41
|
+
|
42
|
+
# Convenience method to allow configuration options to be set in a block
|
43
|
+
def configure
|
44
|
+
yield self
|
45
|
+
end
|
46
|
+
|
47
|
+
def configure(config)
|
48
|
+
unless config.empty?
|
49
|
+
self.consumer_key = config['consumer_key'] if config['consumer_key']
|
50
|
+
self.consumer_secret = config['consumer_secret'] if config['consumer_secret']
|
51
|
+
self.consumer_handler = config['consumer_handler'] if config['consumer_handler']
|
52
|
+
self.site = config['site'] if config['site']
|
53
|
+
self.request_token_path = config['request_token_path'] if config['request_token_path']
|
54
|
+
self.access_token_path = config['access_token_path'] if config['access_token_path']
|
55
|
+
self.authorize_path = config['authorize_path'] if config['authorize_path']
|
56
|
+
self.oauth_scheme = config['oauth_scheme'] if config['oauth_scheme']
|
57
|
+
self.oauth_http_method = config['oauth_http_method'] if config['oauth_http_method']
|
58
|
+
self.callback_path = config['callback_path'] if config['callback_path']
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Create a hash of options and their values
|
63
|
+
def options
|
64
|
+
Hash[VALID_OPTIONS_KEYS.map {|key| [key, send(key)] }]
|
65
|
+
end
|
66
|
+
|
67
|
+
# Reset all configuration options to defaults
|
68
|
+
def reset
|
69
|
+
self.consumer_key = nil
|
70
|
+
self.consumer_secret = nil
|
71
|
+
self.consumer_handler = nil
|
72
|
+
self.site = 'https://telcoassetmarketplace.com'
|
73
|
+
self.request_token_path = '/api/1/oauth/request_token'
|
74
|
+
self.access_token_path = '/api/1/oauth/access_token'
|
75
|
+
self.authorize_path = '/web/authorize'
|
76
|
+
self.oauth_scheme = :query_string
|
77
|
+
self.oauth_http_method = :get
|
78
|
+
self.callback_path = 'creatary'
|
79
|
+
self
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Creatary
|
2
|
+
# Custom error class for rescuing from all Creatary errors
|
3
|
+
class Error < StandardError
|
4
|
+
attr_reader :body
|
5
|
+
|
6
|
+
def initialize(message, body = '')
|
7
|
+
@body = body
|
8
|
+
super message
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Raised when client tries to use any of the API methods that require OAUTH
|
13
|
+
# without configuring the consumer_key or consumer_secret
|
14
|
+
class OAuthConsumerAttributesMissing < Error
|
15
|
+
def initialize
|
16
|
+
super 'consumer_key or consumer_secret not configured'
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Raised when client tries to use any of the API methods without user authorization
|
21
|
+
class RequestNotAuthorized < Error; end
|
22
|
+
|
23
|
+
# Raised when client performs a wrong OAUTH interaction (this is a super-class)
|
24
|
+
class OAuthError < Error; end
|
25
|
+
|
26
|
+
# Raised when client is using an invalid consumer_key
|
27
|
+
class InvalidConsumerKey < OAuthError; end
|
28
|
+
|
29
|
+
# Raised when client is using an invalid consumer_secret
|
30
|
+
class InvalidConsumerSecret < OAuthError; end
|
31
|
+
|
32
|
+
# Raised when client is using an invalid consumer_handler
|
33
|
+
class InvalidConsumerHandler < Error; end
|
34
|
+
|
35
|
+
class UnexpectedError < Error; end
|
36
|
+
|
37
|
+
# Raised when one of the Creatary services is not available
|
38
|
+
class ServiceUnavailable < Error; end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'rails'
|
2
|
+
|
3
|
+
module Creatary
|
4
|
+
class CreataryRailtie < Rails::Railtie
|
5
|
+
initializer "creatary.boot" do
|
6
|
+
configure_with_yaml
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
# Attempts to load the Creatary configuration from config/creatary.yml
|
12
|
+
# in a rails 3 application.
|
13
|
+
# Besides using a creatary.yml, developers can also configure directly Creatary settings, e.g.:
|
14
|
+
# Creatary.consumer_key = 'h42woy35tl08o44l'
|
15
|
+
def configure_with_yaml
|
16
|
+
cfg = load_config(Rails.root.join('config', 'creatary.yml')).freeze
|
17
|
+
Creatary.configure(cfg)
|
18
|
+
end
|
19
|
+
|
20
|
+
def load_config(yaml_file)
|
21
|
+
return {} unless File.exist?(yaml_file)
|
22
|
+
cfg = YAML::load(File.open(yaml_file))
|
23
|
+
if defined? Rails
|
24
|
+
cfg = cfg[Rails.env]
|
25
|
+
end
|
26
|
+
cfg
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Creatary
|
2
|
+
# Represents an end-user of Creatary (a subscriber)
|
3
|
+
class User
|
4
|
+
attr_accessor :access_token
|
5
|
+
attr_accessor :token_secret
|
6
|
+
|
7
|
+
def initialize(access_token, token_secret)
|
8
|
+
@access_token = access_token
|
9
|
+
@token_secret = token_secret
|
10
|
+
end
|
11
|
+
|
12
|
+
def ==(another_user)
|
13
|
+
self.access_token == another_user.access_token and self.token_secret == another_user.token_secret
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'creatary/api'
|
3
|
+
require 'creatary/user'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'json'
|
6
|
+
require 'webmock/rspec'
|
7
|
+
|
8
|
+
describe Creatary::API, "#getcoord" do
|
9
|
+
include WebMock::API
|
10
|
+
include OAuthSettings
|
11
|
+
|
12
|
+
it "sends location request to platform" do
|
13
|
+
#given
|
14
|
+
Creatary.expects(:consumer_key).twice().returns(ConsumerKey)
|
15
|
+
Creatary.expects(:consumer_secret).twice().returns(ConsumerSecret)
|
16
|
+
Creatary.expects(:site).returns(Site)
|
17
|
+
Creatary.expects(:request_token_path).returns('/api/1/oauth/request_token')
|
18
|
+
Creatary.expects(:access_token_path).returns('/api/1/oauth/access_token')
|
19
|
+
Creatary.expects(:authorize_path).returns('/web/authorize')
|
20
|
+
Creatary.expects(:oauth_scheme).returns(:query_string)
|
21
|
+
Creatary.expects(:oauth_http_method).returns(:get)
|
22
|
+
http_stub = stub_request(:get, /.*\/api\/1\/location\/getcoord.*/).with { |request| assert_query(request.uri, OAuthParams) }.to_return(:body => load_fixture("getcoord_success.json"))
|
23
|
+
|
24
|
+
#when
|
25
|
+
body = Creatary::API.getcoord(Creatary::User.new(AccessToken, AccessSecret))
|
26
|
+
|
27
|
+
#then
|
28
|
+
http_stub.should have_been_requested.times(1)
|
29
|
+
body["status"]["code"].should == 0
|
30
|
+
body["status"]["message"].should == "Message sent successfully"
|
31
|
+
end
|
32
|
+
|
33
|
+
def load_fixture(fixture)
|
34
|
+
IO.read("spec/fixtures/#{fixture}")
|
35
|
+
end
|
36
|
+
|
37
|
+
def assert_query(uri, params)
|
38
|
+
uri_params = uri.query_values
|
39
|
+
params.each do |key, value|
|
40
|
+
if not value.match(uri_params[key])
|
41
|
+
return false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
return true
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'creatary/api'
|
3
|
+
require 'creatary/user'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'mocha'
|
6
|
+
require 'json'
|
7
|
+
|
8
|
+
describe Creatary::API, "when receiving sms" do
|
9
|
+
include Rack::Test::Methods
|
10
|
+
|
11
|
+
def app
|
12
|
+
Creatary::API
|
13
|
+
end
|
14
|
+
|
15
|
+
before(:all) do
|
16
|
+
logger = stub('logger')
|
17
|
+
logger.stubs(:error)
|
18
|
+
Creatary.const_set(:LOGGER, logger)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should pass request to creatary sms handler and render success" do
|
22
|
+
#given
|
23
|
+
handler = stub('consumer_handler')
|
24
|
+
handler.expects(:respond_to?).with('receive_sms').returns(true)
|
25
|
+
handler.expects(:send).with('receive_sms', Creatary::User.new('token', 'secret'), 'to_app', 'message', nil)
|
26
|
+
Creatary.expects(:consumer_handler).times(3).returns(handler)
|
27
|
+
#when
|
28
|
+
post '/creatary/receive_sms', JSON.generate({ 'body' => 'message', 'to' => 'to_app', 'from' => 'from_user' ,'access_token' => 'token', 'token_secret' => 'secret'})
|
29
|
+
#then
|
30
|
+
last_response.should be_ok
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should pass request with transaction to creatary sms handler and render success" do
|
34
|
+
#given
|
35
|
+
handler = stub('consumer_handler')
|
36
|
+
handler.expects(:respond_to?).with('receive_sms').returns(true)
|
37
|
+
handler.expects(:send).with('receive_sms', Creatary::User.new('token', 'secret'), 'to_app', 'message', 'tran_id')
|
38
|
+
Creatary.expects(:consumer_handler).times(3).returns(handler)
|
39
|
+
#when
|
40
|
+
post '/creatary/receive_sms', JSON.generate({ 'body' => 'message', 'to' => 'to_app', 'from' => 'from_user','transaction_id' => 'tran_id','access_token' => 'token', 'token_secret' => 'secret'})
|
41
|
+
#then
|
42
|
+
last_response.should be_ok
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should pass request to creatary sms handler and render error on unexpected error" do
|
46
|
+
#given
|
47
|
+
handler = stub('consumer_handler')
|
48
|
+
handler.expects(:respond_to?).with('receive_sms').returns(true)
|
49
|
+
handler.stubs(:send).raises(Creatary::UnexpectedError.new("Cannot handle"))
|
50
|
+
Creatary.expects(:consumer_handler).times(3).returns(handler)
|
51
|
+
#when
|
52
|
+
post '/creatary/receive_sms', JSON.generate({ 'body' => 'message', 'to' => 'to_app', 'from' => 'from_user','transaction_id' => 'tran_id','access_token' => 'token', 'token_secret' => 'secret'})
|
53
|
+
#then
|
54
|
+
last_response.should be_server_error
|
55
|
+
last_response.body.should == "Cannot handle"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should pass request to creatary sms handler and render error on missing consumer_handler" do
|
59
|
+
#given
|
60
|
+
handler = stub('consumer_handler')
|
61
|
+
Creatary.expects(:consumer_handler).times(1).returns(nil)
|
62
|
+
#when
|
63
|
+
post '/creatary/receive_sms', JSON.generate({ 'body' => 'message', 'to' => 'to_app', 'from' => 'from_user','transaction_id' => 'tran_id','access_token' => 'token', 'token_secret' => 'secret'})
|
64
|
+
#then
|
65
|
+
last_response.should be_server_error
|
66
|
+
last_response.body.should == "Application has not configured the Creatary consumer_handler"
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'creatary/api'
|
3
|
+
require 'creatary/user'
|
4
|
+
require 'rack/test'
|
5
|
+
require 'json'
|
6
|
+
require 'webmock/rspec'
|
7
|
+
|
8
|
+
describe Creatary::API, "when sending sms" do
|
9
|
+
include WebMock::API
|
10
|
+
include OAuthSettings
|
11
|
+
|
12
|
+
it "should successfully send the request to platform" do
|
13
|
+
#given
|
14
|
+
Creatary.expects(:consumer_key).twice().returns(ConsumerKey)
|
15
|
+
Creatary.expects(:consumer_secret).twice().returns(ConsumerSecret)
|
16
|
+
Creatary.expects(:site).returns(Site)
|
17
|
+
Creatary.expects(:request_token_path).returns('/api/1/oauth/request_token')
|
18
|
+
Creatary.expects(:access_token_path).returns('/api/1/oauth/access_token')
|
19
|
+
Creatary.expects(:authorize_path).returns('/web/authorize')
|
20
|
+
Creatary.expects(:oauth_scheme).returns(:query_string)
|
21
|
+
Creatary.expects(:oauth_http_method).returns(:get)
|
22
|
+
http_stub = stub_request(:post, /.*\/api\/1\/sms\/send.*/).with { |request| assert_request(request, { :query => OAuthParams, :body => "{\"body\":\"test message\",\"from\":\"to_app\"}"})}.to_return(:body => load_fixture("send_sms_success.json"))
|
23
|
+
|
24
|
+
#when
|
25
|
+
body = Creatary::API.send_sms("to_app", Creatary::User.new(AccessToken, AccessSecret), 'test message')
|
26
|
+
|
27
|
+
#then
|
28
|
+
http_stub.should have_been_requested.times(1)
|
29
|
+
body["status"]["code"].should == 0
|
30
|
+
body["status"]["message"].should == "Message sent successfully"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "sends sms request with transaction id to platform" do
|
34
|
+
#given
|
35
|
+
Creatary.expects(:consumer_key).twice().returns(ConsumerKey)
|
36
|
+
Creatary.expects(:consumer_secret).twice().returns(ConsumerSecret)
|
37
|
+
Creatary.expects(:site).returns(Site)
|
38
|
+
Creatary.expects(:request_token_path).returns('/api/1/oauth/request_token')
|
39
|
+
Creatary.expects(:access_token_path).returns('/api/1/oauth/access_token')
|
40
|
+
Creatary.expects(:authorize_path).returns('/web/authorize')
|
41
|
+
Creatary.expects(:oauth_scheme).returns(:query_string)
|
42
|
+
Creatary.expects(:oauth_http_method).returns(:get)
|
43
|
+
http_stub = stub_request(:post, /.*\/api\/1\/sms\/send.*/).with { |request| assert_request(request, { :query => OAuthParams, :body => "{\"body\":\"test message\",\"from\":\"to_app\",\"transaction_id\":\"tran_id\"}"})}.to_return(:body => load_fixture("send_sms_success.json"))
|
44
|
+
|
45
|
+
#when
|
46
|
+
body = Creatary::API.send_sms("to_app", Creatary::User.new(AccessToken, AccessSecret), 'test message', 'tran_id')
|
47
|
+
|
48
|
+
#then
|
49
|
+
http_stub.should have_been_requested.times(1)
|
50
|
+
body["status"]["code"].should == 0
|
51
|
+
body["status"]["message"].should == "Message sent successfully"
|
52
|
+
end
|
53
|
+
|
54
|
+
def load_fixture(fixture)
|
55
|
+
IO.read("spec/fixtures/#{fixture}")
|
56
|
+
end
|
57
|
+
|
58
|
+
def assert_request(req, matchers)
|
59
|
+
return (assert_query(req.uri, matchers[:query]) and req.body == matchers[:body])
|
60
|
+
end
|
61
|
+
|
62
|
+
def assert_query(uri, params)
|
63
|
+
uri_params = uri.query_values
|
64
|
+
params.each do |key, value|
|
65
|
+
if not value.match(uri_params[key])
|
66
|
+
return false
|
67
|
+
end
|
68
|
+
end
|
69
|
+
return true
|
70
|
+
end
|
71
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start do
|
3
|
+
add_filter "/spec/"
|
4
|
+
end
|
5
|
+
|
6
|
+
module OAuthSettings
|
7
|
+
AccessToken = "token"
|
8
|
+
AccessSecret = "secret"
|
9
|
+
ConsumerKey = "consumer_key"
|
10
|
+
ConsumerSecret = "consumer_secret"
|
11
|
+
Site = "https://telcoassetmarketplace.com"
|
12
|
+
|
13
|
+
OAuthParams = {"oauth_consumer_key" => /^#{ConsumerKey}$/, "oauth_signature_method" => /^HMAC-SHA1$/, "oauth_nonce" => /.+/, "oauth_signature" => /.+/, "oauth_timestamp" => /^[0-9]+$/, "oauth_version" => /^1.0$/, "oauth_token" => /^#{AccessToken}$/}
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,177 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: creatary-sdk
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.3.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Carlos Manzanares
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-24 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: sinatra
|
16
|
+
requirement: &2161550180 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 1.2.1
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2161550180
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: json
|
27
|
+
requirement: &2161549680 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '1.5'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2161549680
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: oauth
|
38
|
+
requirement: &2161549220 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 0.4.3
|
44
|
+
type: :runtime
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2161549220
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rake
|
49
|
+
requirement: &2161548760 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - =
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.9.2
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2161548760
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: rspec
|
60
|
+
requirement: &2161548300 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - =
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: 1.3.2
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2161548300
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rack-test
|
71
|
+
requirement: &2161547840 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 0.6.1
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *2161547840
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: mocha
|
82
|
+
requirement: &2161547380 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.9.0
|
88
|
+
type: :development
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *2161547380
|
91
|
+
- !ruby/object:Gem::Dependency
|
92
|
+
name: webmock
|
93
|
+
requirement: &2161546920 !ruby/object:Gem::Requirement
|
94
|
+
none: false
|
95
|
+
requirements:
|
96
|
+
- - ~>
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: 1.7.0
|
99
|
+
type: :development
|
100
|
+
prerelease: false
|
101
|
+
version_requirements: *2161546920
|
102
|
+
- !ruby/object:Gem::Dependency
|
103
|
+
name: simplecov
|
104
|
+
requirement: &2161546460 !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.5.0
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: *2161546460
|
113
|
+
description: The Ruby gem for the Creatary REST APIs
|
114
|
+
email:
|
115
|
+
- developers@creatary.com
|
116
|
+
executables: []
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- .gitignore
|
121
|
+
- Gemfile
|
122
|
+
- LICENSE
|
123
|
+
- README.mkd
|
124
|
+
- Rakefile
|
125
|
+
- creatary-sdk.gemspec
|
126
|
+
- lib/creatary.rb
|
127
|
+
- lib/creatary/api.rb
|
128
|
+
- lib/creatary/api/charging.rb
|
129
|
+
- lib/creatary/api/location.rb
|
130
|
+
- lib/creatary/api/oauth.rb
|
131
|
+
- lib/creatary/api/sms.rb
|
132
|
+
- lib/creatary/configuration.rb
|
133
|
+
- lib/creatary/error.rb
|
134
|
+
- lib/creatary/railtie.rb
|
135
|
+
- lib/creatary/user.rb
|
136
|
+
- lib/creatary/version.rb
|
137
|
+
- spec/fixtures/getcoord_success.json
|
138
|
+
- spec/fixtures/send_sms_success.json
|
139
|
+
- spec/location_get_spec.rb
|
140
|
+
- spec/sms_receive_spec.rb
|
141
|
+
- spec/sms_send_spec.rb
|
142
|
+
- spec/spec_helper.rb
|
143
|
+
homepage: https://github.com/creatary/creatary-ruby-sdk
|
144
|
+
licenses: []
|
145
|
+
post_install_message: ! "********************************************************************************\n\n
|
146
|
+
\ Visit our community pages for up-to-date information on \n Creatary:\n https://creatary.com/\n
|
147
|
+
\ Notice that in order to use this gem you will also need to register as a \n developer
|
148
|
+
in Creatary:\n https://telcoassetmarketplace.com\n\n********************************************************************************
|
149
|
+
\ \n"
|
150
|
+
rdoc_options: []
|
151
|
+
require_paths:
|
152
|
+
- lib
|
153
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
154
|
+
none: false
|
155
|
+
requirements:
|
156
|
+
- - ! '>='
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
|
+
none: false
|
161
|
+
requirements:
|
162
|
+
- - ! '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: 1.3.6
|
165
|
+
requirements: []
|
166
|
+
rubyforge_project: creatary-sdk
|
167
|
+
rubygems_version: 1.8.15
|
168
|
+
signing_key:
|
169
|
+
specification_version: 3
|
170
|
+
summary: Creatary Ruby gem
|
171
|
+
test_files:
|
172
|
+
- spec/fixtures/getcoord_success.json
|
173
|
+
- spec/fixtures/send_sms_success.json
|
174
|
+
- spec/location_get_spec.rb
|
175
|
+
- spec/sms_receive_spec.rb
|
176
|
+
- spec/sms_send_spec.rb
|
177
|
+
- spec/spec_helper.rb
|