nexmo 5.3.0 → 5.4.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 +4 -4
- data/README.md +56 -20
- data/lib/nexmo.rb +3 -1
- data/lib/nexmo/authentication/basic.rb +9 -0
- data/lib/nexmo/client.rb +5 -1
- data/lib/nexmo/logger.rb +48 -0
- data/lib/nexmo/namespace.rb +6 -17
- data/lib/nexmo/secrets.rb +31 -0
- data/lib/nexmo/version.rb +1 -1
- data/nexmo.gemspec +8 -2
- metadata +12 -6
- data/lib/nexmo/key_value_logger.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: acbd01437020690fe8cfd847124290e384ea7ad151f373aafb7cb043197941a7
|
4
|
+
data.tar.gz: a12a717b8dacd66dc993c237120a1a54dee43305fdf6f5ed93565eb4d4a6a517
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a6540019a076be34194d8185b77417155cd00bc295fbc6983f7b6b58cd9b7ae68a0abad6001f4af202afbaeb5e94296b17558f31461508dd9f33ff5647f040e
|
7
|
+
data.tar.gz: 761584429c830e57c493f78292fe17842c4a327305b480144e91bbe2cbb263e27f7d1394e876a9d4552822dcb84f22ff38e4317c2f74e47d35639a65adec551b
|
data/README.md
CHANGED
@@ -14,6 +14,7 @@ need a Nexmo account. Sign up [for free at nexmo.com][signup].
|
|
14
14
|
* [Number Insight API](#number-insight-api)
|
15
15
|
* [Application API](#application-api)
|
16
16
|
* [Numbers API](#numbers-api)
|
17
|
+
* [Secret Management API](#secret-management-api)
|
17
18
|
* [Redact API](#redact-api)
|
18
19
|
* [Logging](#logging)
|
19
20
|
* [JWT authentication](#jwt-authentication)
|
@@ -86,7 +87,7 @@ of source control, or in some kind of key management infrastructure.
|
|
86
87
|
|
87
88
|
## SMS API
|
88
89
|
|
89
|
-
### Send
|
90
|
+
### Send an SMS
|
90
91
|
|
91
92
|
```ruby
|
92
93
|
response = client.sms.send(from: 'Ruby', to: 'YOUR NUMBER', text: 'Hello world')
|
@@ -98,12 +99,12 @@ else
|
|
98
99
|
end
|
99
100
|
```
|
100
101
|
|
101
|
-
Docs: [https://developer.nexmo.com/api/sms#
|
102
|
+
Docs: [https://developer.nexmo.com/api/sms#send-an-sms](https://developer.nexmo.com/api/sms?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#send-an-sms)
|
102
103
|
|
103
104
|
|
104
105
|
## Voice API
|
105
106
|
|
106
|
-
###
|
107
|
+
### Create an outbound call
|
107
108
|
|
108
109
|
```ruby
|
109
110
|
response = client.calls.create({
|
@@ -113,33 +114,33 @@ response = client.calls.create({
|
|
113
114
|
})
|
114
115
|
```
|
115
116
|
|
116
|
-
Docs: [https://developer.nexmo.com/api/voice#
|
117
|
+
Docs: [https://developer.nexmo.com/api/voice#createCall](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#createCall)
|
117
118
|
|
118
|
-
###
|
119
|
+
### Get details of your calls
|
119
120
|
|
120
121
|
```ruby
|
121
122
|
response = client.calls.list
|
122
123
|
```
|
123
124
|
|
124
|
-
Docs: [https://developer.nexmo.com/api/voice#
|
125
|
+
Docs: [https://developer.nexmo.com/api/voice#getCalls](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#getCalls)
|
125
126
|
|
126
|
-
###
|
127
|
+
### Get detail of a specific call
|
127
128
|
|
128
129
|
```ruby
|
129
130
|
response = client.calls.get(uuid)
|
130
131
|
```
|
131
132
|
|
132
|
-
Docs: [https://developer.nexmo.com/api/voice#
|
133
|
+
Docs: [https://developer.nexmo.com/api/voice#getCall](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#getCall)
|
133
134
|
|
134
|
-
###
|
135
|
+
### Modify an in progress call
|
135
136
|
|
136
137
|
```ruby
|
137
138
|
response = client.calls.hangup(uuid)
|
138
139
|
```
|
139
140
|
|
140
|
-
Docs: [https://developer.nexmo.com/api/voice#
|
141
|
+
Docs: [https://developer.nexmo.com/api/voice#updateCall](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#updateCall)
|
141
142
|
|
142
|
-
###
|
143
|
+
### Play an audio file into a call
|
143
144
|
|
144
145
|
```ruby
|
145
146
|
stream_url = 'https://nexmo-community.github.io/ncco-examples/assets/voice_api_audio_streaming.mp3'
|
@@ -147,39 +148,39 @@ stream_url = 'https://nexmo-community.github.io/ncco-examples/assets/voice_api_a
|
|
147
148
|
response = client.calls.stream.start(uuid, stream_url: [stream_url])
|
148
149
|
```
|
149
150
|
|
150
|
-
Docs: [https://developer.nexmo.com/api/voice#
|
151
|
+
Docs: [https://developer.nexmo.com/api/voice#startStream](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#startStream)
|
151
152
|
|
152
|
-
### Stop
|
153
|
+
### Stop playing an audio file into a call
|
153
154
|
|
154
155
|
```ruby
|
155
156
|
response = client.stream.stop(uuid)
|
156
157
|
```
|
157
158
|
|
158
|
-
Docs: [https://developer.nexmo.com/api/voice#
|
159
|
+
Docs: [https://developer.nexmo.com/api/voice#stopStream](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#stopStream)
|
159
160
|
|
160
|
-
###
|
161
|
+
### Play text to speech into a call
|
161
162
|
|
162
163
|
```ruby
|
163
164
|
response = client.talk.start(uuid, text: 'Hello')
|
164
165
|
```
|
165
166
|
|
166
|
-
Docs: [https://developer.nexmo.com/api/voice#
|
167
|
+
Docs: [https://developer.nexmo.com/api/voice#startTalk](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#startTalk)
|
167
168
|
|
168
|
-
### Stop
|
169
|
+
### Stop text to speech in a call
|
169
170
|
|
170
171
|
```ruby
|
171
172
|
response = client.talk.stop(uuid)
|
172
173
|
```
|
173
174
|
|
174
|
-
Docs: [https://developer.nexmo.com/api/voice#
|
175
|
+
Docs: [https://developer.nexmo.com/api/voice#stopTalk](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#stopTalk)
|
175
176
|
|
176
|
-
###
|
177
|
+
### Play DTMF tones into a call
|
177
178
|
|
178
179
|
```ruby
|
179
180
|
response = client.calls.dtmf.send(uuid, digits: '1234')
|
180
181
|
```
|
181
182
|
|
182
|
-
Docs: [https://developer.nexmo.com/api/voice#
|
183
|
+
Docs: [https://developer.nexmo.com/api/voice#startDTMF](https://developer.nexmo.com/api/voice?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#startDTMF)
|
183
184
|
|
184
185
|
|
185
186
|
## Verify API
|
@@ -358,6 +359,41 @@ client.numbers.update(country: 'GB', msisdn: '447700900000', voice_callback_type
|
|
358
359
|
Docs: [https://developer.nexmo.com/api/developer/numbers#update-a-number](https://developer.nexmo.com/api/developer/numbers?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#update-a-number)
|
359
360
|
|
360
361
|
|
362
|
+
## Secret Management API
|
363
|
+
|
364
|
+
### Retrieve a list of secrets
|
365
|
+
|
366
|
+
```ruby
|
367
|
+
client.secrets.list
|
368
|
+
```
|
369
|
+
|
370
|
+
Docs: [https://developer.nexmo.com/api/account/secret-management#retrieveSecrets](https://developer.nexmo.com/api/account/secret-management?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#retrieveSecrets)
|
371
|
+
|
372
|
+
### Create a secret
|
373
|
+
|
374
|
+
```ruby
|
375
|
+
client.secrets.create(secret: 't0ps3cr3t')
|
376
|
+
```
|
377
|
+
|
378
|
+
Docs: [https://developer.nexmo.com/api/account/secret-management#createSecret](https://developer.nexmo.com/api/account/secret-management?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#createSecret)
|
379
|
+
|
380
|
+
### Retrieve a secret
|
381
|
+
|
382
|
+
```ruby
|
383
|
+
client.secrets.get(secret_id)
|
384
|
+
```
|
385
|
+
|
386
|
+
Docs: [https://developer.nexmo.com/api/account/secret-management#retrieveSecret](https://developer.nexmo.com/api/account/secret-management?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#retrieveSecret)
|
387
|
+
|
388
|
+
### Revoke a secret
|
389
|
+
|
390
|
+
```ruby
|
391
|
+
client.secrets.revoke(secret_id)
|
392
|
+
```
|
393
|
+
|
394
|
+
Docs: [https://developer.nexmo.com/api/account/secret-management#revokeSecret](https://developer.nexmo.com/api/account/secret-management?utm_source=DEV_REL&utm_medium=github&utm_campaign=ruby-client-library#revokeSecret)
|
395
|
+
|
396
|
+
|
361
397
|
## Redact API
|
362
398
|
|
363
399
|
### Redact a specific message
|
data/lib/nexmo.rb
CHANGED
@@ -12,10 +12,11 @@ require 'nexmo/errors/client_error'
|
|
12
12
|
require 'nexmo/errors/server_error'
|
13
13
|
require 'nexmo/errors/authentication_error'
|
14
14
|
require 'nexmo/authentication/abstract'
|
15
|
+
require 'nexmo/authentication/basic'
|
15
16
|
require 'nexmo/authentication/bearer_token'
|
16
17
|
require 'nexmo/authentication/key_secret_params'
|
17
18
|
require 'nexmo/authentication/key_secret_query'
|
18
|
-
require 'nexmo/
|
19
|
+
require 'nexmo/logger'
|
19
20
|
require 'nexmo/namespace'
|
20
21
|
require 'nexmo/client'
|
21
22
|
require 'nexmo/account'
|
@@ -33,5 +34,6 @@ require 'nexmo/numbers'
|
|
33
34
|
require 'nexmo/pricing_types'
|
34
35
|
require 'nexmo/pricing'
|
35
36
|
require 'nexmo/redact'
|
37
|
+
require 'nexmo/secrets'
|
36
38
|
require 'nexmo/sms'
|
37
39
|
require 'nexmo/verify'
|
data/lib/nexmo/client.rb
CHANGED
@@ -33,7 +33,7 @@ module Nexmo
|
|
33
33
|
end
|
34
34
|
|
35
35
|
def logger=(logger)
|
36
|
-
@logger =
|
36
|
+
@logger = Logger.new(logger)
|
37
37
|
end
|
38
38
|
|
39
39
|
def token
|
@@ -149,6 +149,10 @@ module Nexmo
|
|
149
149
|
@redact ||= Redact.new(self)
|
150
150
|
end
|
151
151
|
|
152
|
+
def secrets
|
153
|
+
@secrets ||= Secrets.new(self)
|
154
|
+
end
|
155
|
+
|
152
156
|
def sms
|
153
157
|
@sms ||= SMS.new(self)
|
154
158
|
end
|
data/lib/nexmo/logger.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'logger'
|
3
|
+
require 'forwardable'
|
4
|
+
|
5
|
+
module Nexmo
|
6
|
+
class Logger
|
7
|
+
def initialize(logger)
|
8
|
+
@logger = logger || ::Logger.new(nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
extend Forwardable
|
12
|
+
|
13
|
+
::Logger::Severity.constants.map(&:downcase).each do |name|
|
14
|
+
def_delegator :@logger, name, name
|
15
|
+
end
|
16
|
+
|
17
|
+
def log_request_info(request)
|
18
|
+
info do
|
19
|
+
format('Nexmo API request', {
|
20
|
+
method: request.method,
|
21
|
+
path: request.uri.path
|
22
|
+
})
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def log_response_info(response, host)
|
27
|
+
info do
|
28
|
+
format('Nexmo API response', {
|
29
|
+
host: host,
|
30
|
+
status: response.code,
|
31
|
+
type: response.content_type,
|
32
|
+
length: response.content_length,
|
33
|
+
trace_id: response['x-nexmo-trace-id']
|
34
|
+
})
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def format(message, hash)
|
41
|
+
return message if hash.nil?
|
42
|
+
|
43
|
+
fields = hash.map { |key, value| "#{key}=#{value}" if value }.compact
|
44
|
+
fields.unshift(message)
|
45
|
+
fields.join(' ')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
data/lib/nexmo/namespace.rb
CHANGED
@@ -7,6 +7,8 @@ module Nexmo
|
|
7
7
|
def initialize(client)
|
8
8
|
@client = client
|
9
9
|
|
10
|
+
@logger = client.logger
|
11
|
+
|
10
12
|
@host = self.class.host
|
11
13
|
|
12
14
|
@http = Net::HTTP.new(@host, Net::HTTP.https_default_port)
|
@@ -44,10 +46,6 @@ module Nexmo
|
|
44
46
|
Post = Net::HTTP::Post
|
45
47
|
Delete = Net::HTTP::Delete
|
46
48
|
|
47
|
-
def logger
|
48
|
-
@client.logger
|
49
|
-
end
|
50
|
-
|
51
49
|
def request(path, params: nil, type: Get, &block)
|
52
50
|
uri = URI('https://' + @host + path)
|
53
51
|
|
@@ -62,7 +60,7 @@ module Nexmo
|
|
62
60
|
|
63
61
|
authentication.update(uri)
|
64
62
|
|
65
|
-
message = type.new(uri
|
63
|
+
message = type.new(uri)
|
66
64
|
|
67
65
|
message['User-Agent'] = @client.user_agent
|
68
66
|
|
@@ -70,15 +68,15 @@ module Nexmo
|
|
70
68
|
|
71
69
|
self.class.request_body.update(message, params) if type::REQUEST_HAS_BODY
|
72
70
|
|
73
|
-
logger.
|
71
|
+
@logger.log_request_info(message)
|
74
72
|
|
75
73
|
response = @http.request(message, &block)
|
76
74
|
|
77
|
-
log_response_info(response)
|
75
|
+
@logger.log_response_info(response, @host)
|
78
76
|
|
79
77
|
return if block
|
80
78
|
|
81
|
-
logger.debug(response.body)
|
79
|
+
@logger.debug(response.body) if response.body
|
82
80
|
|
83
81
|
parse(response)
|
84
82
|
end
|
@@ -103,14 +101,5 @@ module Nexmo
|
|
103
101
|
raise Error
|
104
102
|
end
|
105
103
|
end
|
106
|
-
|
107
|
-
def log_response_info(response)
|
108
|
-
logger.info('Nexmo API response',
|
109
|
-
host: @host,
|
110
|
-
status: response.code,
|
111
|
-
type: response.content_type,
|
112
|
-
length: response.content_length,
|
113
|
-
trace_id: response['x-nexmo-trace-id'])
|
114
|
-
end
|
115
104
|
end
|
116
105
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Nexmo
|
4
|
+
class Secrets < Namespace
|
5
|
+
self.authentication = Basic
|
6
|
+
|
7
|
+
self.request_body = JSON
|
8
|
+
|
9
|
+
def create(params)
|
10
|
+
request('/accounts/' + account_id + '/secrets', params: params, type: Post)
|
11
|
+
end
|
12
|
+
|
13
|
+
def list
|
14
|
+
request('/accounts/' + account_id + '/secrets')
|
15
|
+
end
|
16
|
+
|
17
|
+
def get(secret_id)
|
18
|
+
request('/accounts/' + account_id + '/secrets/' + secret_id)
|
19
|
+
end
|
20
|
+
|
21
|
+
def revoke(secret_id)
|
22
|
+
request('/accounts/' + account_id + '/secrets/' + secret_id, type: Delete)
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def account_id
|
28
|
+
@client.api_key
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/nexmo/version.rb
CHANGED
data/nexmo.gemspec
CHANGED
@@ -5,8 +5,8 @@ Gem::Specification.new do |s|
|
|
5
5
|
s.version = Nexmo::VERSION
|
6
6
|
s.license = 'MIT'
|
7
7
|
s.platform = Gem::Platform::RUBY
|
8
|
-
s.authors = ['
|
9
|
-
s.email = ['
|
8
|
+
s.authors = ['Nexmo']
|
9
|
+
s.email = ['devrel@nexmo.com']
|
10
10
|
s.homepage = 'https://github.com/Nexmo/nexmo-ruby'
|
11
11
|
s.description = 'Nexmo Client Library for Ruby'
|
12
12
|
s.summary = 'This is the Ruby client library for Nexmo\'s API. To use it you\'ll need a Nexmo account. Sign up for free at https://www.nexmo.com'
|
@@ -17,4 +17,10 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.add_development_dependency('minitest', '~> 5.0')
|
18
18
|
s.add_development_dependency('webmock', '~> 3.0')
|
19
19
|
s.require_path = 'lib'
|
20
|
+
s.metadata = {
|
21
|
+
'homepage' => 'https://github.com/Nexmo/nexmo-ruby',
|
22
|
+
'source_code_uri' => 'https://github.com/Nexmo/nexmo-ruby',
|
23
|
+
'bug_tracker_uri' => 'https://github.com/Nexmo/nexmo-ruby/issues',
|
24
|
+
'changelog_uri' => 'https://github.com/Nexmo/nexmo-ruby/blob/master/CHANGES.md'
|
25
|
+
}
|
20
26
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nexmo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.
|
4
|
+
version: 5.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Nexmo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-09-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jwt
|
@@ -68,7 +68,7 @@ dependencies:
|
|
68
68
|
version: '3.0'
|
69
69
|
description: Nexmo Client Library for Ruby
|
70
70
|
email:
|
71
|
-
-
|
71
|
+
- devrel@nexmo.com
|
72
72
|
executables: []
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
@@ -80,6 +80,7 @@ files:
|
|
80
80
|
- lib/nexmo/alerts.rb
|
81
81
|
- lib/nexmo/applications.rb
|
82
82
|
- lib/nexmo/authentication/abstract.rb
|
83
|
+
- lib/nexmo/authentication/basic.rb
|
83
84
|
- lib/nexmo/authentication/bearer_token.rb
|
84
85
|
- lib/nexmo/authentication/key_secret_params.rb
|
85
86
|
- lib/nexmo/authentication/key_secret_query.rb
|
@@ -98,8 +99,8 @@ files:
|
|
98
99
|
- lib/nexmo/form_data.rb
|
99
100
|
- lib/nexmo/json.rb
|
100
101
|
- lib/nexmo/jwt.rb
|
101
|
-
- lib/nexmo/key_value_logger.rb
|
102
102
|
- lib/nexmo/keys.rb
|
103
|
+
- lib/nexmo/logger.rb
|
103
104
|
- lib/nexmo/messages.rb
|
104
105
|
- lib/nexmo/namespace.rb
|
105
106
|
- lib/nexmo/number_insight.rb
|
@@ -108,6 +109,7 @@ files:
|
|
108
109
|
- lib/nexmo/pricing.rb
|
109
110
|
- lib/nexmo/pricing_types.rb
|
110
111
|
- lib/nexmo/redact.rb
|
112
|
+
- lib/nexmo/secrets.rb
|
111
113
|
- lib/nexmo/signature.rb
|
112
114
|
- lib/nexmo/sms.rb
|
113
115
|
- lib/nexmo/user_agent.rb
|
@@ -117,7 +119,11 @@ files:
|
|
117
119
|
homepage: https://github.com/Nexmo/nexmo-ruby
|
118
120
|
licenses:
|
119
121
|
- MIT
|
120
|
-
metadata:
|
122
|
+
metadata:
|
123
|
+
homepage: https://github.com/Nexmo/nexmo-ruby
|
124
|
+
source_code_uri: https://github.com/Nexmo/nexmo-ruby
|
125
|
+
bug_tracker_uri: https://github.com/Nexmo/nexmo-ruby/issues
|
126
|
+
changelog_uri: https://github.com/Nexmo/nexmo-ruby/blob/master/CHANGES.md
|
121
127
|
post_install_message:
|
122
128
|
rdoc_options: []
|
123
129
|
require_paths:
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Nexmo
|
4
|
-
class KeyValueLogger
|
5
|
-
def initialize(logger)
|
6
|
-
@logger = logger
|
7
|
-
end
|
8
|
-
|
9
|
-
def debug(message, data = nil)
|
10
|
-
@logger.debug(format(message, data)) if @logger
|
11
|
-
end
|
12
|
-
|
13
|
-
def info(message, data = nil)
|
14
|
-
@logger.info(format(message, data)) if @logger
|
15
|
-
end
|
16
|
-
|
17
|
-
def warning(message, data = nil)
|
18
|
-
@logger.warning(format(message, data)) if @logger
|
19
|
-
end
|
20
|
-
|
21
|
-
def error(message, data = nil)
|
22
|
-
@logger.error(format(message, data)) if @logger
|
23
|
-
end
|
24
|
-
|
25
|
-
private
|
26
|
-
|
27
|
-
def format(message, hash)
|
28
|
-
return message if hash.nil?
|
29
|
-
|
30
|
-
fields = hash.map { |key, value| "#{key}=#{value}" if value }.compact
|
31
|
-
fields.unshift(message)
|
32
|
-
fields.join(' ')
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|