messente-rails 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 54946d4694f6df2962df67f0e7fd47ff32dc6324
4
- data.tar.gz: 3d5608bc4a6b381c96127e3295ff2bda6a3c928e
3
+ metadata.gz: fed9eacb2651c18ac8daae4e11416c0aaf9c98e7
4
+ data.tar.gz: dfac98f867b01dbbb3d5e3062e8daa52a1588d04
5
5
  SHA512:
6
- metadata.gz: 6899f0992094856cc9d74b9d98b6d17c6aaf4bb5462cf35c53475b5e13389fc75d1c0b69d313f5736d2703b313ef6487ae51e45f8c783eade1149c7a36118da9
7
- data.tar.gz: e772cf556ddd73f7541fb1e970b981fac314d40564d3d61378f868cd45a1ff12b459618e8926c11ce8e720f9cd81c94676e52ae9bbe000d2ecc2c3e0e0689ff0
6
+ metadata.gz: f7350cb9f4f555aa09bdacf14bcd12c2c40da263098f9322d23fd0498a72a8fc94197d1444f62f6908ff7c768719fa976a6822f1f660bfa9b2e37f5269c2097e
7
+ data.tar.gz: 216b3364ee404080ea0e804e4cb2c03e97ce61297e2468ece2098b875a31f1c9591496f62a655a73383e7595213b0160433443e75f4b6e34ccedabab3fe2cd86
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ before_install:
3
+ - gem install bundler
4
+ rvm:
5
+ - 2.1.2
6
+ gemfile:
7
+ - Gemfile
8
+ notifications:
9
+ email: false
data/README.md CHANGED
@@ -1,9 +1,14 @@
1
- # Messente::Rails
2
-
3
- Messente.com API wrapper for Rails (non official)
1
+ # messente-rails
4
2
 
