smshelper 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ lib/**/*.rb
2
+ bin/*
3
+ -
4
+ features/**/*.feature
5
+ LICENSE.txt
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,21 @@
1
+ source "http://rubygems.org"
2
+ # Add dependencies required to use your gem here.
3
+ # Example:
4
+ # gem "activesupport", ">= 2.3.5"
5
+
6
+ # Add dependencies to develop your gem here.
7
+ # Include everything needed to run rake, tests, features, etc.
8
+ gem 'api_smith'
9
+ gem 'savon'
10
+ gem 'log4r'
11
+ gem 'textmagic'
12
+ gem 'mediaburst'
13
+
14
+ group :development do
15
+ gem "pry"
16
+ gem "rspec"
17
+ gem "rdoc"
18
+ gem "bundler"
19
+ gem "jeweler"
20
+ gem "simplecov"
21
+ end
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2012 Voip Scout
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.rdoc ADDED
@@ -0,0 +1,70 @@
1
+ = smshelper
2
+ A small utility library to do SMS-MT
3
+
4
+ == Currently supported providers:
5
+
6
+ * www.bulksms.com
7
+ * www.webtext.com
8
+ * www.clickatell.com
9
+ * www.textmagic.com
10
+ * www.smstrade.eu
11
+ * www.esendex.com
12
+ * www.mediaburst.co.uk
13
+ * www.nexmo.com
14
+ == Features
15
+
16
+ * unicode support
17
+ * send message
18
+ * check balance
19
+ * check sent message status
20
+ == Installation
21
+
22
+ gem install smshelper
23
+ == Usage
24
+
25
+ config = Smshelper::Config.new(
26
+ :smswarehouse => {:uname => '', :passwd => ''},
27
+ :routomessaging => {:uname => '', :passwd => ''},
28
+ :webtext => {:uname => '', :passwd => ''},
29
+ :bulksms => {:uname => '', :passwd => ''},
30
+ :clickatell => {:api_key => '',:uname => '', :passwd => ''},
31
+ :textmagic => {:uname => '', :passwd => ''},
32
+ :smstrade => {:api_key => ''},
33
+ :esendex => {:uname => '', :passwd => '', :acc => ''},
34
+ :mediaburst => {:uname => '', :passwd => ''},
35
+ :nexmo => {:uname => '', :passwd => ''},
36
+ :detectlanguage_dot_com => '',
37
+ :alchemy_language => '')
38
+
39
+ service0 = Smshelper::Api::Bulksms.new config
40
+ service1 = Smshelper::Api::Webtext.new config
41
+ service2 = Smshelper::Api::Clickatell.new config
42
+ service3 = Smshelper::Api::Textmagic.new config
43
+ service4 = Smshelper::Api::Smstrade.new config, :route => 'gold' # or 'direct'
44
+ service5 = Smshelper::Api::Esendex.new config, 'com:validityperiod' => '1'
45
+ service6 = Smshelper::Api::MediaBurst.new config
46
+ service7 = Smshelper::Api::Nexmo.new config, :ttl => '60000'
47
+
48
+ message = Smshelper::Message.new(:recipient => '',
49
+ :text => "The balance on #{service.class.to_s} is #{service.get_balance}",
50
+ :sender => '',
51
+ :api => config)
52
+ serviceX.send_message message
53
+ == TODO:
54
+
55
+ * create rspec tests
56
+ * refactor spaghetti code
57
+ * add support for www.totext.net, www.my-cool-sms.com, sms.vianett.com, www.world-text.com, www.mpulse.eu, www.clicksms.co.uk, www.tellustalk.com, www.aql.com, www.tm4b.com, www.txtnation.com, www.smsextrapro.com, www.truesenses.com, www.traitel.com.au
58
+ == Contributing to smshelper
59
+
60
+ * Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
61
+ * Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
62
+ * Fork the project.
63
+ * Start a feature/bugfix branch.
64
+ * Commit and push until you are happy with your contribution.
65
+ * Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
66
+ * Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
67
+
68
+ == Copyright
69
+
70
+ Copyright (c) 2012 Voip Scout.
data/Rakefile ADDED
@@ -0,0 +1,49 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.setup(:default, :development)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+
14
+ require 'jeweler'
15
+ Jeweler::Tasks.new do |gem|
16
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
17
+ gem.name = "smshelper"
18
+ gem.homepage = "http://github.com/voipscout/smshelper"
19
+ gem.license = "MIT"
20
+ gem.summary = %Q{sms helper gem}
21
+ gem.description = %Q{works with esendex, textmagic, smstrade, bulksms, routomessaging, smswarehouse, mediaburst, clickatell, webtext}
22
+ gem.email = "voipscout@gmail.com"
23
+ gem.authors = ["Voip Scout"]
24
+ # dependencies defined in Gemfile
25
+ end
26
+ Jeweler::RubygemsDotOrgTasks.new
27
+
28
+ require 'rspec/core'
29
+ require 'rspec/core/rake_task'
30
+ RSpec::Core::RakeTask.new(:spec) do |spec|
31
+ spec.pattern = FileList['spec/**/*_spec.rb']
32
+ end
33
+
34
+ RSpec::Core::RakeTask.new(:rcov) do |spec|
35
+ spec.pattern = 'spec/**/*_spec.rb'
36
+ spec.rcov = true
37
+ end
38
+
39
+ task :default => :spec
40
+
41
+ require 'rdoc/task'
42
+ Rake::RDocTask.new do |rdoc|
43
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
44
+
45
+ rdoc.rdoc_dir = 'rdoc'
46
+ rdoc.title = "smshelper #{version}"
47
+ rdoc.rdoc_files.include('README*')
48
+ rdoc.rdoc_files.include('lib/**/*.rb')
49
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.3
@@ -0,0 +1,21 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Smshelper
3
+ module Api
4
+ class Base
5
+ include APISmith::Client
6
+ include Log4r
7
+
8
+ attr_reader :sent_message_ids, :sent_message_statuses
9
+ attr_accessor :extra_options
10
+ def initialize(*args)
11
+ @log = Logger.new "#{self.class.name}"
12
+ @log.outputters = Outputter.stdout
13
+ @log.level = DEBUG #ERROR
14
+
15
+ @sent_message_ids, @sent_message_statuses = Array.new, Hash.new
16
+ @response_code = ResponseCodes.instance
17
+ @extra_options = args.shift
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,50 @@
1
+ module Smshelper
2
+ module Api
3
+ class Bulksms < Base
4
+ base_uri 'http://bulksms.vsms.net:5567'
5
+
6
+ def initialize(*args)
7
+ config = args.shift
8
+ add_query_options! :username => config.bulksms[:uname], :password => config.bulksms[:passwd]
9
+ super
10
+ end
11
+
12
+ def send_message(message)
13
+ if message.utf_8
14
+ message.to_hex_be
15
+ q = {:dca => '16bit'}
16
+ else
17
+ q = {:allow_concat_text_sms => '1', :concat_text_sms_max_parts => '5'}
18
+ end
19
+
20
+ options = {
21
+ :msisdn => message.recipient,
22
+ :message => message.text,
23
+ :sender => message.sender}
24
+ options = options.merge(@extra_options) unless @extra_options.nil?
25
+ resp = (post 'eapi/submission/send_sms/2/2.0', :extra_query => options.merge(q)).split('|')
26
+ process_response_code(resp.first) ? (@sent_message_ids << resp.last.strip; resp.last.strip) : (raise ErrorDuringSend, @response_code.bulksms(resp.first))
27
+ end
28
+
29
+ def get_balance
30
+ {'Credits' => (post 'eapi/user/get_credits/1/1.1').split('|').last.chomp}
31
+ end
32
+
33
+ def get_status(message_id)
34
+ options = {:batch_id => message_id}
35
+ resp = (post 'eapi/status_reports/get_report/2/2.0', :extra_query => options)
36
+ @sent_message_statuses[message_id] = []
37
+ resp.split(/\n\n/).last.split(/\n/).each_with_index do |status, index|
38
+ status = status.split('|').last
39
+ @sent_message_statuses[message_id] << {"part #{index}" => @response_code.bulksms(status)}
40
+ end
41
+ {message_id => @sent_message_statuses[message_id]}
42
+ end
43
+
44
+ private
45
+ def process_response_code(code)
46
+ (code == '0') ? true : false
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,54 @@
1
+ module Smshelper
2
+ module Api
3
+ class Clickatell < Base
4
+ base_uri 'http://api.clickatell.com/http'
5
+
6
+ def initialize(*args)
7
+ config = args.shift
8
+ add_query_options! :api_id => config.clickatell[:api_key], :user => config.clickatell[:uname], :password => config.clickatell[:passwd]
9
+ super
10
+ end
11
+
12
+ def send_message(message)
13
+ if message.utf_8
14
+ message.to_hex_be
15
+ q = {:unicode => '1', :req_feat => '40'}
16
+ else
17
+ q = {:req_feat => '32'}
18
+ end
19
+
20
+ options = {
21
+ :to => message.recipient,
22
+ :text => message.text,
23
+ :from => message.sender,
24
+ :queue => '1',
25
+ :escalate => '1',
26
+ :validity => '1',
27
+ :concat => '3'}
28
+ options = options.merge(@extra_options) unless @extra_options.nil?
29
+ resp = (post 'sendmsg', :extra_query => options.merge(q)).split(':')
30
+ process_response_code(resp.first.strip) ? (@sent_message_ids << resp.last.strip; resp.last.strip) : (raise ErrorDuringSend, resp.last.strip)
31
+ end
32
+
33
+ def get_balance
34
+ {'Credits' => (post 'getbalance').split(':').last.strip}
35
+ end
36
+
37
+ def get_status(message_id)
38
+ resp = (post 'querymsg', :extra_query => {:apimsgid => message_id}).split(':')
39
+ @sent_message_statuses[message_id] = []
40
+ if process_response_code(resp.first.strip)
41
+ @sent_message_statuses[message_id] << {"Part 01" => @response_code.clickatell(resp.last.strip)}
42
+ {message_id => @sent_message_statuses[message_id]}
43
+ else
44
+ raise ErrorDuringSend, resp.last.strip
45
+ end
46
+ end
47
+
48
+ private
49
+ def process_response_code(code)
50
+ (code == 'ID') ? true : false
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,83 @@
1
+ module Smshelper
2
+ module Api
3
+ class Esendex < Base
4
+ INBOX_SERVICE_WSDL = 'https://www.esendex.com/secure/messenger/soap/InboxService.asmx?wsdl'
5
+ SEND_SERVICE_WSDL = 'https://www.esendex.com/secure/messenger/soap/SendService.asmx?wsdl'
6
+ ACCOUNT_SERVICE_WSDL = 'https://www.esendex.com/secure/messenger/soap/AccountService.asmx?wsdl'
7
+
8
+ attr_reader :inbox
9
+ def initialize(*args)
10
+ config = args.shift
11
+ @header = {
12
+ "com:Username" => config.esendex[:uname],
13
+ "com:Password" => config.esendex[:passwd],
14
+ "com:Account" => config.esendex[:acc]}
15
+
16
+ Savon.configure do |config|
17
+ config.raise_errors = true
18
+ config.log = false
19
+ config.log_level = :error
20
+ HTTPI.log = false
21
+ end
22
+ @inbox = Array.new
23
+ super
24
+ end
25
+
26
+ def send_message(message)
27
+ client = connect 'message'
28
+ message.utf_8 ? (message_kind = 'Unicode') : (message_kind = 'Text')
29
+ body = {
30
+ "com:recipient" => message.recipient,
31
+ "com:body" => message.text,
32
+ "com:type" => message_kind,
33
+ "com:originator" => message.sender}
34
+ body = body.merge(@extra_options) unless @extra_options.nil?
35
+
36
+ resp = client.request(:com, :send_message_full) {|soap| soap.header["com:MessengerHeader"] = @header; soap.body = body}
37
+ @sent_message_ids << resp.to_hash[:send_message_full_response][:send_message_full_result]
38
+ end
39
+
40
+ def get_inbox
41
+ client = connect 'inbox'
42
+ resp = client.request(:com, :get_messages) {|soap| soap.header["com:MessengerHeader"] = @header}
43
+ @inbox = resp[:get_messages_response][:get_messages_result][:message]
44
+ end
45
+
46
+ def get_balance
47
+ client = connect 'account'
48
+ resp = client.request(:com, :get_message_limit) {|soap| soap.header["com:MessengerHeader"] = @header}
49
+ {'Messages' => resp.to_hash[:get_message_limit_response][:get_message_limit_result].to_s}
50
+ end
51
+
52
+ def get_status(*message_id)
53
+ message_id.flatten!
54
+
55
+ client = connect 'message'
56
+ message_id.each do |id|
57
+ resp = client.request(:com, :get_message_status) {|soap| soap.header["com:MessengerHeader"] = @header; soap.body = {"com:id" => id.to_s}}
58
+ @sent_message_statuses[id] = resp.to_hash[:get_message_status_response][:get_message_status_result]
59
+ end
60
+ end
61
+
62
+ private
63
+ def connect(service)
64
+ case service
65
+ when 'message'
66
+ api SEND_SERVICE_WSDL
67
+ when 'account'
68
+ api ACCOUNT_SERVICE_WSDL
69
+ when 'inbox'
70
+ api INBOX_SERVICE_WSDL
71
+ end
72
+ end
73
+
74
+ def api(service)
75
+ client = Savon::Client.new(service)
76
+ #http://jira.codehaus.org/browse/JRUBY-5529 - jruby-openssl in --1.9 jruby mode
77
+ client.http.auth.ssl.verify_mode=(:none)
78
+ client
79
+ end
80
+
81
+ end #class Esendex
82
+ end #module Api
83
+ end #module Smshelper
@@ -0,0 +1,33 @@
1
+ module Smshelper
2
+ module Api
3
+ class MediaBurst < Base
4
+ def initialize(*args)
5
+ config = args.shift
6
+ @client = Mediaburst::API.new config.mediaburst[:uname], config.mediaburst[:passwd]
7
+ super
8
+ end
9
+ def send_message(message)
10
+ #TODO: rewrite Mediaburst::API.process_response to provide
11
+ #full response data, so that msg_id could be had in @sent_message_ids
12
+ message.utf_8 ? (q = {:msgtype => 'ucs2'}) : (q = {:msgtype => 'text'})
13
+ options = {:concat => '3', :from => message.sender}.merge(q)
14
+ options = options.merge(@extra_options) unless @extra_options.nil?
15
+ resp = @client.send_message message.recipient, message.text, options
16
+ process_response_code(resp.values.last.to_s) ? resp.to_s : (raise ErrorDuringSend, @response_code.mediaburst(resp.values.last.to_s))
17
+ end
18
+
19
+ def get_balance
20
+ {'Messages' => @client.get_credit}
21
+ end
22
+
23
+ def get_status(message_id)
24
+ raise NotImplementedError, "Sms status checks unsupported by #{self.class.name}"
25
+ end
26
+
27
+ private
28
+ def process_response_code(code)
29
+ (code == 'true') ? true : false
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,43 @@
1
+ module Smshelper
2
+ module Api
3
+ class Nexmo < Base
4
+ base_uri 'http://rest.nexmo.com'
5
+ headers 'Accept' => 'application/json'
6
+
7
+ def initialize(*args)
8
+ config = args.shift
9
+ @uname, @passwd = config.nexmo[:uname], config.nexmo[:passwd]
10
+ super
11
+ end
12
+
13
+ def send_message(message)
14
+ message.utf_8 ? (q = {:type => 'unicode'}) : (q = {:type => 'text'})
15
+
16
+ options = {
17
+ :username => @uname,
18
+ :password => @passwd,
19
+ :to => message.recipient,
20
+ :text => message.text,
21
+ :from => message.sender}
22
+ options = options.merge(@extra_options) unless @extra_options.nil?
23
+ options = options.merge(q)
24
+ resp = (post 'sms/json', :extra_query => options)
25
+ resp
26
+ # process_response_code(resp.first) ? (@sent_message_ids << resp.last.strip; resp.last.strip) : (raise ErrorDuringSend, @response_code.nexmo(resp.first))
27
+ end
28
+
29
+ def get_balance
30
+ {'EUR' => (get "account/get-balance/#{@uname}/#{@passwd}").values.last.to_s}
31
+ end
32
+
33
+ def get_status(message_id)
34
+ end
35
+
36
+ private
37
+ def process_response_code(code)
38
+ (code == '0') ? true : false
39
+ end
40
+
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,203 @@
1
+ # -*- coding: utf-8 -*-
2
+ module Smshelper
3
+ module Api
4
+ class ResponseCodes
5
+ include Singleton
6
+
7
+ BULKSMS = {
8
+ '0' => 'In progress',
9
+ '1' => 'Scheduled',
10
+ '10' => 'Delivered upstream',
11
+ '11' => 'Delivered to mobile',
12
+ '12' => 'Delivered upstream unacknowledged',
13
+ '22' => 'Internal fatal error',
14
+ '23' => 'Authentication failure',
15
+ '24' => 'Data validation failed',
16
+ '25' => 'You do not have sufficient credits',
17
+ '26' => 'Upstream credits not available',
18
+ '27' => 'You have exceeded your daily quota',
19
+ '28' => 'Upstream quota exceeded',
20
+ '29' => 'Message sending cancelled',
21
+ '31' => 'Unroutable',
22
+ '32' => 'Blocked',
23
+ '33' => 'Failed: censored',
24
+ '40' => 'Temporarily unavailable',
25
+ '50' => 'Delivery failed - generic failure',
26
+ '51' => 'Delivery to phone failed',
27
+ '52' => 'Delivery to network failed',
28
+ '53' => 'Message expired',
29
+ '54' => 'Failed on remote network',
30
+ '56' => 'Failed: remotely censored',
31
+ '57' => 'Failed due to fault on handset',
32
+ '60' => 'Transient upstream failure',
33
+ '61' => 'Upstream status update',
34
+ '62' => 'Upstream cancel failed',
35
+ '63' => 'Queued for retry after temporary failure delivering',
36
+ '64' => 'Queued for retry after temporary failure delivering, due to fault on handset',
37
+ '70' => 'Unknown upstream status',
38
+ '201' => 'Maximum batch size exceeded'}
39
+
40
+ WEBTEXT = {
41
+ '000' => 'Success. Message accepted for delivery',
42
+ '101' => 'Missing parameter: api_id',
43
+ '102' => 'Missing parameter: api_pwd',
44
+ '103' => 'Missing parameter: txt',
45
+ '104' => 'Missing parameter: dest',
46
+ '105' => 'Missing parameter: msgid',
47
+ '106' => 'Missing parameter: receipt_url',
48
+ '107' => 'Missing parameter: receipt_email',
49
+ '108' => 'Invalid value for parameter: hex',
50
+ '109' => 'Missing parameter: hex (unicode parameter has been presented, but no hex value)',
51
+ '110' => 'Missing parameter: si_txt',
52
+ '111' => 'Missing parameter: si_url',
53
+ '112' => 'Missing parameter: group_name',
54
+ '113' => 'Missing parameter: group_alias',
55
+ '114' => 'Missing parameter: contact_num',
56
+ '115' => 'Missing parameter: remove_num',
57
+ '199' => 'Insufficient Credit',
58
+ '201' => 'Authentication Failure',
59
+ '202' => 'IP Restriction – an attempt has been made to send from an unauthorised IP address',
60
+ '203' => 'Invalid value for parameter: dest',
61
+ '204' => 'Invalid value for parameter: api_pwd',
62
+ '205' => 'Invalid value for parameter: api_id',
63
+ '206' => 'Invalid value for parameter: delivery_time',
64
+ '207' => 'Invalid date specified for delivery_time',
65
+ '208' => 'Invalid value for parameter: delivery_delta',
66
+ '209' => 'Invalid value for parameter: receipt',
67
+ '210' => 'Invalid value for parameter: msgid',
68
+ '211' => 'Invalid value for parameter: tag',
69
+ '212' => 'Invalid value for parameter: si_txt',
70
+ '213' => 'Invalid value for parameter: si_url',
71
+ '214' => 'Invalid value for parameter: group_name',
72
+ '215' => 'Invalid value for parameter: group_alias',
73
+ '216' => 'Invalid value for parameter: contact_num',
74
+ '217' => 'Invalid value for parameter: remove_num',
75
+ '401' => 'Not a contact',
76
+ '402' => 'Invalid value for parameter: group_alias'}
77
+
78
+ CLICKATELL = {
79
+ '001' => 'Message unknown',
80
+ '002' => 'Message queued',
81
+ '003' => 'Delivered to gateway',
82
+ '004' => 'Received by recipient',
83
+ '005' => 'Error with message',
84
+ '006' => 'User cancelled message delivery',
85
+ '007' => 'Error delivering message',
86
+ '008' => 'OK',
87
+ '009' => 'Routing error',
88
+ '010' => 'Message expired',
89
+ '011' => 'Message queued for later delivery',
90
+ '012' => 'Out of credit',
91
+ '014' => 'Maximum MT limit exceeded'}
92
+
93
+ SMSTRADE = {
94
+ '10' => 'Receiver number not valid',
95
+ '20' => 'Sender number not valid',
96
+ '30' => 'Message text not valid',
97
+ '31' => 'Message type not valid',
98
+ '40' => 'SMS route not valid',
99
+ '50' => 'Identification failed',
100
+ '60' => 'Not enough balance in account',
101
+ '70' => 'Network does not support the route',
102
+ '71' => 'Feature is not possible by the route',
103
+ '80' => 'Handover to SMSC failed',
104
+ '100' => 'SMS has been sent successfully'}
105
+
106
+ MEDIABURST = {
107
+ '1' => 'Internal Error',
108
+ '2' => 'Invalid Username Or Password',
109
+ '3' => 'Insufficient Credits Available',
110
+ '4' => 'Authentication Failure',
111
+ '5' => 'Invalid MsgType',
112
+ '6' => "‘To’ Parameter Not Specified",
113
+ '7' => "‘Content’ Parameter Not Specified",
114
+ '8' => "‘MessageID’ Parameter Not specified",
115
+ '9' => "Unknown ‘MessageID’",
116
+ '10' => "Invalid ‘To’ Parameter",
117
+ '11' => "Invalid ‘From’ Parameter",
118
+ '12' => 'Max Message Parts Exceeded',
119
+ '13' => 'Cannot Route Message',
120
+ '14' => 'Message Expired',
121
+ '15' => 'No route defined for this number',
122
+ '16' => "‘URL’ parameter not set",
123
+ '17' => 'Invalid Source IP',
124
+ '18' => "‘UDH’ Parameter Not Specified",
125
+ '19' => "Invalid ‘ServType’ Parameter",
126
+ '20' => "Invalid ‘ExpiryTime’ Parameter",
127
+ '25' => 'Duplicate ClientId received',
128
+ '26' => 'Internal Error',
129
+ '27' => "Invalid ‘TimeStamp’ Parameter",
130
+ '28' => "Invalid ‘AbsExpiry’ Parameter",
131
+ '29' => "Invalid ‘DlrType’ Parameter",
132
+ '31' => "Invalid ‘Concat’ Parameter",
133
+ '32' => "Invalid ‘UniqueId’ Parameter",
134
+ '33' => "Invalid ‘ClientId’ Parameter",
135
+ '39' => "Invalid character in ‘Content’ parameter",
136
+ '40' => 'Invalid TextPayload',
137
+ '41' => 'Invalid HexPayload',
138
+ '42' => 'Invalid Base64Payload',
139
+ '43' => 'Missing content type',
140
+ '44' => 'Missing ID',
141
+ '45' => 'MMS Message too large',
142
+ '46' => 'Invalid Payload ID',
143
+ '47' => 'Duplicate Payload ID',
144
+ '48' => 'No payload on MMS',
145
+ '49' => "Duplicate ‘filename’ Attribute on Payload",
146
+ '50' => "‘ItemId’ Parameter Not Specified",
147
+ '51' => "Invalid ‘ItemId’ Parameter",
148
+ '52' => 'Unable to generate filename for Content-Type',
149
+ '53' => "Invalid ‘InvalidCharAction’ Parameter",
150
+ '54' => "Invalid ‘DlrEnroute’ Parameter",
151
+ '55' => "Invalid ‘Truncate’ Parameter",
152
+ '56' => "Invalid ‘Long’ Parameter",
153
+ '100' => 'Internal Error',
154
+ '101' => 'Internal Error',
155
+ '102' => 'Invalid XML',
156
+ '103' => 'XML Document does not validate',
157
+ '300' => 'Client ID too long',
158
+ '305' => 'Query throttling rate exceeded'}
159
+
160
+ NEXMO = {
161
+ '0' => 'Success',
162
+ '1' => 'Throttled',
163
+ '2' => 'Missing params',
164
+ '3' => 'Invalid params',
165
+ '4' => 'Invalid credentials',
166
+ '5' => 'Internal error',
167
+ '6' => 'Invalid message',
168
+ '7' => 'Number barred',
169
+ '8' => 'Partner account barred',
170
+ '9' => 'Partner quota exceeded',
171
+ '10' => 'Too many existing binds',
172
+ '11' => 'Account not enabled for REST',
173
+ '12' => 'Message too long',
174
+ '15' => 'Invalid sender address',
175
+ '16' => 'Invalid TTL'}
176
+
177
+ def webtext(code)
178
+ WEBTEXT[code]
179
+ end
180
+
181
+ def bulksms(code)
182
+ BULKSMS[code]
183
+ end
184
+
185
+ def clickatell(code)
186
+ CLICKATELL[code]
187
+ end
188
+
189
+ def smstrade(code)
190
+ SMSTRADE[code]
191
+ end
192
+
193
+ def mediaburst(code)
194
+ MEDIABURST[code]
195
+ end
196
+
197
+ def nexmo(code)
198
+ NEXMO[code]
199
+ end
200
+
201
+ end
202
+ end
203
+ end