smess 1.0.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.
- checksums.yaml +7 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +87 -0
- data/LICENSE +20 -0
- data/README.md +114 -0
- data/lib/smess.rb +63 -0
- data/lib/smess/country_code_registry.rb +33 -0
- data/lib/smess/logging.rb +16 -0
- data/lib/smess/outputs/auto.rb +26 -0
- data/lib/smess/outputs/clickatell.rb +115 -0
- data/lib/smess/outputs/etisalatdemo.rb +61 -0
- data/lib/smess/outputs/global_mouth.rb +87 -0
- data/lib/smess/outputs/iconectiv.rb +48 -0
- data/lib/smess/outputs/ipx.rb +223 -0
- data/lib/smess/outputs/ipxus.rb +103 -0
- data/lib/smess/outputs/mblox.rb +155 -0
- data/lib/smess/outputs/mm7.rb +122 -0
- data/lib/smess/outputs/smsglobal.rb +70 -0
- data/lib/smess/outputs/test.rb +31 -0
- data/lib/smess/outputs/twilio.rb +69 -0
- data/lib/smess/sms.rb +25 -0
- data/lib/smess/utils.rb +91 -0
- data/lib/smess/version.rb +3 -0
- data/lib/string.rb +122 -0
- metadata +192 -0
@@ -0,0 +1,61 @@
|
|
1
|
+
module Smess
|
2
|
+
class Etisalatdemo
|
3
|
+
include Smess::Logging
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@smtp_settings = {
|
7
|
+
address: "exmail.emirates.net.ae",
|
8
|
+
port: 25,
|
9
|
+
domain: 'eim.ae',
|
10
|
+
user_name: ENV["SMESS_ETISALATDEMO_USER"],
|
11
|
+
password: ENV["SMESS_ETISALATDEMO_PASS"],
|
12
|
+
authentication: 'plain',
|
13
|
+
enable_starttls_auto: false
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
def deliver_sms(sms)
|
18
|
+
return false unless sms.kind_of? Sms
|
19
|
+
@sms = sms
|
20
|
+
|
21
|
+
local_from_var = from_address
|
22
|
+
mail = Mail.new do
|
23
|
+
from local_from_var
|
24
|
+
to "+#{sms.to}@email2sms.ae"
|
25
|
+
subject "Smess Message"
|
26
|
+
body sms.message.strip_nongsm_chars
|
27
|
+
end
|
28
|
+
|
29
|
+
mail.delivery_method :smtp, @smtp_settings
|
30
|
+
|
31
|
+
begin
|
32
|
+
mail.deliver
|
33
|
+
rescue Exception => e
|
34
|
+
result = {
|
35
|
+
response_code: "-1",
|
36
|
+
response: {text: "Email2sms: Delivery Error: #{e.inspect}"},
|
37
|
+
data: {
|
38
|
+
to: sms.to,
|
39
|
+
text: sms.message.strip_nongsm_chars,
|
40
|
+
from: from_address
|
41
|
+
}
|
42
|
+
}
|
43
|
+
else
|
44
|
+
result = {
|
45
|
+
response_code: "0",
|
46
|
+
response: {text: "Email2sms: Delivery Successful"},
|
47
|
+
data: {
|
48
|
+
to: sms.to,
|
49
|
+
text: sms.message.strip_nongsm_chars,
|
50
|
+
from: from_address
|
51
|
+
}
|
52
|
+
}
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def from_address
|
57
|
+
"#{@smtp_settings[:user_name]}@#{@smtp_settings[:domain]}"
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
require 'uri'
|
2
|
+
require 'httpi'
|
3
|
+
|
4
|
+
module Smess
|
5
|
+
class GlobalMouth
|
6
|
+
include Smess::Logging
|
7
|
+
|
8
|
+
|
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
|
35
|
+
request.url = "#{url}?#{params.to_query}"
|
36
|
+
|
37
|
+
begin
|
38
|
+
HTTPI.log_level = :debug
|
39
|
+
response = HTTPI.get request
|
40
|
+
|
41
|
+
rescue Exception => e
|
42
|
+
logger.warn response
|
43
|
+
# 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
|
+
}
|
72
|
+
end
|
73
|
+
result
|
74
|
+
end
|
75
|
+
|
76
|
+
def username
|
77
|
+
ENV["SMESS_GLOBAL_MOUTH_USER"].dup # paranoid safeguard
|
78
|
+
end
|
79
|
+
def password
|
80
|
+
ENV["SMESS_GLOBAL_MOUTH_PASS"]
|
81
|
+
end
|
82
|
+
def sender_id
|
83
|
+
ENV["SMESS_GLOBAL_MOUTH_SENDER_ID"]
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Smess
|
2
|
+
class Iconectiv < Ipxus
|
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
|
+
def account
|
32
|
+
@account ||= {
|
33
|
+
sms_url: 'http://66.70.32.42:32005/api/services2/SmsApi52?wsdl',
|
34
|
+
shortcode: ENV["SMESS_ICONECTIV_SHORTCODE"],
|
35
|
+
username: ENV["SMESS_ICONECTIV_USER"],
|
36
|
+
password: ENV["SMESS_ICONECTIV_PASS"],
|
37
|
+
account_name: ENV["SMESS_ICONECTIV_ACCOUNT_NAME"],
|
38
|
+
service_name: ENV["SMESS_SERVICE_NAME"],
|
39
|
+
service_meta_data_t_mobile: ENV["SMESS_ICONECTIV_SERVICE_META_DATA_T_MOBILE_US"],
|
40
|
+
service_meta_data_verizon: ENV["SMESS_ICONECTIV_SERVICE_META_DATA_VERIZON"]
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def fallback_to_twilio
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,223 @@
|
|
1
|
+
module Smess
|
2
|
+
class Ipx
|
3
|
+
include Smess::Logging
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
@endpoint = account[:sms_url]
|
7
|
+
|
8
|
+
@credentials = {
|
9
|
+
:name => account[:username],
|
10
|
+
:pass => account[:password]
|
11
|
+
}
|
12
|
+
end
|
13
|
+
|
14
|
+
def account
|
15
|
+
@account ||= {
|
16
|
+
sms_url: 'http://europe.ipx.com/api/services2/SmsApi52?wsdl',
|
17
|
+
shortcode: ENV["SMESS_IPX_SHORTCODE"],
|
18
|
+
username: ENV["SMESS_IPX_USER"],
|
19
|
+
password: ENV["SMESS_IPX_PASS"],
|
20
|
+
account_name: ENV["SMESS_IPX_ACCOUNT_NAME"],
|
21
|
+
service_name: ENV["SMESS_SERVICE_NAME"]
|
22
|
+
}
|
23
|
+
end
|
24
|
+
|
25
|
+
def build_sms_payload
|
26
|
+
# SOAP data
|
27
|
+
@sms_options = {
|
28
|
+
"correlationId" => Time.now.strftime('%Y%m%d%H%M%S') + @sms.to,
|
29
|
+
"originatingAddress" => account[:shortcode],
|
30
|
+
"originatorTON" => "0",
|
31
|
+
"destinationAddress" => nil,
|
32
|
+
"userData" => "",
|
33
|
+
"userDataHeader" => "#NULL#",
|
34
|
+
"DCS" => "-1",
|
35
|
+
"PID" => "-1",
|
36
|
+
"relativeValidityTime" => "-1",
|
37
|
+
"deliveryTime" => "#NULL#",
|
38
|
+
"statusReportFlags" => "1", # 1
|
39
|
+
"accountName" => account[:account_name],
|
40
|
+
"tariffClass" => "USD0",
|
41
|
+
"VAT" => "-1",
|
42
|
+
"referenceId" => "#NULL#",
|
43
|
+
"serviceName" => account[:service_name],
|
44
|
+
"serviceCategory" => "#NULL#",
|
45
|
+
"serviceMetaData" => "#NULL#",
|
46
|
+
"campaignName" => "#NULL#",
|
47
|
+
"username" => account[:username],
|
48
|
+
"password" => account[:password]
|
49
|
+
}
|
50
|
+
end
|
51
|
+
|
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
|
+
|
110
|
+
def soap_client
|
111
|
+
Savon.configure do |config|
|
112
|
+
config.log_level = :info
|
113
|
+
config.raise_errors = false
|
114
|
+
end
|
115
|
+
|
116
|
+
|
117
|
+
endpoint = @endpoint
|
118
|
+
mm7ns = wsdl_namespace
|
119
|
+
credentials = @credentials
|
120
|
+
|
121
|
+
client = Savon::Client.new do |wsdl, http|
|
122
|
+
wsdl.endpoint = endpoint
|
123
|
+
wsdl.namespace = mm7ns
|
124
|
+
|
125
|
+
http.open_timeout = 15
|
126
|
+
http.read_timeout = 60 # Won't set read timeout to 10 minutes!! (IPX are crazy)
|
127
|
+
http.auth.basic credentials[:name], credentials[:pass] unless credentials.nil?
|
128
|
+
end
|
129
|
+
client
|
130
|
+
end
|
131
|
+
|
132
|
+
# Delivery reliability, particularly in the US, is appalling
|
133
|
+
# and being able to reduce non-deliveries by more than half
|
134
|
+
# is a big deal when sending transactional messages.
|
135
|
+
def fallback_to_twilio
|
136
|
+
@sms.output = :twilio
|
137
|
+
@sms.deliver
|
138
|
+
end
|
139
|
+
|
140
|
+
def get_response_hash_from(response)
|
141
|
+
response.to_hash[:submit_rsp]
|
142
|
+
end
|
143
|
+
|
144
|
+
def get_message_id_from hash
|
145
|
+
hash[:message_id] rescue ''
|
146
|
+
end
|
147
|
+
|
148
|
+
def set_originator(originator)
|
149
|
+
@sms_options["originatingAddress"] = originator
|
150
|
+
@sms_options["originatorTON"] = (originator.length == 5 && originator.to_i.to_s == originator) ? "0" : "1"
|
151
|
+
end
|
152
|
+
|
153
|
+
def xmlns
|
154
|
+
"http://www.ipx.com/api/services/smsapi52/types"
|
155
|
+
end
|
156
|
+
|
157
|
+
def wsdl_namespace
|
158
|
+
"http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-2"
|
159
|
+
end
|
160
|
+
|
161
|
+
def send_one_sms
|
162
|
+
client = soap_client
|
163
|
+
sms_options = @sms_options
|
164
|
+
begin
|
165
|
+
response = client.request "SendRequest", "xmlns" => xmlns do
|
166
|
+
soap.body = sms_options
|
167
|
+
end
|
168
|
+
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
|
+
}
|
177
|
+
# LOG error here?
|
178
|
+
return result
|
179
|
+
end
|
180
|
+
return parse_sms_response response
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
def parse_sms_response(response)
|
185
|
+
# logger.debug " --- "
|
186
|
+
# logger.debug response.to_hash
|
187
|
+
# logger.debug " --- "
|
188
|
+
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
|
199
|
+
end
|
200
|
+
|
201
|
+
|
202
|
+
hash = response.to_hash[:send_response]
|
203
|
+
message_id = ""
|
204
|
+
message_id = hash[:message_id] if hash.has_key? :message_id
|
205
|
+
response_code = hash[:response_code]
|
206
|
+
|
207
|
+
result = {
|
208
|
+
:message_id => message_id,
|
209
|
+
:response_code => response_code,
|
210
|
+
:response => hash
|
211
|
+
}
|
212
|
+
end
|
213
|
+
|
214
|
+
|
215
|
+
# Called before final message assembly
|
216
|
+
# used to look up the operator and make changes to the SOAP data for some carriers
|
217
|
+
def perform_operator_adaptation(msisdn)
|
218
|
+
end
|
219
|
+
|
220
|
+
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
module Smess
|
2
|
+
class Ipxus < Ipx
|
3
|
+
|
4
|
+
def account
|
5
|
+
@account ||= {
|
6
|
+
sms_url: 'http://europe.ipx.com/api/services2/SmsApi52?wsdl',
|
7
|
+
shortcode: ENV["SMESS_IPX_SHORTCODE"],
|
8
|
+
username: ENV["SMESS_IPX_USER"],
|
9
|
+
password: ENV["SMESS_IPX_PASS"],
|
10
|
+
account_name: ENV["SMESS_IPX_ACCOUNT_NAME"],
|
11
|
+
service_name: ENV["SMESS_SERVICE_NAME"],
|
12
|
+
service_meta_data_t_mobile_us: ENV["SMESS_IPX_SERVICE_META_DATA_T_MOBILE_US"],
|
13
|
+
service_meta_data_verizon: ENV["SMESS_IPX_SERVICE_META_DATA_VERIZON"]
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def set_originator(originator)
|
20
|
+
# Cannot set custom originator in the US
|
21
|
+
end
|
22
|
+
|
23
|
+
# Called before final message assembly
|
24
|
+
# used to look up the operator and make changes to the MM7 for Verizon and T-mobile
|
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
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def lookup_operator(msisdn)
|
39
|
+
orig_endpoint = @endpoint
|
40
|
+
orig_credentials = @credentials
|
41
|
+
@endpoint = "http://europe.ipx.com/api/services/ConsumerLookupApi09"
|
42
|
+
@credentials = nil
|
43
|
+
client = soap_client
|
44
|
+
client.wsdl.namespace = "http://www.ipx.com/api/services/consumerlookupapi09/types"
|
45
|
+
body = {
|
46
|
+
"correlationId" => Time.now.strftime('%Y%m%d%H%M%S') + msisdn,
|
47
|
+
"consumerId" => msisdn,
|
48
|
+
"campaignName" => "#NULL#",
|
49
|
+
"username" => account[:username],
|
50
|
+
"password" => account[:password]
|
51
|
+
}
|
52
|
+
|
53
|
+
begin
|
54
|
+
response = client.request "ResolveOperatorRequest", "xmlns"=>"http://www.ipx.com/api/services/consumerlookupapi09/types" do
|
55
|
+
soap.body = body
|
56
|
+
end
|
57
|
+
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?
|
67
|
+
@endpoint = orig_endpoint
|
68
|
+
@credentials = orig_credentials
|
69
|
+
return result
|
70
|
+
end
|
71
|
+
@endpoint = orig_endpoint
|
72
|
+
@credentials = orig_credentials
|
73
|
+
return parse_operator_response response
|
74
|
+
end
|
75
|
+
|
76
|
+
def parse_operator_response(response)
|
77
|
+
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
|
88
|
+
end
|
89
|
+
|
90
|
+
hash = response.to_hash[:resolve_operator_response]
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
def adapt_for_verizon(msisdn)
|
95
|
+
@sms_options["serviceMetaData"] = account[:service_meta_data_verizon]
|
96
|
+
end
|
97
|
+
|
98
|
+
def adapt_for_t_mobile_us(msisdn)
|
99
|
+
@sms_options["serviceMetaData"] = account[:service_meta_data_t_mobile_us]
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
end
|