bluevia 1.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/LICENSE.LGPLv3 +165 -0
- data/License_Bluevia.txt +22 -0
- data/README +172 -0
- data/lib/bluevia.rb +13 -0
- data/lib/bluevia/ad_response.rb +35 -0
- data/lib/bluevia/advertising.rb +108 -0
- data/lib/bluevia/base_client.rb +401 -0
- data/lib/bluevia/bluevia_client.rb +119 -0
- data/lib/bluevia/bluevia_logger.rb +30 -0
- data/lib/bluevia/directory.rb +81 -0
- data/lib/bluevia/errors.rb +13 -0
- data/lib/bluevia/errors/client_error.rb +6 -0
- data/lib/bluevia/errors/not_found_error.rb +5 -0
- data/lib/bluevia/errors/server_error.rb +6 -0
- data/lib/bluevia/ext/hash.rb +64 -0
- data/lib/bluevia/messaging.rb +96 -0
- data/lib/bluevia/oauth.rb +117 -0
- data/lib/bluevia/response.rb +48 -0
- data/lib/bluevia/schemas.rb +10 -0
- data/lib/bluevia/schemas/common_types.rb +166 -0
- data/lib/bluevia/schemas/directory_types.rb +491 -0
- data/lib/bluevia/schemas/sms_types.rb +256 -0
- data/lib/bluevia/sms.rb +91 -0
- data/lib/bluevia/utils.rb +110 -0
- data/lib/multipartable.rb +15 -0
- data/test/test_advertising.rb +67 -0
- data/test/test_config.rb +77 -0
- data/test/test_directory.rb +124 -0
- data/test/test_oauth.rb +72 -0
- data/test/test_sms.rb +112 -0
- data/test/test_sms_mo.rb +78 -0
- metadata +137 -0
@@ -0,0 +1,401 @@
|
|
1
|
+
#
|
2
|
+
# BlueVia is a global iniciative of Telefonica delivered by Movistar and O2.
|
3
|
+
# Please, check out www.bluevia.com and if you need more information
|
4
|
+
# contact us at mailto:support@bluevia.com
|
5
|
+
|
6
|
+
require 'net/http'
|
7
|
+
require 'net/https'
|
8
|
+
require 'uri'
|
9
|
+
require 'cgi'
|
10
|
+
require 'bluevia/utils'
|
11
|
+
require 'bluevia/response'
|
12
|
+
require 'bluevia/ext/hash'
|
13
|
+
require 'bluevia/utils'
|
14
|
+
require 'bluevia/errors'
|
15
|
+
require 'bluevia/bluevia_logger'
|
16
|
+
require 'oauth/client/helper'
|
17
|
+
|
18
|
+
module Bluevia
|
19
|
+
#
|
20
|
+
# Abstract class that wraps access to REST services
|
21
|
+
#
|
22
|
+
|
23
|
+
class BaseClient
|
24
|
+
include BlueviaLogger
|
25
|
+
|
26
|
+
attr_accessor :base_uri
|
27
|
+
|
28
|
+
#
|
29
|
+
# REST INTERFACE CONFIGURATION
|
30
|
+
#
|
31
|
+
|
32
|
+
# Base URI to invoke Bluevia API. Production environment
|
33
|
+
BASEURI = "https://api.bluevia.com"
|
34
|
+
|
35
|
+
# Base Path to invoke Bluevia API. Production environment
|
36
|
+
BASEPATH = "/services/REST"
|
37
|
+
|
38
|
+
# Default parameters required to invoke API
|
39
|
+
DEFAULT_PARAMS = {:version => "v1", :alt => "json"}
|
40
|
+
# Endpoint for commercial (either testing or commercial apps)
|
41
|
+
BASEPATH_COMMERCIAL = ""
|
42
|
+
# Endpoint for sandbox (either testing or commercial apps)
|
43
|
+
BASEPATH_SANDBOX = "_Sandbox"
|
44
|
+
|
45
|
+
# HTTP Proxy is SDK is being used behind a firewall
|
46
|
+
PROXY = nil #"localhost:8888" #, "nube.hi.inet:8080"
|
47
|
+
|
48
|
+
def BaseClient.create_rest_client(uri = nil)
|
49
|
+
@@base_uri = uri.nil? ? BASEURI : uri
|
50
|
+
@@uri = URI.parse(@@base_uri)
|
51
|
+
|
52
|
+
# Set proxy if required
|
53
|
+
unless PROXY.nil?
|
54
|
+
proxy = PROXY.split(":")
|
55
|
+
rest = Net::HTTP::Proxy(proxy[0], proxy[1]).new(@@uri.host, @@uri.port)
|
56
|
+
else
|
57
|
+
rest = Net::HTTP.new(@@uri.host, @@uri.port)
|
58
|
+
end
|
59
|
+
# Set HTTP connection with SSL if required
|
60
|
+
if @@uri.instance_of?(URI::HTTPS)
|
61
|
+
rest.use_ssl = true
|
62
|
+
end
|
63
|
+
rest.read_timeout=(5)
|
64
|
+
rest
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
#
|
69
|
+
# Creates basic HTTP client
|
70
|
+
#
|
71
|
+
def initialize(params = nil)
|
72
|
+
@@uri = URI.parse(BASEURI)
|
73
|
+
|
74
|
+
if params.nil?
|
75
|
+
@rest = BaseClient.create_rest_client
|
76
|
+
elsif params.instance_of?(Hash)
|
77
|
+
params.has_key?(:rest) and @rest = params[:rest]
|
78
|
+
params.has_key?(:logger) and logger = params[:logger]
|
79
|
+
else
|
80
|
+
@rest = params
|
81
|
+
end
|
82
|
+
|
83
|
+
logger.debug "Initialized baseClient for service: #{self.class.name}"
|
84
|
+
end
|
85
|
+
|
86
|
+
#
|
87
|
+
# set HTTP client
|
88
|
+
#
|
89
|
+
def set_http_client(rest)
|
90
|
+
@rest = rest
|
91
|
+
end
|
92
|
+
|
93
|
+
#
|
94
|
+
# set the valid timeout for the HTTP requests
|
95
|
+
#
|
96
|
+
def set_timeout(timeout = 5)
|
97
|
+
!timeout.nil? and @rest.read_timeout(timeout)
|
98
|
+
end
|
99
|
+
|
100
|
+
#
|
101
|
+
# Define an instance variable using the default Hash syntax
|
102
|
+
#
|
103
|
+
def []=(key, value)
|
104
|
+
self.instance_variable_set(:"@#{key}", value) unless key.nil?
|
105
|
+
end
|
106
|
+
|
107
|
+
#
|
108
|
+
# Creates a valid path by concat the path received
|
109
|
+
# with the path defined in BASEPATH
|
110
|
+
#
|
111
|
+
def set_path(_path = nil)
|
112
|
+
path = BASEPATH.clone
|
113
|
+
path << _path unless _path.nil?
|
114
|
+
end
|
115
|
+
|
116
|
+
#
|
117
|
+
# Include params in the URI being created to perform a REST call
|
118
|
+
#
|
119
|
+
def include_params(_path, _params)
|
120
|
+
"#{_path}?".
|
121
|
+
concat(
|
122
|
+
_params.collect{
|
123
|
+
|k,v|
|
124
|
+
"#{k}=#{CGI::escape(v.to_s)}"
|
125
|
+
}.reverse.join('&')) unless _params.nil?
|
126
|
+
end
|
127
|
+
|
128
|
+
# Each Bluevia API has a specific basepath. This method gets the specific
|
129
|
+
# service basepath and the path associated to the request (either test or
|
130
|
+
# commercial)
|
131
|
+
def get_basepath
|
132
|
+
begin
|
133
|
+
basepath = self.class.const_get("BASEPATH_API")
|
134
|
+
rescue NameError => e
|
135
|
+
logger.error "Unable to fetch basepath #{e}"
|
136
|
+
basepath = "/#{self.class.to_s.upcase}_"
|
137
|
+
end
|
138
|
+
|
139
|
+
if @commercial
|
140
|
+
path = BASEPATH_COMMERCIAL
|
141
|
+
else
|
142
|
+
path = BASEPATH_SANDBOX
|
143
|
+
end
|
144
|
+
"#{basepath}#{path}"
|
145
|
+
end
|
146
|
+
|
147
|
+
#
|
148
|
+
# Send an Http::Get to the server
|
149
|
+
#
|
150
|
+
def GET(_path = nil, params = nil, headers = nil, field = nil)
|
151
|
+
path = set_path(_path)
|
152
|
+
params = Hash.new if params.nil?
|
153
|
+
params.merge!(DEFAULT_PARAMS) { |key,oldval,newval| oldval }
|
154
|
+
|
155
|
+
path = include_params(path, params)
|
156
|
+
|
157
|
+
logger.debug "GET Request path: " << path
|
158
|
+
|
159
|
+
begin
|
160
|
+
resp = authorized_client.get(path, get_headers(headers))
|
161
|
+
rescue => e
|
162
|
+
logger.error e
|
163
|
+
end
|
164
|
+
return handle_response(create_response(resp), "body", field)
|
165
|
+
end
|
166
|
+
|
167
|
+
#
|
168
|
+
# Send an Http::Post to the server
|
169
|
+
#
|
170
|
+
def POST(_path = nil, body = nil, headers = nil, files = nil, return_header = nil)
|
171
|
+
|
172
|
+
if files.nil?
|
173
|
+
path = set_path(_path)
|
174
|
+
path = include_params(path, DEFAULT_PARAMS)
|
175
|
+
logger.debug "POST Request path: " << path
|
176
|
+
logger.debug "POST body: " << body
|
177
|
+
|
178
|
+
begin
|
179
|
+
resp = authorized_client.post(path, body, get_headers(headers, true))
|
180
|
+
rescue => e
|
181
|
+
logger.error e
|
182
|
+
end
|
183
|
+
return handle_response(create_response(resp), return_header.nil? ? nil : "headers", return_header)
|
184
|
+
else
|
185
|
+
return POST_MULTIPART(_path, body, headers, files)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
#
|
190
|
+
# Send an Http::Delete to the server
|
191
|
+
#
|
192
|
+
def DELETE(_path = nil, headers = nil)
|
193
|
+
path = set_path(_path)
|
194
|
+
path = include_params(path, DEFAULT_PARAMS)
|
195
|
+
|
196
|
+
logger.debug "DELETE Request path: " << path
|
197
|
+
|
198
|
+
resp = authorized_client.delete(path, get_headers(headers, false))
|
199
|
+
return handle_response(create_response(resp))
|
200
|
+
end
|
201
|
+
|
202
|
+
def authorized_client
|
203
|
+
@consumer ||= OAuth::Consumer.new(@consumer_key, @consumer_secret, :site => @@base_uri)
|
204
|
+
@access_token ||= OAuth::AccessToken.new(@consumer, @token, @token_secret)
|
205
|
+
@access_token
|
206
|
+
end
|
207
|
+
|
208
|
+
#
|
209
|
+
# Creates the basic header while creating an HTTP Request
|
210
|
+
#
|
211
|
+
def get_headers(_headers = nil, is_post = false)
|
212
|
+
|
213
|
+
headers = {
|
214
|
+
"Accept" => "application/json"
|
215
|
+
}
|
216
|
+
|
217
|
+
if is_post
|
218
|
+
headers["Content-Type"] = "application/json"
|
219
|
+
end
|
220
|
+
|
221
|
+
unless _headers.nil?
|
222
|
+
headers.merge!(_headers) { |key,oldval,newval| newval }
|
223
|
+
end
|
224
|
+
logger.debug "HEADERS: "
|
225
|
+
logger.debug headers
|
226
|
+
return headers
|
227
|
+
end
|
228
|
+
|
229
|
+
private
|
230
|
+
|
231
|
+
# Converts an HTTP response to an internal object
|
232
|
+
def create_response(http_response)
|
233
|
+
return nil if http_response.nil?
|
234
|
+
|
235
|
+
response = Response.new
|
236
|
+
response.code = http_response.code
|
237
|
+
response.message = http_response.message
|
238
|
+
|
239
|
+
# headers
|
240
|
+
response.headers = Hash.new
|
241
|
+
|
242
|
+
http_response.each_header {|key, value|
|
243
|
+
response.headers[key] = value
|
244
|
+
}
|
245
|
+
|
246
|
+
# body
|
247
|
+
begin
|
248
|
+
# Convert JSON
|
249
|
+
if response.headers["content-type"].to_s.start_with?("application/json")
|
250
|
+
unless http_response.body.nil? or http_response.body.empty?
|
251
|
+
response.body = JSON.parse(http_response.body)
|
252
|
+
else
|
253
|
+
response.body = ""
|
254
|
+
end
|
255
|
+
# Convert XML to Hash
|
256
|
+
elsif response.headers["content-type"].to_s.start_with?("application/xml")
|
257
|
+
begin
|
258
|
+
response.body = Hash.from_xml(http_response.body)
|
259
|
+
rescue => e
|
260
|
+
logger.error "Unable to decode response: #{e.to_s}"
|
261
|
+
raise ServerError, "Unable to decode XML response"
|
262
|
+
end
|
263
|
+
# Do nothing
|
264
|
+
else
|
265
|
+
response.body = http_response.body
|
266
|
+
end
|
267
|
+
rescue => e
|
268
|
+
logger.error "Error while converting response"
|
269
|
+
logger.error e
|
270
|
+
raise ServerError, "Error while processing the response"
|
271
|
+
end
|
272
|
+
logger.debug response.to_s
|
273
|
+
return response
|
274
|
+
end
|
275
|
+
|
276
|
+
#
|
277
|
+
# This method is in charge of verify the code retrieved from the server and
|
278
|
+
# handle it properly.
|
279
|
+
# In case of get a field, just this JSON filed is retrieved from the body response
|
280
|
+
#
|
281
|
+
# Examples:
|
282
|
+
#
|
283
|
+
# response.code = 200
|
284
|
+
# response.body = {"name": "foo", "surname": "bar", "age": 32, "address": "Nissim Aloni"}
|
285
|
+
#
|
286
|
+
# handle_response(response, {"name"}) => "foo"
|
287
|
+
# handle_response(response) => {"name": "foo", "surname": "bar", "age": 32, "address": "Nissim Aloni"}
|
288
|
+
# handle_response(response, {"age"}) => 32
|
289
|
+
#
|
290
|
+
def handle_response(response, field_name = nil, field_value = nil)
|
291
|
+
unless response.nil?
|
292
|
+
|
293
|
+
if !field_name.nil? && field_value.instance_of?(String)
|
294
|
+
field_value = [field_value]
|
295
|
+
end
|
296
|
+
|
297
|
+
# Valid response
|
298
|
+
if response.code =~ /20?/
|
299
|
+
unless field_name.nil?
|
300
|
+
response_field = response[field_name]
|
301
|
+
if field_value.nil?
|
302
|
+
return response_field
|
303
|
+
end
|
304
|
+
unless response_field.nil?
|
305
|
+
if response_field.instance_of?(Hash)
|
306
|
+
unless field_value.nil? || !field_value.instance_of?(Array)
|
307
|
+
field_value.each{ |key|
|
308
|
+
unless response_field.has_key?(key)
|
309
|
+
raise ClientError, "Unable to find the request data: #{key}"
|
310
|
+
end
|
311
|
+
response_field = response_field[key]
|
312
|
+
}
|
313
|
+
end
|
314
|
+
return response_field
|
315
|
+
end
|
316
|
+
else
|
317
|
+
return false
|
318
|
+
end
|
319
|
+
else
|
320
|
+
return response
|
321
|
+
end
|
322
|
+
# Not found
|
323
|
+
elsif response.code.eql?("404")
|
324
|
+
raise NotFoundError, "Unable to find the resource: #{response.message} - #{response.body}"
|
325
|
+
# 40?
|
326
|
+
elsif response.code =~ /40?/
|
327
|
+
raise ClientError, "Error #{response.code} received: #{response.message} - #{response.body}"
|
328
|
+
# Not implemented
|
329
|
+
elsif response.code =~ /501/
|
330
|
+
raise NotImplementedError, "Operation not implemented in server side #{response.message} - #{response.body}"
|
331
|
+
# Server Error
|
332
|
+
elsif response.code =~ /500/
|
333
|
+
raise ServerError, "Server error #{response.message} - #{response.body}"
|
334
|
+
end
|
335
|
+
else
|
336
|
+
raise ServerError, "Unable to connect with endpoint."
|
337
|
+
end
|
338
|
+
end
|
339
|
+
|
340
|
+
#
|
341
|
+
# Send an Http::Post::Multipart to the server
|
342
|
+
#
|
343
|
+
def POST_MULTIPART(_path = nil, body = nil, headers = nil, files = nil)
|
344
|
+
path = set_path(_path)
|
345
|
+
path = include_params(path, DEFAULT_PARAMS)
|
346
|
+
unless files.nil?
|
347
|
+
logger.debug "POST MULTIPART " << path
|
348
|
+
multipart_data = Hash.new
|
349
|
+
#prueba = Utils::Multipart.new
|
350
|
+
unless files.nil?
|
351
|
+
if files.instance_of?(String) or (files.instance_of?(Array) and files.length == 1)
|
352
|
+
if files.instance_of?(Array)
|
353
|
+
files = files[0]
|
354
|
+
end
|
355
|
+
multipart_data["attachments"] = UploadIO.new(files, Utils.get_file_mime_type(files))
|
356
|
+
elsif files.instance_of?(Array)
|
357
|
+
requestbody = String.new
|
358
|
+
mimeboundary = "ABC123Boundary"
|
359
|
+
files.each{|file|
|
360
|
+
requestbody << "\r\n"
|
361
|
+
requestbody << "--#{mimeboundary}\n"
|
362
|
+
requestbody << "\r\n"
|
363
|
+
requestbody << "Content-Disposition: attachment; fileName=\"text.txt\""
|
364
|
+
requestbody << "\r\n"
|
365
|
+
requestbody << "Content-Type: #{Utils.get_file_mime_type(file)}\n"
|
366
|
+
requestbody << "\r\n"
|
367
|
+
content = File.open(file, "rb")
|
368
|
+
requestbody << "#{content.read}\n"
|
369
|
+
}
|
370
|
+
requestbody << "--#{mimeboundary}--\n"
|
371
|
+
multipart_data["attachment"] = UploadIO.new(StringIO.new(requestbody), "multipart/mixed; boundary=#{mimeboundary}", "attachments")
|
372
|
+
elsif files.instance_of?(Hash) && files.has_key?(:text)
|
373
|
+
multipart_data["attachments"] = UploadIO.new(StringIO.new(files[:text]), "text/plain", "text")
|
374
|
+
else
|
375
|
+
logger.error "Not sure about how to send this object: #{files.class.name}"
|
376
|
+
end
|
377
|
+
end
|
378
|
+
multipart_data["message"] = UploadIO.new(StringIO.new(body), "application/json", "root-field")
|
379
|
+
logger.debug "MULTIPART POST message: #{body}"
|
380
|
+
req = Net::HTTP::Post::Multipart.new(
|
381
|
+
path,
|
382
|
+
multipart_data,
|
383
|
+
get_headers(headers, true)
|
384
|
+
)
|
385
|
+
|
386
|
+
# Set proxy if required
|
387
|
+
unless PROXY.nil?
|
388
|
+
proxy = PROXY.split(":")
|
389
|
+
rest = Net::HTTP::Proxy(proxy[0], proxy[1]).new(@@uri.host,@@uri.port)
|
390
|
+
else
|
391
|
+
rest = Net::HTTP.new(@@uri.host,@@uri.port)
|
392
|
+
end
|
393
|
+
res = rest.start do |http|
|
394
|
+
http.request(req)
|
395
|
+
end
|
396
|
+
|
397
|
+
return create_response(res)
|
398
|
+
end
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
#
|
2
|
+
# BlueVia is a global iniciative of Telefonica delivered by Movistar and O2.
|
3
|
+
# Please, check out www.bluevia.com and if you need more information
|
4
|
+
# contact us at mailto:support@bluevia.com
|
5
|
+
|
6
|
+
require 'rubygems'
|
7
|
+
require 'json'
|
8
|
+
require 'uri'
|
9
|
+
require 'net/http'
|
10
|
+
require 'bluevia/directory'
|
11
|
+
require 'bluevia/sms'
|
12
|
+
require 'bluevia/oauth'
|
13
|
+
require 'bluevia/advertising'
|
14
|
+
require 'bluevia/bluevia_logger'
|
15
|
+
|
16
|
+
module Bluevia
|
17
|
+
#
|
18
|
+
# This class is the main client to access Bluevia API.
|
19
|
+
# It defines a services factory that provides an isolated way to reach
|
20
|
+
# each API. Currently the following APIs are supported:
|
21
|
+
# * oAuth authentication
|
22
|
+
# * SMS
|
23
|
+
# * Advertising
|
24
|
+
# * Directory
|
25
|
+
#
|
26
|
+
# When creating a BlueviaClient instance, basic authentication parameters
|
27
|
+
# can be provided:
|
28
|
+
#
|
29
|
+
# require 'bluevia'
|
30
|
+
#
|
31
|
+
# bc = BlueviaClient.new(
|
32
|
+
# { :consumer_key => <YOUR_CONSUMER_KEY>,
|
33
|
+
# :consumer_secret => <YOUR_CONSUMER_SECRET>,
|
34
|
+
# :token => <OAUTH_TOKEN>,
|
35
|
+
# :token_secret => <OAUTH_TOKEN_SECRET>
|
36
|
+
# })
|
37
|
+
#
|
38
|
+
|
39
|
+
class BlueviaClient
|
40
|
+
include BlueviaLogger
|
41
|
+
|
42
|
+
# Constructor
|
43
|
+
def initialize(params = nil)
|
44
|
+
|
45
|
+
unless params.nil? || params[:uri].nil?
|
46
|
+
rest = BaseClient.create_rest_client(params[:uri])
|
47
|
+
else
|
48
|
+
rest = BaseClient.create_rest_client
|
49
|
+
end
|
50
|
+
|
51
|
+
@commercial = false
|
52
|
+
@consumer_key = nil
|
53
|
+
@consumer_secret = nil
|
54
|
+
|
55
|
+
unless params.nil?
|
56
|
+
%w(consumer_key consumer_secret token token_secret).each{ |param|
|
57
|
+
self.instance_variable_set(:"@#{param}", params[:"#{param}"]) unless params[:"#{param}"].nil?
|
58
|
+
}
|
59
|
+
end
|
60
|
+
|
61
|
+
@factory = ServicesFactory.new(rest)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Retrieves a specific service to call any related API
|
65
|
+
# i.e.
|
66
|
+
# sms = bc.get_service(:Sms)
|
67
|
+
def get_service(_service)
|
68
|
+
service = @factory.get(_service)
|
69
|
+
service[:consumer_key] = @consumer_key unless @consumer_key.nil?
|
70
|
+
service[:consumer_secret] = @consumer_secret unless @consumer_secret.nil?
|
71
|
+
service[:token] = @token unless @token.nil?
|
72
|
+
service[:token_secret] = @token_secret unless @token_secret.nil?
|
73
|
+
service[:commercial] = @commercial
|
74
|
+
return service
|
75
|
+
end
|
76
|
+
|
77
|
+
# Client will get access to commercial APIs
|
78
|
+
def set_commercial
|
79
|
+
@commercial = true
|
80
|
+
end
|
81
|
+
|
82
|
+
# Client will get access to sandbox APIs
|
83
|
+
def set_sandbox
|
84
|
+
@commercial = false
|
85
|
+
end
|
86
|
+
|
87
|
+
# {true|false} if commercial or sandbox client
|
88
|
+
def commercial?
|
89
|
+
return @commercial
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# This service factory wraps the initialization of a service
|
94
|
+
class ServicesFactory
|
95
|
+
include BlueviaLogger
|
96
|
+
def initialize(rest = nil)
|
97
|
+
@directory = Directory.new({:rest =>rest, :logger => logger})
|
98
|
+
@sms = Sms.new({:rest =>rest, :logger => logger})
|
99
|
+
@advertising = Advertising.new({:rest =>rest, :logger => logger})
|
100
|
+
@oauth = Oauth.new({:rest =>rest, :logger => logger})
|
101
|
+
end
|
102
|
+
|
103
|
+
def get(service)
|
104
|
+
case service.to_s.downcase
|
105
|
+
when "directory"
|
106
|
+
return @directory
|
107
|
+
when "sms"
|
108
|
+
return @sms
|
109
|
+
when "oauth"
|
110
|
+
return @oauth
|
111
|
+
when "advertising"
|
112
|
+
return @advertising
|
113
|
+
else
|
114
|
+
raise(SyntaxError, "Service not valid")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|