3
+ Non-official [Messente.com](https://messente.com) SMS gateway API wrapper for Rails.
5
4
  Original API documentation: [https://messente.com/docs/api/rest/](https://messente.com/docs/api/rest/)
6
5
 
6
+ [![Gem Version](https://badge.fury.io/rb/messente-rails.svg)](http://badge.fury.io/rb/messente-rails)
7
+ [![Build Status](https://travis-ci.org/Gedrovits/messente-rails.svg)](https://travis-ci.org/Gedrovits/messente-rails)
8
+ [![Dependency Status](https://gemnasium.com/Gedrovits/messente-rails.svg)](https://gemnasium.com/Gedrovits/messente-rails)
9
+ [![Code Climate](https://codeclimate.com/github/Gedrovits/messente-rails.png)](https://codeclimate.com/github/Gedrovits/messente-rails)
10
+ [![Inline docs](http://inch-ci.org/github/Gedrovits/messente-rails.png?branch=master)](http://inch-ci.org/github/Gedrovits/messente-rails)
11
+
7
12
  ## Installation
8
13
 
9
14
  Add this line to your application's Gemfile:
@@ -28,10 +33,28 @@ NB! Don't forget to restart server after configuration.
28
33
 
29
34
  ## Usage
30
35
 
31
- Methods from original documentation as is, but only synchronous sending is supported for now.
32
-
33
36
  Original API documentation: [https://messente.com/docs/api/rest/](https://messente.com/docs/api/rest/)
34
37
 
38
+ Idea was to leave original API names intact, so methods and parameters from API are same in gem.
39
+
40
+ So for example to send SMS with generated initializer it's simply as that:
41
+
42
+ $ messente = Messente.new
43
+ $ messente.send_sms(text: 'Message', to: '+000000000')
44
+
45
+ OR alternative way
46
+
47
+ $ Messente.send_sms(text: 'Message', to: '+000000000')
48
+
49
+ This way you can pass in required and optional parameters and use official documentation as manual.
50
+
51
+ $ Messente.prices(country: 'GB', format: 'xml')
52
+
53
+ NB! Be warned about non-ruby like attribute names and pass them as strings.
54
+ For now there is only one parameter like this 'dlr-url'. Please if you need it send it like that:
55
+
56
+ $ Messente.send_sms(text: 'Message', to: '+000000000', 'dlr-url' => 'http://example.com/callback')
57
+
35
58
  ## Contributing
36
59
 
37
60
  1. Fork it ( https://github.com/Gedrovits/messente-rails/fork )
@@ -1,8 +1,15 @@
1
1
  # You can configure messente-rails within this file
2
2
  MessenteRails.configure do |config|
3
3
  ## Messente.com API credentials
4
- #
5
- config.username = <% if ::Rails::VERSION::MAJOR == 4 %>Rails.application.secrets.messente_username<% else %>Rails.env.development? ? 'dev' : 'prod'<% end %>
6
- #
7
- config.password = <% if ::Rails::VERSION::MAJOR == 4 %>Rails.application.secrets.messente_password<% else %>Rails.env.development? ? 'dev' : 'prod'<% end %>
4
+ # API username
5
+ config.username = Rails.application.secrets.messente_username
6
+ # API password
7
+ config.password = Rails.application.secrets.messente_password
8
+
9
+ ## Options
10
+ # Return Messente.com stringified response as is without any special parsing
11
+ config.response_as_is = false
12
+ # Retry with backup Messente.com server on failed response
13
+ # This works only if :response_as_is === false
14
+ config.retry_on_fail = true
8
15
  end
@@ -13,5 +13,11 @@ module MessenteRails
13
13
  mattr_accessor :password
14
14
  @@password = nil
15
15
 
16
+ mattr_accessor :response_as_is
17
+ @@response_as_is = true
18
+
19
+ mattr_accessor :retry_on_fail
20
+ @@retry_on_fail = true
21
+
16
22
  end
17
23
  end
@@ -4,135 +4,136 @@ class Messente
4
4
  include HTTParty
5
5
  base_uri 'api2.messente.com'
6
6
 
7
+ SUPPORTED_METHODS = [:send_sms, :get_dlr_response, :cancel_sms, :get_balance, :prices, :pricelist]
8
+
7
9
  ERROR_101 = 'Access is restricted, wrong credentials. Check username and password values.'
8
10
  ERROR_102 = 'Parameters are wrong or missing. Check that all required parameters are present.'
9
11
  ERROR_103 = 'Invalid IP address. The IP address you made the request from, is not in the API settings whitelist.'
12
+ ERROR_104 = 'Country was not found.'
13
+ ERROR_105 = 'This country is not supported.'
14
+ ERROR_106 = 'Invalid format provided. Only json or xml is allowed.'
15
+ ERROR_107 = 'Could not find message with sms_unique_id.'
10
16
  ERROR_111 = 'Sender parameter "from" is invalid. You have not activated this sender name from Messente.com'
11
17
  FAILED_209 = 'Server failure, try again after a few seconds or try api3.messente.com backup server.'
12
18
 
13
- class << self
14
- # https://messente.com/docs/api/rest/sms/
15
- def send_sms(mobile, message, backup_uri = false)
16
- action = '/send_sms/'
17
- query = credentials.merge({ to: mobile, text: message })
18
- url = backup_uri ? self.backup_uri + action : action
19
-
20
- response = get(url, { query: query })
21
- return false unless ok? response
22
-
23
- case response.parsed_response
24
- when 'ERROR 101' then ERROR_101
25
- when 'ERROR 102' then ERROR_102
26
- when 'ERROR 103' then ERROR_103
27
- when 'ERROR 111' then ERROR_111
28
- when 'FAILED 209' then backup_uri ? false : send_sms(mobile, message, true)
29
- else
30
- # TODO: Should we save somewhere unique SMS ID?
31
- # unique_sms_id = response.parsed_response.split(' ').second
32
- true
33
- end
34
- end
35
-
36
- # https://messente.com/docs/api/rest/delivery-request/sync/
37
- def get_dlr_response(sms_unique_id, backup_uri = false)
38
- action = '/get_dlr_response/'
39
- query = credentials.merge({ sms_unique_id: sms_unique_id })
40
- url = backup_uri ? self.backup_uri + action : action
41
-
42
- response = get(url, { query: query })
43
- return false unless ok? response
19
+ attr_accessor :defaults, :credentials, :use_backup_uri, :current_params
20
+
21
+ def initialize(username = nil, password = nil)
22
+ self.defaults = {
23
+ response_as_is: MessenteRails::Configuration.response_as_is,
24
+ retry_on_fail: MessenteRails::Configuration.retry_on_fail
25
+ }
26
+ self.credentials = {
27
+ username: username || MessenteRails::Configuration.username,
28
+ password: password || MessenteRails::Configuration.password
29
+ }
30
+ end
44
31
 
45
- case response.parsed_response
46
- when 'ERROR 101' then ERROR_101
47
- when 'ERROR 102' then ERROR_102
48
- when 'FAILED 209' then backup_uri ? false : get_dlr_response(sms_unique_id, true)
49
- else response.parsed_response.split(' ').second.downcase
50
- end
51
- end
32
+ # https://messente.com/docs/api/rest/sms/
33
+ # :text, :to, :time_to_send, :from, 'dlr-url', :charset, :autoconvert, :udh
34
+ def send_sms(params)
35
+ self.current_params = params
36
+ response = send_request(params)
37
+ smart_response(response.parsed_response)
38
+ end
52
39
 
53
- # https://messente.com/docs/api/rest/cancel-sms/
54
- def cancel_sms(sms_unique_id, backup_uri = false)
55
- action = '/cancel_sms/'
56
- query = credentials.merge({ sms_unique_id: sms_unique_id })
57
- url = backup_uri ? self.backup_uri + action : action
40
+ # https://messente.com/docs/api/rest/delivery-request/sync/
41
+ # :sms_unique_id
42
+ def get_dlr_response(params)
43
+ self.current_params = params
44
+ response = send_request(params)
45
+ smart_response(response.parsed_response)
46
+ end
58
47
 
59
- response = get(url, { query: query })
60
- return false unless ok? response
48
+ # https://messente.com/docs/api/rest/cancel-sms/
49
+ # :sms_unique_id
50
+ def cancel_sms(params)
51
+ self.current_params = params
52
+ response = send_request(params)
53
+ smart_response(response.parsed_response)
54
+ end
61
55
 
62
- case response.parsed_response
63
- when 'ERROR 107' then 'Could not find message with sms_unique_id.'
64
- when 'FAILED 209' then backup_uri ? false : cancel_sms(sms_unique_id, true)
65
- else true
66
- end
67
- end
56
+ # https://messente.com/docs/api/rest/balance/
57
+ def get_balance
58
+ response = send_request
59
+ smart_response(response.parsed_response)
60
+ end
68
61
 
69
- # https://messente.com/docs/api/rest/balance/
70
- def get_balance(backup_uri = false)
71
- action = '/get_balance/'
72
- url = backup_uri ? self.backup_uri + action : action
62
+ # https://messente.com/docs/api/rest/prices/
63
+ # :country, :format
64
+ def prices(params)
65
+ self.current_params = params
66
+ response = send_request(params)
67
+ smart_response(response.parsed_response)
68
+ end
73
69
 
74
- response = get(url, { query: credentials })
75
- return false unless ok? response
70
+ # https://messente.com/docs/api/rest/full-pricelist/
71
+ def pricelist
72
+ response = send_request
73
+ smart_response(response.parsed_response)
74
+ end
76
75
 
77
- case response.parsed_response
78
- when 'ERROR 101' then ERROR_101
79
- when 'ERROR 102' then ERROR_102
80
- when 'FAILED 209' then backup_uri ? false : get_balance(true)
81
- else response.parsed_response.split(' ').second
82
- end
83
- end
76
+ # Methods below allows us to make all calls above as class methods
77
+ # DRY so we don't need to define all methods again with calling instance from inside
84
78
 
85
- # https://messente.com/docs/api/rest/prices/
86
- def prices(country, format = 'json', backup_uri = false)
87
- action = '/prices/'
88
- query = credentials.merge({ country: country, format: format })
89
- url = backup_uri ? self.backup_uri + action : action
90
-
91
- response = get(url, { query: query })
92
- return false unless ok? response
93
-
94
- case response.parsed_response
95
- when 'ERROR 101' then ERROR_101
96
- when 'ERROR 102' then ERROR_102
97
- when 'ERROR 103' then 'IP address not allowed.'
98
- when 'ERROR 104' then 'Country was not found.'
99
- when 'ERROR 105' then 'This country is not supported.'
100
- when 'ERROR 106' then 'Invalid format provided. Only json or xml is allowed.'
101
- when 'FAILED 209' then backup_uri ? false : prices(country, 'json', true)
102
- else response.parsed_response
103
- end
79
+ def self.method_missing(method_name, *arguments, &block)
80
+ if SUPPORTED_METHODS.include? method_name
81
+ self.new.send(method_name, *arguments, &block)
82
+ else
83
+ super
104
84
  end
85
+ end
105
86
 
106
- # https://messente.com/docs/api/rest/full-pricelist/
107
- def pricelist(backup_uri = false)
108
- action = '/pricelist/'
109
- url = backup_uri ? self.backup_uri + action : action
87
+ def self.respond_to_missing?(method_name, include_private = false)
88
+ SUPPORTED_METHODS.include? method_name || super
89
+ end
110
90
 
111
- response = get(url, { query: credentials })
112
- return false unless ok? response
91
+ private
92
+
93
+ def send_request(query = nil)
94
+ action = caller[0].split('`').pop.gsub('\'', '')
95
+ safe_query = query ? credentials.merge(query) : credentials
96
+ url = if use_backup_uri === true
97
+ self.use_backup_uri = false
98
+ "#{ self.class.base_uri.gsub('api2', 'api3') }/#{ action }/"
99
+ else
100
+ "/#{ action }/"
101
+ end
102
+ self.class.post(url, { query: safe_query })
103
+ end
113
104
 
114
- case response.parsed_response
115
- when 'ERROR 101' then ERROR_101
116
- when 'ERROR 102' then ERROR_102
117
- when 'ERROR 103' then 'IP address not allowed.'
118
- when 'FAILED 209' then backup_uri ? false : pricelist(true)
119
- else response.parsed_response
105
+ def smart_response(response)
106
+ if response_as_is?
107
+ response
108
+ else
109
+ case response.split(' ').first
110
+ when 'ERROR'
111
+ [false, human_readable_error(response)]
112
+ when 'FAILED'
113
+ if retry_on_fail? && use_backup_uri != false
114
+ self.use_backup_uri = true
115
+ method_name = caller[0].split('`').pop.gsub('\'', '').to_sym
116
+ current_params.blank? ? send(method_name) : send(method_name, current_params)
117
+ else
118
+ self.use_backup_uri = nil
119
+ end
120
+ [false, human_readable_error(response)]
121
+ else
122
+ [true, response]
120
123
  end
121
124
  end
125
+ end
122
126
 
123
- private
124
-
125
- def credentials
126
- { username: MessenteRails::Configuration.username,
127
- password: MessenteRails::Configuration.password }
128
- end
127
+ def human_readable_error(error)
128
+ safe_error = error.gsub(' ', '_')
129
+ self.class.const_defined?(safe_error) ? self.class.const_get(safe_error) : "#{error} not defined."
130
+ end
129
131
 
130
- def backup_uri
131
- base_uri.gsub('api2', 'api3')
132
- end
132
+ def response_as_is?
133
+ defaults && defaults[:response_as_is]
134
+ end
133
135
 
134
- def ok?(response)
135
- response.code == 200
136
- end
136
+ def retry_on_fail?
137
+ defaults && defaults[:retry_on_fail]
137
138
  end
138
139
  end
@@ -1,3 +1,3 @@
1
1
  module MessenteRails
2
- VERSION = '0.1.0'
2
+ VERSION = '0.2.0'
3
3
  end
@@ -6,6 +6,7 @@ require 'messente-rails/version'
6
6
  Gem::Specification.new do |spec|
7
7
  spec.name = 'messente-rails'
8
8
  spec.version = MessenteRails::VERSION
9
+ spec.platform = Gem::Platform::RUBY
9
10
  spec.authors = ['Vjatseslav Gedrovits']
10
11
  spec.email = ['vjatseslav.gedrovits@gmail.com']
11
12
  spec.summary = %q{Messente.com API wrapper for Rails}
@@ -22,5 +23,5 @@ Gem::Specification.new do |spec|
22
23
 
23
24
  spec.add_development_dependency 'bundler', '~> 1.6'
24
25
  spec.add_development_dependency 'rake'
25
- spec.add_development_dependency 'rails', '~> 4.1'
26
+ spec.add_development_dependency 'rails', '>= 4.1'
26
27
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: messente-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vjatseslav Gedrovits
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-13 00:00:00.000000000 Z
11
+ date: 2014-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httparty
@@ -56,14 +56,14 @@ dependencies:
56
56
  name: rails
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "~>"
59
+ - - ">="
60
60
  - !ruby/object:Gem::Version
61
61
  version: '4.1'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - "~>"
66
+ - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '4.1'
69
69
  description: Messente.com API wrapper for Rails
@@ -74,6 +74,7 @@ extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
76
  - ".gitignore"
77
+ - ".travis.yml"
77
78
  - Gemfile
78
79
  - LICENSE
79
80
  - README.md