bluevia 1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|