nexmo 4.8.0 → 5.0.0.pre1
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 +4 -4
- data/README.md +48 -42
- data/lib/nexmo.rb +20 -0
- data/lib/nexmo/account.rb +23 -0
- data/lib/nexmo/alerts.rb +25 -0
- data/lib/nexmo/applications.rb +25 -0
- data/lib/nexmo/call_dtmf.rb +15 -0
- data/lib/nexmo/call_stream.rb +19 -0
- data/lib/nexmo/call_talk.rb +19 -0
- data/lib/nexmo/calls.rb +68 -0
- data/lib/nexmo/client.rb +75 -324
- data/lib/nexmo/conversions.rb +15 -0
- data/lib/nexmo/entity.rb +53 -0
- data/lib/nexmo/files.rb +25 -0
- data/lib/nexmo/jwt.rb +2 -1
- data/lib/nexmo/keys.rb +31 -0
- data/lib/nexmo/messages.rb +23 -0
- data/lib/nexmo/namespace.rb +83 -0
- data/lib/nexmo/number_insight.rb +21 -0
- data/lib/nexmo/numbers.rb +33 -0
- data/lib/nexmo/pricing.rb +31 -0
- data/lib/nexmo/pricing_types.rb +17 -0
- data/lib/nexmo/signature.rb +9 -1
- data/lib/nexmo/sms.rb +17 -0
- data/lib/nexmo/user_agent.rb +13 -0
- data/lib/nexmo/verify.rb +31 -0
- data/lib/nexmo/version.rb +1 -1
- data/nexmo.gemspec +3 -11
- metadata +39 -23
- data/spec/nexmo/client_spec.rb +0 -651
- data/spec/nexmo/jwt_spec.rb +0 -53
- data/spec/nexmo/params_spec.rb +0 -18
- data/spec/nexmo/signature_spec.rb +0 -20
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nexmo
|
4
|
+
class CallStream < Namespace
|
5
|
+
def start(id, params)
|
6
|
+
request('/v1/calls/' + id + '/stream', params: params, type: Put)
|
7
|
+
end
|
8
|
+
|
9
|
+
def stop(id)
|
10
|
+
request('/v1/calls/' + id + '/stream', type: Delete)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def authorization_header?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nexmo
|
4
|
+
class CallTalk < Namespace
|
5
|
+
def start(id, params)
|
6
|
+
request('/v1/calls/' + id + '/talk', params: params, type: Put)
|
7
|
+
end
|
8
|
+
|
9
|
+
def stop(id)
|
10
|
+
request('/v1/calls/' + id + '/talk', type: Delete)
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def authorization_header?
|
16
|
+
true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/nexmo/calls.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nexmo
|
4
|
+
class Calls < Namespace
|
5
|
+
def create(params)
|
6
|
+
request('/v1/calls', params: params, type: Post)
|
7
|
+
end
|
8
|
+
|
9
|
+
def list(params = nil)
|
10
|
+
request('/v1/calls', params: params)
|
11
|
+
end
|
12
|
+
|
13
|
+
def get(id)
|
14
|
+
request('/v1/calls/' + id)
|
15
|
+
end
|
16
|
+
|
17
|
+
def update(id, params)
|
18
|
+
request('/v1/calls/' + id, params: params, type: Put)
|
19
|
+
end
|
20
|
+
|
21
|
+
def hangup(id)
|
22
|
+
update(id, action: 'hangup')
|
23
|
+
end
|
24
|
+
|
25
|
+
def mute(id)
|
26
|
+
update(id, action: 'mute')
|
27
|
+
end
|
28
|
+
|
29
|
+
def unmute(id)
|
30
|
+
update(id, action: 'unmute')
|
31
|
+
end
|
32
|
+
|
33
|
+
def earmuff(id)
|
34
|
+
update(id, action: 'earmuff')
|
35
|
+
end
|
36
|
+
|
37
|
+
def unearmuff(id)
|
38
|
+
update(id, action: 'unearmuff')
|
39
|
+
end
|
40
|
+
|
41
|
+
def transfer(id, destination: nil)
|
42
|
+
# Ruby 2.0.0 does not support the syntax for required keyword arguments
|
43
|
+
# that was introduced in Ruby 2.1. The following line and the nil default
|
44
|
+
# can be removed when dropping support for Ruby 2.0.0.
|
45
|
+
raise ArgumentError, 'missing keyword: destination' if destination.nil?
|
46
|
+
|
47
|
+
update(id, action: 'transfer', destination: destination)
|
48
|
+
end
|
49
|
+
|
50
|
+
def stream
|
51
|
+
@stream ||= CallStream.new(@client)
|
52
|
+
end
|
53
|
+
|
54
|
+
def talk
|
55
|
+
@talk ||= CallTalk.new(@client)
|
56
|
+
end
|
57
|
+
|
58
|
+
def dtmf
|
59
|
+
@dtmf ||= CallDTMF.new(@client)
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def authorization_header?
|
65
|
+
true
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/nexmo/client.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
-
|
2
|
-
require 'json'
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
3
|
module Nexmo
|
5
4
|
class Client
|
6
|
-
attr_accessor :
|
5
|
+
attr_accessor :auth_token, :user_agent
|
7
6
|
|
8
7
|
def initialize(options = {})
|
9
|
-
@
|
8
|
+
@api_key = options[:api_key] || ENV['NEXMO_API_KEY']
|
10
9
|
|
11
|
-
@
|
10
|
+
@api_secret = options[:api_secret] || ENV['NEXMO_API_SECRET']
|
12
11
|
|
13
|
-
@signature_secret = options
|
12
|
+
@signature_secret = options[:signature_secret] || ENV['NEXMO_SIGNATURE_SECRET']
|
14
13
|
|
15
14
|
@application_id = options[:application_id]
|
16
15
|
|
@@ -20,368 +19,120 @@ module Nexmo
|
|
20
19
|
|
21
20
|
@api_host = options.fetch(:api_host) { 'api.nexmo.com' }
|
22
21
|
|
23
|
-
@user_agent =
|
24
|
-
|
25
|
-
if options.key?(:app_name) && options.key?(:app_version)
|
26
|
-
@user_agent << " #{options[:app_name]}/#{options[:app_version]}"
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def send_message(params)
|
31
|
-
post(@host, '/sms/json', params)
|
32
|
-
end
|
33
|
-
|
34
|
-
def track_message_conversion(message_id, params = {})
|
35
|
-
post(@api_host, '/conversions/sms', {'message-id' => message_id}.merge(params))
|
36
|
-
end
|
37
|
-
|
38
|
-
def track_voice_conversion(message_id, params = {})
|
39
|
-
post(@api_host, '/conversions/voice', {'message-id' => message_id}.merge(params))
|
40
|
-
end
|
41
|
-
|
42
|
-
def get_balance
|
43
|
-
get(@host, '/account/get-balance')
|
44
|
-
end
|
45
|
-
|
46
|
-
def get_country_pricing(country_code)
|
47
|
-
get(@host, '/account/get-pricing/outbound', country: country_code)
|
48
|
-
end
|
49
|
-
|
50
|
-
def get_prefix_pricing(prefix)
|
51
|
-
get(@host, '/account/get-prefix-pricing/outbound', prefix: prefix)
|
52
|
-
end
|
53
|
-
|
54
|
-
def get_sms_pricing(number)
|
55
|
-
get(@host, '/account/get-phone-pricing/outbound/sms', phone: number)
|
56
|
-
end
|
57
|
-
|
58
|
-
def get_voice_pricing(number)
|
59
|
-
get(@host, '/account/get-phone-pricing/outbound/voice', phone: number)
|
60
|
-
end
|
61
|
-
|
62
|
-
def update_settings(params)
|
63
|
-
post(@host, '/account/settings', params)
|
64
|
-
end
|
65
|
-
|
66
|
-
def topup(params)
|
67
|
-
post(@host, '/account/top-up', params)
|
68
|
-
end
|
69
|
-
|
70
|
-
def get_account_numbers(params)
|
71
|
-
get(@host, '/account/numbers', params)
|
72
|
-
end
|
73
|
-
|
74
|
-
def get_available_numbers(country_code, params = {})
|
75
|
-
get(@host, '/number/search', {country: country_code}.merge(params))
|
76
|
-
end
|
77
|
-
|
78
|
-
def buy_number(params)
|
79
|
-
post(@host, '/number/buy', params)
|
80
|
-
end
|
81
|
-
|
82
|
-
def cancel_number(params)
|
83
|
-
post(@host, '/number/cancel', params)
|
84
|
-
end
|
85
|
-
|
86
|
-
def update_number(params)
|
87
|
-
post(@host, '/number/update', params)
|
88
|
-
end
|
89
|
-
|
90
|
-
def get_message(id)
|
91
|
-
get(@host, '/search/message', id: id)
|
92
|
-
end
|
93
|
-
|
94
|
-
def get_message_rejections(params)
|
95
|
-
get(@host, '/search/rejections', params)
|
96
|
-
end
|
97
|
-
|
98
|
-
def search_messages(params)
|
99
|
-
get(@host, '/search/messages', Hash === params ? params : {ids: Array(params)})
|
100
|
-
end
|
101
|
-
|
102
|
-
def send_2fa_message(params)
|
103
|
-
post(@host, '/sc/us/2fa/json', params)
|
104
|
-
end
|
105
|
-
|
106
|
-
def send_event_alert_message(params)
|
107
|
-
post(@host, '/sc/us/alert/json', params)
|
108
|
-
end
|
109
|
-
|
110
|
-
def send_marketing_message(params)
|
111
|
-
post(@host, '/sc/us/marketing/json', params)
|
22
|
+
@user_agent = UserAgent.string(options[:app_name], options[:app_version])
|
112
23
|
end
|
113
24
|
|
114
|
-
def
|
115
|
-
|
116
|
-
end
|
117
|
-
|
118
|
-
def resubscribe_event_alert_number(params)
|
119
|
-
post(@host, '/sc/us/alert/opt-in/manage/json', params)
|
120
|
-
end
|
121
|
-
|
122
|
-
def initiate_call(params)
|
123
|
-
Kernel.warn "#{self.class}##{__method__} is deprecated (use the Voice API instead)."
|
124
|
-
|
125
|
-
post(@host, '/call/json', params)
|
126
|
-
end
|
127
|
-
|
128
|
-
def initiate_tts_call(params)
|
129
|
-
Kernel.warn "#{self.class}##{__method__} is deprecated (use the Voice API instead)."
|
130
|
-
|
131
|
-
post(@api_host, '/tts/json', params)
|
132
|
-
end
|
133
|
-
|
134
|
-
def initiate_tts_prompt_call(params)
|
135
|
-
Kernel.warn "#{self.class}##{__method__} is deprecated (use the Voice API instead)."
|
136
|
-
|
137
|
-
post(@api_host, '/tts-prompt/json', params)
|
138
|
-
end
|
139
|
-
|
140
|
-
def start_verification(params)
|
141
|
-
post(@api_host, '/verify/json', params)
|
142
|
-
end
|
143
|
-
|
144
|
-
def check_verification(request_id, params)
|
145
|
-
post(@api_host, '/verify/check/json', params.merge(request_id: request_id))
|
146
|
-
end
|
147
|
-
|
148
|
-
def get_verification(request_id)
|
149
|
-
get(@api_host, '/verify/search/json', request_id: request_id)
|
150
|
-
end
|
25
|
+
def authorization
|
26
|
+
token = auth_token || JWT.generate({application_id: application_id}, private_key)
|
151
27
|
|
152
|
-
|
153
|
-
post(@api_host, '/verify/control/json', request_id: request_id, cmd: 'cancel')
|
28
|
+
'Bearer ' + token
|
154
29
|
end
|
155
30
|
|
156
|
-
def
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
end
|
163
|
-
|
164
|
-
def get_standard_number_insight(params)
|
165
|
-
get(@api_host, '/ni/standard/json', params)
|
166
|
-
end
|
167
|
-
|
168
|
-
def get_advanced_number_insight(params)
|
169
|
-
get(@api_host, '/ni/advanced/json', params)
|
170
|
-
end
|
171
|
-
|
172
|
-
def get_advanced_async_number_insight(params)
|
173
|
-
get(@api_host, '/ni/advanced/async/json', params)
|
174
|
-
end
|
175
|
-
|
176
|
-
def request_number_insight(params)
|
177
|
-
post(@host, '/ni/json', params)
|
178
|
-
end
|
179
|
-
|
180
|
-
def get_applications(params = {})
|
181
|
-
get(@api_host, '/v1/applications', params)
|
182
|
-
end
|
183
|
-
|
184
|
-
def get_application(id)
|
185
|
-
get(@api_host, "/v1/applications/#{id}")
|
186
|
-
end
|
187
|
-
|
188
|
-
def create_application(params)
|
189
|
-
post(@api_host, '/v1/applications', params)
|
190
|
-
end
|
31
|
+
def api_key
|
32
|
+
unless @api_key
|
33
|
+
raise AuthenticationError.new('No API key provided. ' \
|
34
|
+
'See https://developer.nexmo.com/concepts/guides/authentication for details, ' \
|
35
|
+
'or email support@nexmo.com if you have any questions.')
|
36
|
+
end
|
191
37
|
|
192
|
-
|
193
|
-
put(@api_host, "/v1/applications/#{id}", params)
|
38
|
+
@api_key
|
194
39
|
end
|
195
40
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
41
|
+
def api_secret
|
42
|
+
unless @api_secret
|
43
|
+
raise AuthenticationError.new('No API secret provided. ' \
|
44
|
+
'See https://developer.nexmo.com/concepts/guides/authentication for details, ' \
|
45
|
+
'or email support@nexmo.com if you have any questions.')
|
46
|
+
end
|
199
47
|
|
200
|
-
|
201
|
-
api_request(Net::HTTP::Post, '/v1/calls', params)
|
48
|
+
@api_secret
|
202
49
|
end
|
203
50
|
|
204
|
-
def
|
205
|
-
|
206
|
-
|
51
|
+
def signature_secret
|
52
|
+
unless @signature_secret
|
53
|
+
raise AuthenticationError.new('No signature_secret provided. ' \
|
54
|
+
'You can find your signature secret in the Nexmo dashboard. ' \
|
55
|
+
'See https://developer.nexmo.com/concepts/guides/signing-messages for details, ' \
|
56
|
+
'or email support@nexmo.com if you have any questions.')
|
57
|
+
end
|
207
58
|
|
208
|
-
|
209
|
-
api_request(Net::HTTP::Get, "/v1/calls/#{uuid}")
|
59
|
+
@signature_secret
|
210
60
|
end
|
211
61
|
|
212
|
-
def
|
213
|
-
|
214
|
-
|
62
|
+
def application_id
|
63
|
+
unless @application_id
|
64
|
+
raise AuthenticationError.new('No application_id provided. ' \
|
65
|
+
'Either provide an application_id, or set an auth token. ' \
|
66
|
+
'You can add new applications from the Nexmo dashboard. ' \
|
67
|
+
'See https://developer.nexmo.com/concepts/guides/applications for details, ' \
|
68
|
+
'or email support@nexmo.com if you have any questions.')
|
69
|
+
end
|
215
70
|
|
216
|
-
|
217
|
-
api_request(Net::HTTP::Put, "/v1/calls/#{uuid}/stream", params)
|
71
|
+
@application_id
|
218
72
|
end
|
219
73
|
|
220
|
-
def
|
221
|
-
|
222
|
-
|
74
|
+
def private_key
|
75
|
+
unless @private_key
|
76
|
+
raise AuthenticationError.new('No private_key provided. ' \
|
77
|
+
'Either provide a private_key, or set an auth token. ' \
|
78
|
+
'You can add new applications from the Nexmo dashboard. ' \
|
79
|
+
'See https://developer.nexmo.com/concepts/guides/applications for details, ' \
|
80
|
+
'or email support@nexmo.com if you have any questions.')
|
81
|
+
end
|
223
82
|
|
224
|
-
|
225
|
-
api_request(Net::HTTP::Put, "/v1/calls/#{uuid}/talk", params)
|
83
|
+
@private_key
|
226
84
|
end
|
227
85
|
|
228
|
-
def
|
229
|
-
|
86
|
+
def signature
|
87
|
+
@signature ||= Signature.new(self)
|
230
88
|
end
|
231
89
|
|
232
|
-
def
|
233
|
-
|
90
|
+
def account
|
91
|
+
@account ||= Account.new(self)
|
234
92
|
end
|
235
93
|
|
236
|
-
def
|
237
|
-
|
94
|
+
def alerts
|
95
|
+
@alerts ||= Alerts.new(self)
|
238
96
|
end
|
239
97
|
|
240
|
-
def
|
241
|
-
|
242
|
-
File.open(filename, 'wb') do |file|
|
243
|
-
response.read_body do |chunk|
|
244
|
-
file.write(chunk)
|
245
|
-
end
|
246
|
-
end
|
247
|
-
end
|
98
|
+
def applications
|
99
|
+
@applications ||= Applications.new(self)
|
248
100
|
end
|
249
101
|
|
250
|
-
def
|
251
|
-
|
252
|
-
raise AuthenticationError.new('No signature_secret provided. ' \
|
253
|
-
'You can find your signature secret in the Nexmo dashboard. ' \
|
254
|
-
'See https://developer.nexmo.com/concepts/guides/signing-messages for details, ' \
|
255
|
-
'or email support@nexmo.com if you have any questions.')
|
256
|
-
end
|
257
|
-
|
258
|
-
Signature.check(params, @signature_secret)
|
102
|
+
def calls
|
103
|
+
@calls ||= Calls.new(self)
|
259
104
|
end
|
260
105
|
|
261
|
-
|
262
|
-
|
263
|
-
def get(host, request_uri, params = {})
|
264
|
-
uri = URI('https://' + host + request_uri)
|
265
|
-
uri.query = Params.encode(params.merge(api_key_and_secret))
|
266
|
-
|
267
|
-
message = Net::HTTP::Get.new(uri.request_uri)
|
268
|
-
|
269
|
-
request(uri, message)
|
106
|
+
def conversions
|
107
|
+
@conversions ||= Conversions.new(self)
|
270
108
|
end
|
271
109
|
|
272
|
-
def
|
273
|
-
|
274
|
-
|
275
|
-
message = Net::HTTP::Post.new(uri.request_uri)
|
276
|
-
message.form_data = params.merge(api_key_and_secret)
|
277
|
-
|
278
|
-
request(uri, message)
|
110
|
+
def files
|
111
|
+
@files ||= Files.new(self)
|
279
112
|
end
|
280
113
|
|
281
|
-
def
|
282
|
-
|
283
|
-
|
284
|
-
message = Net::HTTP::Put.new(uri.request_uri)
|
285
|
-
message['Content-Type'] = 'application/json'
|
286
|
-
message.body = JSON.generate(params.merge(api_key_and_secret))
|
287
|
-
|
288
|
-
request(uri, message)
|
114
|
+
def messages
|
115
|
+
@messages ||= Messages.new(self)
|
289
116
|
end
|
290
117
|
|
291
|
-
def
|
292
|
-
|
293
|
-
uri.query = Params.encode(api_key_and_secret)
|
294
|
-
|
295
|
-
message = Net::HTTP::Delete.new(uri.request_uri)
|
296
|
-
|
297
|
-
request(uri, message)
|
118
|
+
def number_insight
|
119
|
+
@number_insight ||= NumberInsight.new(self)
|
298
120
|
end
|
299
121
|
|
300
|
-
def
|
301
|
-
|
302
|
-
|
303
|
-
unless message_class::REQUEST_HAS_BODY || params.nil? || params.empty?
|
304
|
-
uri.query = Params.encode(params)
|
305
|
-
end
|
306
|
-
|
307
|
-
message = message_class.new(uri.request_uri)
|
308
|
-
|
309
|
-
if message_class::REQUEST_HAS_BODY
|
310
|
-
message['Content-Type'] = 'application/json'
|
311
|
-
message.body = JSON.generate(params)
|
312
|
-
end
|
313
|
-
|
314
|
-
token = auth_token || generate_auth_token
|
315
|
-
|
316
|
-
message['Authorization'] = "Bearer #{token}"
|
317
|
-
|
318
|
-
request(uri, message, &block)
|
122
|
+
def numbers
|
123
|
+
@numbers ||= Numbers.new(self)
|
319
124
|
end
|
320
125
|
|
321
|
-
def
|
322
|
-
|
323
|
-
http.use_ssl = true
|
324
|
-
|
325
|
-
message['User-Agent'] = @user_agent
|
326
|
-
|
327
|
-
http_response = http.request(message)
|
328
|
-
|
329
|
-
case http_response
|
330
|
-
when Net::HTTPNoContent
|
331
|
-
:no_content
|
332
|
-
when Net::HTTPSuccess
|
333
|
-
return (yield http_response) if block_given?
|
334
|
-
|
335
|
-
if http_response['Content-Type'].split(';').first == 'application/json'
|
336
|
-
JSON.parse(http_response.body)
|
337
|
-
else
|
338
|
-
http_response.body
|
339
|
-
end
|
340
|
-
when Net::HTTPUnauthorized
|
341
|
-
raise AuthenticationError, "#{http_response.code} response from #{uri.host}"
|
342
|
-
when Net::HTTPClientError
|
343
|
-
raise ClientError, "#{http_response.code} response from #{uri.host}"
|
344
|
-
when Net::HTTPServerError
|
345
|
-
raise ServerError, "#{http_response.code} response from #{uri.host}"
|
346
|
-
else
|
347
|
-
raise Error, "#{http_response.code} response from #{uri.host}"
|
348
|
-
end
|
126
|
+
def pricing
|
127
|
+
@pricing ||= PricingTypes.new(self)
|
349
128
|
end
|
350
129
|
|
351
|
-
def
|
352
|
-
|
353
|
-
raise AuthenticationError.new('No API key provided. ' \
|
354
|
-
'See https://developer.nexmo.com/concepts/guides/authentication for details, ' \
|
355
|
-
'or email support@nexmo.com if you have any questions.')
|
356
|
-
end
|
357
|
-
|
358
|
-
unless @secret
|
359
|
-
raise AuthenticationError.new('No API secret provided. ' \
|
360
|
-
'See https://developer.nexmo.com/concepts/guides/authentication for details, ' \
|
361
|
-
'or email support@nexmo.com if you have any questions.')
|
362
|
-
end
|
363
|
-
|
364
|
-
{api_key: @key, api_secret: @secret}
|
130
|
+
def sms
|
131
|
+
@sms ||= SMS.new(self)
|
365
132
|
end
|
366
133
|
|
367
|
-
def
|
368
|
-
|
369
|
-
raise AuthenticationError.new('No application_id provided. ' \
|
370
|
-
'Either provide an application_id, or set an auth token. ' \
|
371
|
-
'You can add new applications from the Nexmo dashboard. ' \
|
372
|
-
'See https://developer.nexmo.com/concepts/guides/applications for details, ' \
|
373
|
-
'or email support@nexmo.com if you have any questions.')
|
374
|
-
end
|
375
|
-
|
376
|
-
unless @private_key
|
377
|
-
raise AuthenticationError.new('No private_key provided. ' \
|
378
|
-
'Either provide a private_key, or set an auth token. ' \
|
379
|
-
'You can add new applications from the Nexmo dashboard. ' \
|
380
|
-
'See https://developer.nexmo.com/concepts/guides/applications for details, ' \
|
381
|
-
'or email support@nexmo.com if you have any questions.')
|
382
|
-
end
|
383
|
-
|
384
|
-
JWT.auth_token({application_id: @application_id}, @private_key)
|
134
|
+
def verify
|
135
|
+
@verify ||= Verify.new(self)
|
385
136
|
end
|
386
137
|
end
|
387
138
|
end
|