smess 1.0.0 → 1.0.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c788fb1adca56a19e9415362cdf44e74c8064e89
4
- data.tar.gz: 4778a898c0d307f1b7e45606e9942b9a81456a3e
3
+ metadata.gz: 0a1e283815e44722a3631efb29a2eaa38d0fa4eb
4
+ data.tar.gz: 1c48a4e6deb6695578794876979b2fb1d3bf928d
5
5
  SHA512:
6
- metadata.gz: 64dcc2a833300d0d55a55c38329bd7c5562556a4b1189c2e587380ab4a5d94af45a0ecb98e5080ae6d5f6ff72e85ae903cca7c63a324c32833fd615c182eda43
7
- data.tar.gz: 50ea00e53fda127b453cf3975dd936f9459025b1fe1f02fdfcc32566b9f81f8a0eeebbb48d89793e02496d8adb3e869e7a2761496ab47c1caf558ec9a90bc05c
6
+ metadata.gz: ffcaee4dd2e2e81dd04de3d50d9d3a915b84160d675fefd4fa7d127141e61a77b3f41dc662b3d5ecb95ef7bd31b968beed9965fdc1386b7f5059673e455e9d4e
7
+ data.tar.gz: 6dc69c352819f3e6061efae4b72b0f163cb860a760c5cba95024c030a65363d99d35792e5cb9984cdad90db47e1fe6b69ca2ead4fb039a832c76e66f1318c511
data/README.md CHANGED
@@ -1,3 +1,6 @@
1
+ [![Gem Version](https://badge.fury.io/rb/smess.png)](http://badge.fury.io/rb/smess)
2
+ [![Code Climate](https://codeclimate.com/repos/52249703f3ea003d03072821/badges/efe9fa39e239e1515d4e/gpa.png)](https://codeclimate.com/repos/52249703f3ea003d03072821/feed)
3
+
1
4
  # Smess - A mess of SMS messaging
2
5
 
3
6
  This is a messy SMS messenger supporting every aggregator I have gotten my hands on.
data/lib/smess.rb CHANGED
@@ -12,7 +12,6 @@ require 'smess/country_code_registry'
12
12
  require 'smess/utils'
13
13
  require 'smess/sms'
14
14
  require 'smess/outputs/auto'
15
- require 'smess/outputs/mm7'
16
15
  require 'smess/outputs/ipx'
17
16
  require 'smess/outputs/ipxus'
18
17
  require 'smess/outputs/clickatell'
@@ -5,74 +5,29 @@ module Smess
5
5
  class GlobalMouth
6
6
  include Smess::Logging
7
7
 
8
+ def deliver_sms(sms_arg)
9
+ return false unless sms_arg.kind_of? Sms
10
+ @sms = sms_arg
8
11
 
9
- def compute_hash(values = [])
10
- hash = "#{username}#{values.join}"
11
- auth_hash = Digest::MD5.hexdigest "#{username}:#{password}"
12
- Digest::MD5.hexdigest "#{hash}#{auth_hash}"
13
- end
14
-
15
-
16
- def deliver_sms(sms)
17
- return false unless sms.kind_of? Sms
18
-
19
- url = "https://mcm.globalmouth.com:8443/api/mcm"
20
- from = sms.originator || sender_id
21
- message_id = Digest::MD5.hexdigest "#{Time.now.strftime('%Y%m%d%H%M%S')}#{sms.to}-#{SecureRandom.hex(6)}"
22
-
23
- params = {
24
- username: username,
25
- msisdn: "+#{sms.to}",
26
- body: sms.message.strip_nongsm_chars.encode("ISO-8859-1"),
27
- originator: from,
28
- ref: message_id,
29
- dlr: "true"
30
- }
31
- params[:hash] = compute_hash(
32
- [sms.message.strip_nongsm_chars.encode("ISO-8859-1"), params[:originator], params[:msisdn]]
33
- )
34
- request = HTTPI::Request.new
12
+ generate_mac_hash
35
13
  request.url = "#{url}?#{params.to_query}"
36
14
 
37
15
  begin
38
16
  HTTPI.log_level = :debug
39
17
  response = HTTPI.get request
40
-
18
+ result = normal_result(response)
41
19
  rescue Exception => e
42
20
  logger.warn response
43
21
  # connection problem or some error
44
- result = {
45
- response_code: '-1',
46
- response: {
47
- temporaryError: 'true',
48
- responseCode: e.code,
49
- responseText: e.message
50
- },
51
- data: {
52
- to: sms.to,
53
- text: sms.message.strip_nongsm_chars,
54
- from: from
55
- }
56
- }
57
- else
58
- response_code = response.body.split(/\n/).first
59
- response_code = "0" if response_code == "200"
60
- # Successful response
61
- result = {
62
- message_id: message_id,
63
- response_code: response_code.to_s,
64
- response: {body: response.body},
65
- destination_address: sms.to,
66
- data: {
67
- to: sms.to,
68
- text: sms.message.strip_nongsm_chars,
69
- from: from
70
- }
71
- }
22
+ result = result_for_error(e)
72
23
  end
73
24
  result
74
25
  end
75
26
 
27
+ private
28
+
29
+ attr_reader :sms
30
+
76
31
  def username
77
32
  ENV["SMESS_GLOBAL_MOUTH_USER"].dup # paranoid safeguard
78
33
  end
@@ -83,5 +38,78 @@ module Smess
83
38
  ENV["SMESS_GLOBAL_MOUTH_SENDER_ID"]
84
39
  end
85
40
 
41
+ def url
42
+ "https://mcm.globalmouth.com:8443/api/mcm"
43
+ end
44
+
45
+ def from
46
+ sms.originator || sender_id
47
+ end
48
+
49
+ def message_id
50
+ @message_id ||= Digest::MD5.hexdigest "#{Time.now.strftime('%Y%m%d%H%M%S')}#{sms.to}-#{SecureRandom.hex(6)}"
51
+ end
52
+
53
+ def params
54
+ @params ||= {
55
+ username: username,
56
+ msisdn: "+#{sms.to}",
57
+ body: sms.message.strip_nongsm_chars.encode("ISO-8859-1"),
58
+ originator: from,
59
+ ref: message_id,
60
+ dlr: "true"
61
+ }
62
+ end
63
+
64
+ def compute_hash(values = [])
65
+ hash = "#{username}#{values.join}"
66
+ auth_hash = Digest::MD5.hexdigest "#{username}:#{password}"
67
+ Digest::MD5.hexdigest "#{hash}#{auth_hash}"
68
+ end
69
+
70
+ def generate_mac_hash
71
+ params[:hash] = compute_hash(
72
+ [sms.message.strip_nongsm_chars.encode("ISO-8859-1"), params[:originator], params[:msisdn]]
73
+ )
74
+ end
75
+
76
+ def request
77
+ @request ||= HTTPI::Request.new
78
+ end
79
+
80
+ def result_for_error(e)
81
+ code = e.code rescue "-1"
82
+ {
83
+ response_code: '-1',
84
+ response: {
85
+ temporaryError: 'true',
86
+ responseCode: e.code,
87
+ responseText: e.message
88
+ },
89
+ data: result_data
90
+ }
91
+ end
92
+
93
+ def normal_result(response)
94
+ response_code = response.body.split(/\n/).first
95
+ response_code = "0" if response_code == "200"
96
+ # Successful response
97
+ {
98
+ message_id: message_id,
99
+ response_code: response_code.to_s,
100
+ response: {body: response.body},
101
+ destination_address: sms.to,
102
+ data: result_data
103
+ }
104
+ end
105
+
106
+ def result_data
107
+ {
108
+ to: sms.to,
109
+ text: sms.message.strip_nongsm_chars,
110
+ from: from
111
+ }
112
+ end
113
+
86
114
  end
87
115
  end
@@ -1,33 +1,6 @@
1
1
  module Smess
2
2
  class Iconectiv < Ipxus
3
3
 
4
- def build_sms_payload
5
- # SOAP data
6
- @sms_options = {
7
- "correlationId" => Time.now.strftime('%Y%m%d%H%M%S') + @sms.to,
8
- "originatingAddress" => account[:shortcode],
9
- "originatorTON" => "0",
10
- "destinationAddress" => nil,
11
- "userData" => "",
12
- "userDataHeader" => "#NULL#",
13
- "DCS" => "-1",
14
- "PID" => "-1",
15
- "relativeValidityTime" => "-1",
16
- "deliveryTime" => "#NULL#",
17
- "statusReportFlags" => "1", # 1
18
- "accountName" => account[:account_name],
19
- "tariffClass" => "USD0",
20
- "VAT" => "-1",
21
- "referenceId" => "#NULL#",
22
- "serviceName" => account[:service_name],
23
- "serviceCategory" => "#NULL#",
24
- "serviceMetaData" => "#NULL#",
25
- "campaignName" => "#NULL#",
26
- "username" => account[:username],
27
- "password" => account[:password]
28
- }
29
- end
30
-
31
4
  def account
32
5
  @account ||= {
33
6
  sms_url: 'http://66.70.32.42:32005/api/services2/SmsApi52?wsdl',
@@ -36,7 +9,7 @@ module Smess
36
9
  password: ENV["SMESS_ICONECTIV_PASS"],
37
10
  account_name: ENV["SMESS_ICONECTIV_ACCOUNT_NAME"],
38
11
  service_name: ENV["SMESS_SERVICE_NAME"],
39
- service_meta_data_t_mobile: ENV["SMESS_ICONECTIV_SERVICE_META_DATA_T_MOBILE_US"],
12
+ service_meta_data_t_mobile_us: ENV["SMESS_ICONECTIV_SERVICE_META_DATA_T_MOBILE_US"],
40
13
  service_meta_data_verizon: ENV["SMESS_ICONECTIV_SERVICE_META_DATA_VERIZON"]
41
14
  }
42
15
  end
@@ -4,10 +4,9 @@ module Smess
4
4
 
5
5
  def initialize
6
6
  @endpoint = account[:sms_url]
7
-
8
7
  @credentials = {
9
- :name => account[:username],
10
- :pass => account[:password]
8
+ name: account[:username],
9
+ pass: account[:password]
11
10
  }
12
11
  end
13
12
 
@@ -22,13 +21,44 @@ module Smess
22
21
  }
23
22
  end
24
23
 
25
- def build_sms_payload
26
- # SOAP data
27
- @sms_options = {
28
- "correlationId" => Time.now.strftime('%Y%m%d%H%M%S') + @sms.to,
24
+ def deliver_sms(sms_arg)
25
+ return false unless sms_arg.kind_of? Sms
26
+ @sms = sms_arg
27
+
28
+ set_originator(sms.originator)
29
+
30
+ perform_operator_adaptation sms.to
31
+
32
+ results = []
33
+ parts.each_with_index do |part, i|
34
+ return false if part.empty?
35
+ # if we have several parts, send them as concatenated sms using UDH codes
36
+ soap_body["userDataHeader"] = concatenation_udh(i+1, parts.length) if parts.length > 1
37
+ soap_body["userData"] = part
38
+ soap_body["correlationId"] = Time.now.strftime('%Y%m%d%H%M%S') + sms.to + (i+1).to_s
39
+ results << send_one_sms
40
+
41
+ # halt and use fallback on error...
42
+ unless results.last[:response_code].to_s == "0"
43
+ logger.info "IPX_ERROR: #{results.last}"
44
+ return fallback_to_twilio || results.first
45
+ end
46
+ end
47
+
48
+ # we don't actually return the status for any of additional messages which is cheating
49
+ results.first
50
+ end
51
+
52
+ private
53
+
54
+ attr_reader :sms
55
+
56
+ def soap_body
57
+ @soap_body ||= {
58
+ "correlationId" => Time.now.strftime('%Y%m%d%H%M%S') + sms.to,
29
59
  "originatingAddress" => account[:shortcode],
30
60
  "originatorTON" => "0",
31
- "destinationAddress" => nil,
61
+ "destinationAddress" => sms.to,
32
62
  "userData" => "",
33
63
  "userDataHeader" => "#NULL#",
34
64
  "DCS" => "-1",
@@ -37,7 +67,7 @@ module Smess
37
67
  "deliveryTime" => "#NULL#",
38
68
  "statusReportFlags" => "1", # 1
39
69
  "accountName" => account[:account_name],
40
- "tariffClass" => "USD0",
70
+ "tariffClass" => "USD0", # needs to be extracted and variable per country
41
71
  "VAT" => "-1",
42
72
  "referenceId" => "#NULL#",
43
73
  "serviceName" => account[:service_name],
@@ -49,63 +79,6 @@ module Smess
49
79
  }
50
80
  end
51
81
 
52
- def deliver_sms(sms)
53
- return false unless sms.kind_of? Sms
54
-
55
- @sms = sms
56
- build_sms_payload
57
-
58
- set_originator sms.originator
59
- @sms_options["destinationAddress"] = sms.to
60
-
61
- perform_operator_adaptation sms.to
62
-
63
- # validate sms contents
64
- parts = Smess.split_sms(sms.message.strip_nongsm_chars)
65
- return false if parts[0].empty?
66
- # if we have several parts, send them as concatenated sms
67
- if parts.length > 1
68
- logger.info "Num Parts: #{parts.length.to_s}"
69
- # create concat-sms smpp header
70
- ref_id = Random.new.rand(255).to_s(16).rjust(2,"0")
71
- num_parts = parts.length
72
- @sms_options["userDataHeader"] = "050003#{ref_id}#{num_parts.to_s(16).rjust(2,'0')}01" # {050003}{ff}{02}{01} {concat-command}{id to link all parts}{total num parts}{num of current part}
73
- end
74
-
75
- @sms_options["userData"] = parts.shift
76
-
77
- result = send_one_sms
78
- result[:data] = @sms_options.dup
79
- result[:data].delete "password"
80
- result[:data]["userData"] = sms.message.strip_nongsm_chars
81
-
82
- # fallback...
83
- unless result[:response_code].to_s == "0"
84
- logger.info "IPX_ERROR: #{result}"
85
- return fallback_to_twilio
86
- end
87
-
88
- # send aditional parts if we have them
89
- if parts.length > 0 && result[:response_code] != "-1"
90
- logger.info "Sending more parts..."
91
- set_originator sms.originator
92
- @sms_options["destinationAddress"] = sms.to
93
-
94
- more_results = []
95
- parts.each_with_index do |part,i|
96
- logger.info "Sending Part #{(i+2).to_s}"
97
- @sms_options["userData"] = part
98
- @sms_options["userDataHeader"] = "050003#{ref_id}#{num_parts.to_s(16).rjust(2,'0')}#{(i+2).to_s(16).rjust(2,'0')}"
99
- @sms_options["correlationId"] = Time.now.strftime('%Y%m%d%H%M%S') + @sms.to + (i+1).to_s
100
- more_results << send_one_sms
101
- # we don't actually return the status for any of these which is cheating
102
- end
103
- end
104
-
105
- result
106
- end
107
-
108
- private
109
82
 
110
83
  def soap_client
111
84
  Savon.configure do |config|
@@ -113,7 +86,6 @@ module Smess
113
86
  config.raise_errors = false
114
87
  end
115
88
 
116
-
117
89
  endpoint = @endpoint
118
90
  mm7ns = wsdl_namespace
119
91
  credentials = @credentials
@@ -133,8 +105,8 @@ module Smess
133
105
  # and being able to reduce non-deliveries by more than half
134
106
  # is a big deal when sending transactional messages.
135
107
  def fallback_to_twilio
136
- @sms.output = :twilio
137
- @sms.deliver
108
+ sms.output = :twilio
109
+ sms.deliver
138
110
  end
139
111
 
140
112
  def get_response_hash_from(response)
@@ -146,8 +118,8 @@ module Smess
146
118
  end
147
119
 
148
120
  def set_originator(originator)
149
- @sms_options["originatingAddress"] = originator
150
- @sms_options["originatorTON"] = (originator.length == 5 && originator.to_i.to_s == originator) ? "0" : "1"
121
+ soap_body["originatingAddress"] = originator
122
+ soap_body["originatorTON"] = (originator.length == 5 && originator.to_i.to_s == originator) ? "0" : "1"
151
123
  end
152
124
 
153
125
  def xmlns
@@ -158,59 +130,83 @@ module Smess
158
130
  "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-2"
159
131
  end
160
132
 
133
+ def parts
134
+ @parts ||= split_parts
135
+ end
136
+
137
+ def split_parts
138
+ Smess.split_sms(sms.message.strip_nongsm_chars).reject {|s| s.empty? }
139
+ end
140
+
141
+ # {050003}{ff}{02}{01} {concat-command}{id to link all parts}{total num parts}{num of current part}
142
+ def concatenation_udh(num, total)
143
+ "050003#{ref_id}#{total.to_s(16).rjust(2,'0')}#{(num).to_s(16).rjust(2,'0')}"
144
+ end
145
+
146
+ def ref_id
147
+ @ref_id ||= Random.new.rand(255).to_s(16).rjust(2,"0")
148
+ end
149
+
161
150
  def send_one_sms
162
151
  client = soap_client
163
- sms_options = @sms_options
152
+ soap_body_var = soap_body
164
153
  begin
165
154
  response = client.request "SendRequest", "xmlns" => xmlns do
166
- soap.body = sms_options
155
+ soap.body = soap_body_var
167
156
  end
157
+ result = parse_sms_response(response)
168
158
  rescue Exception => e
169
- result = {
170
- :response_code => "-1",
171
- :response => {
172
- :temporaryError =>"true",
173
- :responseCode => "-1",
174
- :responseText => "MM: System Communication Error. #{e.inspect}"
175
- }
176
- }
159
+ result = result_for_error(e)
177
160
  # LOG error here?
178
- return result
179
161
  end
180
- return parse_sms_response response
162
+ result
181
163
  end
182
164
 
183
-
184
165
  def parse_sms_response(response)
185
- # logger.debug " --- "
186
- # logger.debug response.to_hash
187
- # logger.debug " --- "
188
166
  if response.http_error? || response.soap_fault?
189
- result = {
190
- :response_code => "-1",
191
- :response => {
192
- :temporaryError =>"true",
193
- :responseCode => "-1",
194
- :responseText => response.http_error || response.soap_fault.to_hash
195
- }
196
- }
197
- # LOG error here?
198
- return result
167
+ e = Struct.new(:code, :message).new("-1", response.http_error || response.soap_fault.to_hash)
168
+ result = result_for_error(e)
169
+ else
170
+ result = normal_result(response)
199
171
  end
172
+ result
173
+ end
200
174
 
175
+ def result_for_error(e)
176
+ code = e.code rescue "-1"
177
+ {
178
+ response_code: '-1',
179
+ response: {
180
+ temporaryError: 'true',
181
+ responseCode: code,
182
+ responseText: e.message
183
+ },
184
+ data: result_data
185
+ }
186
+ end
201
187
 
188
+ def normal_result(response)
202
189
  hash = response.to_hash[:send_response]
203
190
  message_id = ""
204
191
  message_id = hash[:message_id] if hash.has_key? :message_id
205
192
  response_code = hash[:response_code]
206
193
 
207
- result = {
208
- :message_id => message_id,
209
- :response_code => response_code,
210
- :response => hash
194
+ {
195
+ message_id: message_id,
196
+ response_code: response_code,
197
+ response: hash,
198
+ destination_address: sms.to,
199
+ data: result_data
211
200
  }
212
201
  end
213
202
 
203
+ def result_data
204
+ data = soap_body.dup
205
+ data.delete "password"
206
+ data["userData"] = sms.message.strip_nongsm_chars
207
+ data
208
+ end
209
+
214
210
 
215
211
  # Called before final message assembly
216
212
  # used to look up the operator and make changes to the SOAP data for some carriers
@@ -23,15 +23,10 @@ module Smess
23
23
  # Called before final message assembly
24
24
  # used to look up the operator and make changes to the MM7 for Verizon and T-mobile
25
25
  def perform_operator_adaptation(msisdn)
26
- if @mms && @mms.slides.empty?
27
- @mm7body["mm7:ServiceCode"] << ";contentMetaData=devicediscovery=true"
28
- return false
29
- else
30
- operator_data = lookup_operator msisdn
31
- unless operator_data[:operator].nil?
32
- method_name = "adapt_for_#{operator_data[:operator].to_underscore.gsub(" ","_")}"
33
- send(method_name,msisdn) if respond_to?(:"#{method_name}", true)
34
- end
26
+ operator_data = lookup_operator msisdn
27
+ unless operator_data[:operator].nil?
28
+ method_name = "adapt_for_#{operator_data[:operator].to_underscore.gsub(" ","_")}"
29
+ send(method_name, msisdn) if respond_to?(:"#{method_name}", true)
35
30
  end
36
31
  end
37
32
 
@@ -54,49 +49,33 @@ module Smess
54
49
  response = client.request "ResolveOperatorRequest", "xmlns"=>"http://www.ipx.com/api/services/consumerlookupapi09/types" do
55
50
  soap.body = body
56
51
  end
52
+ result = parse_operator_response(response)
57
53
  rescue Exception => e
58
- result = {
59
- :response_code => "-1",
60
- :response => {
61
- :temporaryError =>"true",
62
- :responseCode => "-1",
63
- :responseText => "MM: System Communication Error"
64
- }
65
- }
66
- # LOG error here?
54
+ result = result_for_error(e)
55
+ ensure
67
56
  @endpoint = orig_endpoint
68
57
  @credentials = orig_credentials
69
- return result
70
58
  end
71
- @endpoint = orig_endpoint
72
- @credentials = orig_credentials
73
- return parse_operator_response response
59
+ result
74
60
  end
75
61
 
76
62
  def parse_operator_response(response)
77
63
  if response.http_error? || response.soap_fault?
78
- result = {
79
- :response_code => "-1",
80
- :response => {
81
- :temporaryError =>"true",
82
- :responseCode => "-1",
83
- :responseText => response.http_error || response.soap_fault.to_hash
84
- }
85
- }
86
- # LOG error here?
87
- return result
64
+ e = Struct.new(:code, :message).new("-1", response.http_error || response.soap_fault.to_hash)
65
+ result = result_for_error(e)
66
+ else
67
+ result = response.to_hash[:resolve_operator_response]
88
68
  end
89
-
90
- hash = response.to_hash[:resolve_operator_response]
69
+ result
91
70
  end
92
71
 
93
72
 
94
73
  def adapt_for_verizon(msisdn)
95
- @sms_options["serviceMetaData"] = account[:service_meta_data_verizon]
74
+ soap_body["serviceMetaData"] = account[:service_meta_data_verizon]
96
75
  end
97
76
 
98
77
  def adapt_for_t_mobile_us(msisdn)
99
- @sms_options["serviceMetaData"] = account[:service_meta_data_t_mobile_us]
78
+ soap_body["serviceMetaData"] = account[:service_meta_data_t_mobile_us]
100
79
  end
101
80
 
102
81
  end
@@ -103,7 +103,7 @@ module Smess
103
103
 
104
104
  def hash_data_for(xml_params)
105
105
  rand = (SecureRandom.random_number*100000000).to_i
106
- @message_id = rand # "#{Time.now.to_i}#{xml_params.to}#{rand}"
106
+ @message_id = rand
107
107
 
108
108
  xml_hash = {
109
109
  notification_request: {
@@ -5,13 +5,39 @@ module Smess
5
5
  class Smsglobal
6
6
  include Smess::Logging
7
7
 
8
- def deliver_sms(sms)
9
- return false unless sms.kind_of? Sms
8
+ def deliver_sms(sms_arg)
9
+ return false unless sms_arg.kind_of? Sms
10
+ @sms = sms_arg
10
11
 
11
- url = "https://www.smsglobal.com/http-api.php"
12
- from = sms.originator || ENV["SMESS_SMSGLOBAL_SENDER_ID"]
12
+ request.url = url
13
+ request.body = params
14
+
15
+ begin
16
+ HTTPI.log_level = :debug
17
+ response = HTTPI.post request
18
+ result = normal_result(response)
19
+ rescue Exception => e
20
+ puts logger.warn response
21
+ # connection problem or some error
22
+ result = result_for_error(e)
23
+ end
24
+ result
25
+ end
26
+
27
+ private
13
28
 
14
- params = {
29
+ attr_reader :sms
30
+
31
+ def url
32
+ "https://www.smsglobal.com/http-api.php"
33
+ end
34
+
35
+ def from
36
+ sms.originator || ENV["SMESS_SMSGLOBAL_SENDER_ID"]
37
+ end
38
+
39
+ def params
40
+ @params ||= {
15
41
  action: "sendsms",
16
42
  user: ENV["SMESS_SMSGLOBAL_USER"],
17
43
  password: ENV["SMESS_SMSGLOBAL_PASS"],
@@ -20,50 +46,45 @@ module Smess
20
46
  text: sms.message.strip_nongsm_chars,
21
47
  maxsplit: "3"
22
48
  }
49
+ end
23
50
 
24
- request = HTTPI::Request.new
25
- request.url = url
26
- request.body = params
51
+ def request
52
+ @request ||= HTTPI::Request.new
53
+ end
27
54
 
28
- begin
29
- HTTPI.log_level = :debug
30
- response = HTTPI.post request
55
+ def result_for_error(e)
56
+ code = e.code rescue "-1"
57
+ {
58
+ response_code: '-1',
59
+ response: {
60
+ temporaryError: 'true',
61
+ responseCode: e.code,
62
+ responseText: e.message
63
+ },
64
+ data: result_data
65
+ }
66
+ end
31
67
 
32
- rescue Exception => e
33
- logger.warn response
34
- # connection problem or some error
35
- result = {
36
- response_code: '-1',
37
- response: {
38
- temporaryError: 'true',
39
- responseCode: e.code,
40
- responseText: e.message
41
- },
42
- data: {
43
- to: sms.to,
44
- text: sms.message.strip_nongsm_chars,
45
- from: from
46
- }
47
- }
48
- else
49
- first_response = response.body.split(/\r\n/).first.split(";")
50
- response_code = first_response.first.split(':').last.to_i
51
- message_id = first_response.last.split('SMSGlobalMsgID:').last
68
+ def normal_result(response)
69
+ first_response = response.body.split(/\r\n/).first.split(";")
70
+ response_code = first_response.first.split(':').last.to_i
71
+ message_id = first_response.last.split('SMSGlobalMsgID:').last
72
+ # Successful response
73
+ {
74
+ message_id: message_id,
75
+ response_code: response_code.to_s,
76
+ response: response.body,
77
+ destination_address: sms.to,
78
+ data: result_data
79
+ }
80
+ end
52
81
 
53
- # Successful response
54
- result = {
55
- message_id: message_id,
56
- response_code: response_code.to_s,
57
- response: response.body,
58
- destination_address: sms.to,
59
- data: {
60
- to: sms.to,
61
- text: sms.message.strip_nongsm_chars,
62
- from: from
63
- }
64
- }
65
- end
66
- result
82
+ def result_data
83
+ {
84
+ to: sms.to,
85
+ text: sms.message.strip_nongsm_chars,
86
+ from: from
87
+ }
67
88
  end
68
89
 
69
90
  end
data/lib/smess/utils.rb CHANGED
@@ -1,46 +1,8 @@
1
1
  # encoding: UTF-8
2
2
 
3
3
  module Smess
4
-
5
4
  class << self
6
5
 
7
- # cleans and forces the selected country prefix on the number given
8
- # if international is set a lighter cleaning is done to preserve any existing country code
9
- # this is not entirely problem-free for US area codes without leading 0.
10
- def clean_phone(num)
11
- num = num.to_s
12
-
13
- return nil if /\{[a-z]+:.+\}/.match(num)
14
-
15
- # make num all digits
16
- num = num.gsub(/\D/,"")
17
-
18
- if num.length > 0 && num[0..1] == "00"
19
- num = num[2..-1]
20
- elsif num.length > 0 && num[0] == "0"
21
- # cut away leading zeros
22
- num = num[1..-1] # while num[0] == "0"
23
- # Add country code unless the start of the number is the correct country code
24
- unless num[0..Smess.config.country_code.to_s.length-1] == Smess.config.country_code.to_s
25
- num = Smess.config.country_code.to_s + num
26
- end
27
- elsif !Smess.config.international
28
- # Add country code unless the start of the number is the correct country code
29
- unless num[0..Smess.config.country_code.to_s.length-1] == Smess.config.country_code.to_s
30
- num = Smess.config.country_code.to_s + num
31
- end
32
- end
33
-
34
- # number must be in a valid range
35
- unless (10..15) === num.length
36
- return nil
37
- end
38
-
39
- num
40
- end
41
-
42
-
43
-
44
6
  # returns an array of strings of gsm-compatible lengths
45
7
  # performance issue: utf8_safe_split also loops over the split point
46
8
  # this should be used when sending via concatenating providers
data/lib/smess/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Smess
2
- VERSION = '1.0.0'
2
+ VERSION = '1.0.1'
3
3
  end
data/lib/string.rb CHANGED
@@ -47,7 +47,7 @@ class String
47
47
  # Should this be a patch to String?
48
48
 
49
49
  # keeping them here in canse I need them
50
- #$basic_alpha = array(
50
+ # basic alpha
51
51
  # '@','£','$','¥','è','é','ù','ì','ò','Ç',"\n",'Ø','ø',"\r",'Å','å',
52
52
  # 'Δ','_','Φ','Γ','Λ','Ω','Π','Ψ','Σ','Θ','Ξ','Æ','æ','ß','É',' ',
53
53
  # '!','"','#','¤','%','&','\'','(',')','*','+',',','-','.','/','0',
@@ -56,9 +56,9 @@ class String
56
56
  # 'Q','R','S','T','U','V','W','X','Y','Z','Ä','Ö','Ñ','Ü','§','¿',
57
57
  # 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p',
58
58
  # 'q','r','s','t','u','v','w','x','y','z','ä','ö','ñ','ü','à'
59
- #);
60
- #$extended_alpha = array('|','^','€','{','}','[',']','~','\\');
61
- #$all_alpha = array_merge($basic_alpha, $extended_alpha);
59
+ #
60
+ # extended alpha
61
+ # '|','^','€','{','}','[',']','~','\\'
62
62
 
63
63
  allowed = '@£$¥èéùìòÇ'+"\n"+'Øø'+"\r"+'ÅåΔ_ΦΓΛΩΠΨΣΘΞÆæßÉ'+' '+Regexp.escape('!"#¤%&\'()*+,-.')+'\/'+Regexp.escape('0123456789:;<=>?¡ABCDEFGHIJKLMNOPQRSTUVWXYZÄÖÑܧ¿abcdefghijklmnopqrstuvwxyzäöñüà|^€{}[]~\\')
64
64
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: smess
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Westin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-02 00:00:00.000000000 Z
11
+ date: 2013-09-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -152,7 +152,6 @@ files:
152
152
  - lib/smess/outputs/ipx.rb
153
153
  - lib/smess/outputs/ipxus.rb
154
154
  - lib/smess/outputs/mblox.rb
155
- - lib/smess/outputs/mm7.rb
156
155
  - lib/smess/outputs/smsglobal.rb
157
156
  - lib/smess/outputs/test.rb
158
157
  - lib/smess/outputs/twilio.rb
@@ -166,7 +165,8 @@ files:
166
165
  - LICENSE
167
166
  - README.md
168
167
  homepage: https://github.com/eimermusic/smess
169
- licenses: []
168
+ licenses:
169
+ - MIT
170
170
  metadata: {}
171
171
  post_install_message:
172
172
  rdoc_options: []
@@ -1,122 +0,0 @@
1
- module Smess
2
-
3
- class Mm7
4
- include Smess::Logging
5
-
6
- def initialize
7
-
8
- # SOAP defaults
9
- @endpoint = "http://example.com/mms/mm7"
10
-
11
- # MM7 defaults
12
- @mm7ns = "http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-2"
13
- @mm7header = {
14
- "mm7:TransactionID" => Time.now.strftime('%Y%m%d%H%M%S'),
15
- :attributes! => {
16
- "mm7:TransactionID" => {
17
- "xmlns:mm7" => @mm7ns
18
- }
19
- }
20
- }
21
- @mm7body = {
22
- "mm7:MM7Version" => "6.5.0",
23
- "mm7:SenderIdentification" => {
24
- "mm7:VASPID" => "",
25
- "mm7:SenderAddress" => {}
26
- },
27
- "mm7:Recipients" => {
28
- "mm7:To" => {
29
- "mm7:Number" => ""
30
- }
31
- },
32
- "mm7:ServiceCode" => "",
33
- "mm7:LinkedID" => "",
34
- "mm7:DeliveryReport" => "true",
35
- "mm7:Subject" => "",
36
- "mm7:Content/" => nil,
37
- :attributes! => {"mm7:Content/" => {"href" => "cid:attachment_1"}}
38
- }
39
-
40
- @credentials = nil
41
-
42
- end
43
-
44
- private
45
-
46
- def perform_operator_adaptation(msisdn)
47
- # implement this method to do modify the message output
48
- end
49
-
50
- def soap_client
51
- Savon.configure do |config|
52
- config.log_level = :info
53
- config.raise_errors = false
54
- end
55
-
56
-
57
- endpoint = @endpoint
58
- mm7ns = @mm7ns
59
- credentials = @credentials
60
-
61
- client = Savon::Client.new do |wsdl, http|
62
- wsdl.endpoint = endpoint
63
- wsdl.namespace = mm7ns
64
-
65
- http.open_timeout = 15
66
- http.read_timeout = 60 # Won't set read timeout to 10 minutes!! (IPX are crazy)
67
- http.auth.basic credentials[:name], credentials[:pass] unless credentials.nil?
68
- end
69
- client
70
- end
71
-
72
- def get_response_hash_from(response)
73
- response.to_hash[:submit_rsp]
74
- end
75
-
76
- def get_message_id_from hash
77
- hash[:message_id] rescue ''
78
- end
79
-
80
- def parse_response(response)
81
- logger.debug ' --- '
82
- logger.debug response.http_error.to_hash
83
- logger.debug ' --- '
84
- # logger.debug response.success?
85
- # logger.debug ' --- '
86
- # logger.debug "#{response.http_error}, #{response.soap_fault }"
87
- # logger.debug ' --- '
88
-
89
- unless response.success?
90
- result = {
91
- :response_code => "-1",
92
- :response => {
93
- :responseCode => "-1",
94
- :responseText => response.http_error? ? response.http_error.to_hash : response.soap_fault.to_hash
95
- }
96
- }
97
-
98
- return result
99
- end
100
-
101
- hash = get_response_hash_from response
102
- message_id = get_message_id_from hash
103
-
104
- # any 1000 range code is a success, anything else is an error.
105
- status_code = hash[:status][:status_code] rescue '-1'
106
- if (1000..1999) === status_code.to_i
107
- response_code = "0"
108
- else
109
- response_code = status_code
110
- # LOG error here?
111
- end
112
-
113
- result = {
114
- :message_id => message_id,
115
- :response_code => response_code,
116
- :response => hash
117
- }
118
-
119
- end
120
-
121
- end
122
- end