4me-sdk 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/4me-sdk.gemspec +40 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +74 -0
- data/LICENSE +21 -0
- data/README.md +324 -0
- data/lib/sdk4me.rb +37 -0
- data/lib/sdk4me/ca-bundle.crt +3910 -0
- data/lib/sdk4me/client.rb +342 -0
- data/lib/sdk4me/client/attachments.rb +109 -0
- data/lib/sdk4me/client/multipart.rb +75 -0
- data/lib/sdk4me/client/response.rb +119 -0
- data/lib/sdk4me/client/version.rb +5 -0
- metadata +169 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 885049091080590a682f5fa2df6320a55d251ab5
|
4
|
+
data.tar.gz: 8f119ed9d892fa6abb55ac2aafafd297a8f2e617
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 72ce9082f51ad8f90626f7039a9ce2c67616dd6983616592d92572b9801880b92a033ac18cae8616c254fbdb917e388bfa436a7694324a18b9794a3ce9ac9806
|
7
|
+
data.tar.gz: e998fc6b6f19f313039a793cfb7357c9aabf8e05c8a65e67a718c449bed7a5e053a563204dd57f0e946f11d042d08977fde8f2be36f52ca95d2f419f3b3a1103
|
data/4me-sdk.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sdk4me/client/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = '4me-sdk'
|
8
|
+
spec.version = Sdk4me::Client::VERSION
|
9
|
+
spec.platform = Gem::Platform::RUBY
|
10
|
+
spec.required_ruby_version = '>= 2.0.0'
|
11
|
+
spec.authors = ['4me']
|
12
|
+
spec.email = %q{developers@4me.com}
|
13
|
+
spec.description = %q{SDK for accessing the 4me}
|
14
|
+
spec.summary = %q{The official 4me SDK for Ruby. Provides easy access to the APIs found at https://developer.4me.com}
|
15
|
+
spec.homepage = %q{https://github.com/code4me/4me-sdk-ruby}
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = Dir.glob('lib/**/*') + %w(
|
19
|
+
LICENSE
|
20
|
+
README.md
|
21
|
+
Gemfile
|
22
|
+
Gemfile.lock
|
23
|
+
4me-sdk.gemspec
|
24
|
+
)
|
25
|
+
spec.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
26
|
+
spec.test_files = `git ls-files -- {test,spec}/*`.split("\n")
|
27
|
+
spec.require_paths = ['lib']
|
28
|
+
spec.rdoc_options = ['--charset=UTF-8']
|
29
|
+
|
30
|
+
spec.add_runtime_dependency 'gem_config', '>=0.3'
|
31
|
+
spec.add_runtime_dependency 'activesupport', '>= 4.2'
|
32
|
+
spec.add_runtime_dependency 'mime-types', '>= 3.0'
|
33
|
+
|
34
|
+
spec.add_development_dependency 'bundler', '~> 1'
|
35
|
+
spec.add_development_dependency 'rake', '~> 12'
|
36
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
37
|
+
spec.add_development_dependency 'webmock', '~> 2'
|
38
|
+
spec.add_development_dependency 'simplecov', '~> 0'
|
39
|
+
|
40
|
+
end
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
4me-sdk (1.1.2)
|
5
|
+
activesupport
|
6
|
+
gem_config
|
7
|
+
mime-types
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: https://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activesupport (5.2.1)
|
13
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
14
|
+
i18n (>= 0.7, < 2)
|
15
|
+
minitest (~> 5.1)
|
16
|
+
tzinfo (~> 1.1)
|
17
|
+
addressable (2.5.2)
|
18
|
+
public_suffix (>= 2.0.2, < 4.0)
|
19
|
+
concurrent-ruby (1.1.3)
|
20
|
+
crack (0.4.3)
|
21
|
+
safe_yaml (~> 1.0.0)
|
22
|
+
diff-lcs (1.3)
|
23
|
+
docile (1.3.1)
|
24
|
+
gem_config (0.3.1)
|
25
|
+
hashdiff (0.3.7)
|
26
|
+
i18n (1.1.1)
|
27
|
+
concurrent-ruby (~> 1.0)
|
28
|
+
json (2.1.0)
|
29
|
+
mime-types (3.2.2)
|
30
|
+
mime-types-data (~> 3.2015)
|
31
|
+
mime-types-data (3.2018.0812)
|
32
|
+
minitest (5.11.3)
|
33
|
+
public_suffix (3.0.3)
|
34
|
+
rake (12.3.1)
|
35
|
+
rspec (3.3.0)
|
36
|
+
rspec-core (~> 3.3.0)
|
37
|
+
rspec-expectations (~> 3.3.0)
|
38
|
+
rspec-mocks (~> 3.3.0)
|
39
|
+
rspec-core (3.3.2)
|
40
|
+
rspec-support (~> 3.3.0)
|
41
|
+
rspec-expectations (3.3.1)
|
42
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
43
|
+
rspec-support (~> 3.3.0)
|
44
|
+
rspec-mocks (3.3.2)
|
45
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
46
|
+
rspec-support (~> 3.3.0)
|
47
|
+
rspec-support (3.3.0)
|
48
|
+
safe_yaml (1.0.4)
|
49
|
+
simplecov (0.16.1)
|
50
|
+
docile (~> 1.1)
|
51
|
+
json (>= 1.8, < 3)
|
52
|
+
simplecov-html (~> 0.10.0)
|
53
|
+
simplecov-html (0.10.2)
|
54
|
+
thread_safe (0.3.6)
|
55
|
+
tzinfo (1.2.5)
|
56
|
+
thread_safe (~> 0.1)
|
57
|
+
webmock (2.3.2)
|
58
|
+
addressable (>= 2.3.6)
|
59
|
+
crack (>= 0.3.2)
|
60
|
+
hashdiff
|
61
|
+
|
62
|
+
PLATFORMS
|
63
|
+
ruby
|
64
|
+
|
65
|
+
DEPENDENCIES
|
66
|
+
4me-sdk!
|
67
|
+
bundler (~> 1)
|
68
|
+
rake (~> 12)
|
69
|
+
rspec (~> 3.3)
|
70
|
+
simplecov (~> 0)
|
71
|
+
webmock (~> 2)
|
72
|
+
|
73
|
+
BUNDLED WITH
|
74
|
+
1.16.1
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2018 https://code.4me.com
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,324 @@
|
|
1
|
+
# Sdk4me::Client
|
2
|
+
|
3
|
+
Client for accessing the [4me REST API](http://developer.4me.com/v1/)
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem '4me-sdk'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install 4me-sdk
|
18
|
+
|
19
|
+
## Configuration
|
20
|
+
|
21
|
+
### Global
|
22
|
+
|
23
|
+
```
|
24
|
+
Sdk4me.configure do |config|
|
25
|
+
config.api_token = 'd41f5868feb65fc87fa2311a473a8766ea38bc40'
|
26
|
+
config.account = 'my-sandbox'
|
27
|
+
config.logger = Rails.logger
|
28
|
+
...
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
All options available:
|
33
|
+
|
34
|
+
* _logger_: The [Ruby Logger](http://www.ruby-doc.org/stdlib-1.9.3/libdoc/logger/rdoc/Logger.html) instance, default: `Logger.new(STDOUT)`
|
35
|
+
* _host_: The [4me API host](http://developer.4me.com/v1/#service-url), default: 'https://api.4me.com'
|
36
|
+
* _api_version_: The [4me API version](http://developer.4me.com/v1/#service-url), default: 'v1'
|
37
|
+
* _api_token_: (**required**) The [4me API token](http://developer.4me.com/v1/#api-tokens)
|
38
|
+
* _account_: Specify a [different account](http://developer.4me.com/v1/#multiple-accounts) to work with
|
39
|
+
* _source_: The [source](http://developer.4me.com/v1/general/source/) used when creating new records
|
40
|
+
* _max_retry_time_: maximum nr of seconds to wait for server to respond (default = 5400 = 1.5 hours)<br/>
|
41
|
+
The sleep time between retries starts at 2 seconds and doubles after each retry, i.e.
|
42
|
+
2, 6, 18, 54, 162, 486, 1458, 4374, 13122, ... seconds.<br/>
|
43
|
+
One retry will always be performed unless you set the value to -1.
|
44
|
+
* _read_timeout_: [HTTP read timeout](http://ruby-doc.org/stdlib-2.0.0/libdoc/net/http/rdoc/Net/HTTP.html#method-i-read_timeout-3D) in seconds (default = 25)
|
45
|
+
* _block_at_rate_limit_: Set to `true` to block the request until the [rate limit](http://developer.4me.com/v1/#rate-limiting) is lifted, default: `false`
|
46
|
+
* _proxy_host_: Define in case HTTP traffic needs to go through a proxy
|
47
|
+
* _proxy_port_: Port of the proxy, defaults to 8080
|
48
|
+
* _proxy_user_: Proxy user
|
49
|
+
* _proxy_password_: Proxy password
|
50
|
+
* _ca_file_: Certificate file (defaults to the provided ca-bundle.crt file from Mozilla)
|
51
|
+
|
52
|
+
### Override
|
53
|
+
|
54
|
+
Each time an 4me SDK Client is instantiated it is possible to override the [global configuration](#global-configuration) like so:
|
55
|
+
|
56
|
+
```
|
57
|
+
client = Sdk4me::Client.new(account: 'trusted-sandbox', source: 'my special integration')
|
58
|
+
```
|
59
|
+
|
60
|
+
### Proxy
|
61
|
+
|
62
|
+
The proxy settings are limited to basic authentication only. In case ISA-NTLM authentication is required, make sure to setup a local proxy configured to forward the requests. And example local proxy host for Windows is [Fiddle](http://www.telerik.com/fiddler).
|
63
|
+
|
64
|
+
## 4me SDK Client
|
65
|
+
|
66
|
+
Minimal example:
|
67
|
+
|
68
|
+
```
|
69
|
+
require 'sdk4me/client'
|
70
|
+
|
71
|
+
client = Sdk4me::Client.new(api_token: '3a4e4590179263839...')
|
72
|
+
response = client.get('me')
|
73
|
+
puts response[:primary_email]
|
74
|
+
```
|
75
|
+
|
76
|
+
### Retrieve a single record
|
77
|
+
|
78
|
+
The `get` method can be used to retrieve a single record from SDK4ME.
|
79
|
+
|
80
|
+
```
|
81
|
+
response = Sdk4me::Client.new.get('organizations/4321')
|
82
|
+
puts response[:name]
|
83
|
+
```
|
84
|
+
|
85
|
+
By default this call will return all [fields](http://developer.4me.com/v1/organizations/#fields) of the Organization.
|
86
|
+
|
87
|
+
The fields can be accessed using *symbols* and *strings*, and it is possible chain a number of keys in one go:
|
88
|
+
```
|
89
|
+
response = Sdk4me::Client.new.get('organizations/4321')
|
90
|
+
puts response[:parent][:name] # this may throw an error when +parent+ is +nil+
|
91
|
+
puts response[:parent, :name] # using this format you will retrieve +nil+ when +parent+ is +nil+
|
92
|
+
puts response['parent', 'name'] # strings are also accepted as keys
|
93
|
+
```
|
94
|
+
|
95
|
+
### Browse through a collection of records
|
96
|
+
|
97
|
+
Although the `get` method can be also used to retrieve a collection of records from SDK4ME, the preferred way is to use the `each` method.
|
98
|
+
|
99
|
+
```
|
100
|
+
count = Sdk4me::Client.new.each('organizations') do |organization|
|
101
|
+
puts organization[:name]
|
102
|
+
end
|
103
|
+
puts "Found #{count} organizations"
|
104
|
+
```
|
105
|
+
|
106
|
+
By default this call will return all [collection fields](http://developer.4me.com/v1/organizations/#collection-fields) for each Organization.
|
107
|
+
For more fields, check out the [field selection](http://developer.4me.com/v1/general/field_selection/#collection-of-resources) documentation.
|
108
|
+
|
109
|
+
The fields can be accessed using *symbols* and *strings*, and it is possible chain a number of keys in one go:
|
110
|
+
```
|
111
|
+
count = Sdk4me::Client.new.each('organizations', fields: 'parent') do |organization|
|
112
|
+
puts organization[:parent][:name] # this may throw an error when +parent+ is +nil+
|
113
|
+
puts organization[:parent, :name] # using this format you will retrieve +nil+ when +parent+ is +nil+
|
114
|
+
puts organization['parent', 'name'] # strings are also accepted as keys
|
115
|
+
end
|
116
|
+
```
|
117
|
+
|
118
|
+
Note that an `Sdk4me::Exception` could be thrown in case one of the API requests fails. When using the [blocking options](#blocking) the chances of this happening are rather small and you may decide not to explicitly catch the `Sdk4me::Exception` here, but leave it up to a generic exception handler.
|
119
|
+
|
120
|
+
### Retrieve a collection of records
|
121
|
+
|
122
|
+
The `each` method [described above](#browse-through-a-collection-of-records) is the preferred way to work with collections of data.
|
123
|
+
|
124
|
+
If you really want to [paginate](http://developer.4me.com/v1/general/pagination/) yourself, the `get` method is your friend.
|
125
|
+
|
126
|
+
```
|
127
|
+
@client = Sdk4me::Client.new
|
128
|
+
response = @client.get('organizations', {per_page: 10, page: 2})
|
129
|
+
|
130
|
+
puts response.json # all data in an array
|
131
|
+
|
132
|
+
puts "showing page #{response.current_page}/#{response.total_pages}, with #{response.per_page} records per page"
|
133
|
+
puts "total number of records #{response.total_entries}"
|
134
|
+
|
135
|
+
# retrieve collection for other pages directly from the response
|
136
|
+
first_page = @client.get(response.pagination_link(:first))
|
137
|
+
prev_page = @client.get(response.pagination_link(:prev))
|
138
|
+
next_page = @client.get(response.pagination_link(:next))
|
139
|
+
last_page = @client.get(response.pagination_link(:last))
|
140
|
+
```
|
141
|
+
|
142
|
+
By default this call will return all [collection fields](http://developer.4me.com/v1/organizations/#collection-fields) for each Organization.
|
143
|
+
For more fields, check out the [field selection](http://developer.4me.com/v1/general/field_selection/#collection-of-resources) documentation.
|
144
|
+
|
145
|
+
The fields can be accessed using *symbols* and *strings*, and it is possible chain a number of keys in one go:
|
146
|
+
```
|
147
|
+
response = Sdk4me::Client.new.get('organizations', {per_page: 10, page: 2, fields: 'parent'})
|
148
|
+
puts response[:parent, :name] # an array with the parent organization names
|
149
|
+
puts response['parent', 'name'] # strings are also accepted as keys
|
150
|
+
```
|
151
|
+
|
152
|
+
### Create a new record
|
153
|
+
|
154
|
+
Creating new records is done using the `post` method.
|
155
|
+
|
156
|
+
```
|
157
|
+
response = Sdk4me::Client.new.post('people', {primary_email: 'new.user@example.com', organization_id: 777})
|
158
|
+
if response.valid?
|
159
|
+
puts "New person created with id #{response[:id]}"
|
160
|
+
else
|
161
|
+
puts response.message
|
162
|
+
end
|
163
|
+
```
|
164
|
+
|
165
|
+
Make sure to validate the success by calling `response.valid?` and to take appropriate action in case the response is not valid.
|
166
|
+
|
167
|
+
|
168
|
+
### Update an existing record
|
169
|
+
|
170
|
+
Updating records is done using the `put` method.
|
171
|
+
|
172
|
+
```
|
173
|
+
response = Sdk4me::Client.new.put('people/888', {name: 'Mrs. Susan Smith', organization_id: 777})
|
174
|
+
if response.valid?
|
175
|
+
puts "Person with id #{response[:id]} successfully updated"
|
176
|
+
else
|
177
|
+
puts response.message
|
178
|
+
end
|
179
|
+
```
|
180
|
+
|
181
|
+
Make sure to validate the success by calling `response.valid?` and to take appropriate action in case the response is not valid.
|
182
|
+
|
183
|
+
### Delete an existing record
|
184
|
+
|
185
|
+
Deleting records is done using the `delete` method.
|
186
|
+
|
187
|
+
```
|
188
|
+
response = Sdk4me::Client.new.delete('organizations/88/addresses/')
|
189
|
+
if response.valid?
|
190
|
+
puts "Addresses of Organization with id #{response[:id]} successfully removed"
|
191
|
+
else
|
192
|
+
puts response.message
|
193
|
+
end
|
194
|
+
```
|
195
|
+
|
196
|
+
Make sure to validate the success by calling `response.valid?` and to take appropriate action in case the response is not valid.
|
197
|
+
|
198
|
+
|
199
|
+
### Note Attachments
|
200
|
+
|
201
|
+
To add attachments to a note is rather tricky when done manually as it involves separate file uploads to Amazon S3 and sending
|
202
|
+
confirmations back to 4me.
|
203
|
+
|
204
|
+
To make it easy, a special `attachments` parameter can be added when using the `post` or `put` method when the `note` field is available.
|
205
|
+
|
206
|
+
```
|
207
|
+
response = Sdk4me::Client.new.put('requests/416621', {
|
208
|
+
status: 'waiting_for_customer',
|
209
|
+
note: 'Please complete the attached forms and reassign the request back to us.',
|
210
|
+
attachments: ['/tmp/forms/Inventory.xls', '/tmp/forms/PersonalData.xls']
|
211
|
+
})
|
212
|
+
```
|
213
|
+
|
214
|
+
If an attachment upload fails, the errors are logged but the `post` or `put` request will still be sent to 4me without the
|
215
|
+
failed attachments. To receive exceptions add `attachments_exception: true` to the data.
|
216
|
+
|
217
|
+
```
|
218
|
+
begin
|
219
|
+
response = Sdk4me::Client.new.put('requests/416621', {
|
220
|
+
status: 'waiting_for_customer',
|
221
|
+
note: 'Please complete the attached forms and reassign the request back to us.',
|
222
|
+
attachments: ['/tmp/forms/Inventory.xls', '/tmp/forms/PersonalData.xls']
|
223
|
+
})
|
224
|
+
if response.valid?
|
225
|
+
puts "Request #{response[:id]} updated and attachments added to the note"
|
226
|
+
else
|
227
|
+
puts "Update of request failed: #{response.message}"
|
228
|
+
end
|
229
|
+
catch Sdk4me::UploadFailed => ex
|
230
|
+
puts "Could not upload an attachment: #{ex.message}"
|
231
|
+
end
|
232
|
+
```
|
233
|
+
|
234
|
+
### Importing CSV files
|
235
|
+
|
236
|
+
4me also provides an [Import API](http://developer.4me.com/v1/import/). The 4me SDK Client can be used to upload files to that API.
|
237
|
+
|
238
|
+
```
|
239
|
+
response = Sdk4me::Client.new.import('\tmp\people.csv', 'people')
|
240
|
+
if response.valid?
|
241
|
+
puts "Import queued with token #{response[:token]}"
|
242
|
+
else
|
243
|
+
puts "Import upload failed: #{response.message}"
|
244
|
+
end
|
245
|
+
|
246
|
+
```
|
247
|
+
|
248
|
+
The second argument contains the [import type](http://developer.4me.com/v1/import/#parameters).
|
249
|
+
|
250
|
+
It is also possible to [monitor the progress](http://developer.4me.com/v1/import/#import-progress) of the import and block until the import is complete. In that case you will need to add some exception handling to your code.
|
251
|
+
|
252
|
+
```
|
253
|
+
begin
|
254
|
+
response = Sdk4me::Client.new.import('\tmp\people.csv', 'people', true)
|
255
|
+
puts response[:state]
|
256
|
+
puts response[:results]
|
257
|
+
puts response[:message]
|
258
|
+
catch Sdk4me::UploadFailed => ex
|
259
|
+
puts "Could not upload the people import file: #{ex.message}"
|
260
|
+
catch Sdk4me::Exception => ex
|
261
|
+
puts "Unable to monitor progress of the people import: #{ex.message}"
|
262
|
+
end
|
263
|
+
```
|
264
|
+
|
265
|
+
Note that blocking for the import to finish is required when you import multiple CSVs that are dependent on each other.
|
266
|
+
|
267
|
+
|
268
|
+
### Exporting CSV files
|
269
|
+
|
270
|
+
4me also provides an [Export API](http://developer.4me.com/v1/export/). The 4me SDK Client can be used to download (zipped) CSV files using that API.
|
271
|
+
|
272
|
+
```
|
273
|
+
response = Sdk4me::Client.new.export(['people', 'people_contact_details'], DateTime.new(2012,03,30,23,00,00))
|
274
|
+
if response.valid?
|
275
|
+
puts "Export queued with token #{response[:token]}"
|
276
|
+
else
|
277
|
+
puts "Export failed: #{response.message}"
|
278
|
+
end
|
279
|
+
|
280
|
+
```
|
281
|
+
|
282
|
+
The first argument contains the [export types](http://developer.4me.com/v1/export/#parameters).
|
283
|
+
The second argument is optional and limits the export to all changed records since the given time.
|
284
|
+
|
285
|
+
It is also possible to [monitor the progress](http://developer.4me.com/v1/export/#export-progress) of the export and block until the export is complete. In that case you will need to add some exception handling to your code.
|
286
|
+
|
287
|
+
```
|
288
|
+
require 'open-uri'
|
289
|
+
|
290
|
+
begin
|
291
|
+
response = Sdk4me::Client.new.export(['people', 'people_contact_details'], nil, true)
|
292
|
+
puts response[:state]
|
293
|
+
# write the export file to disk
|
294
|
+
File.open('/tmp/export.zip', 'wb') { |f| f.write(open(response[:url]).read) }
|
295
|
+
catch Sdk4me::UploadFailed => ex
|
296
|
+
puts "Could not queue the people export: #{ex.message}"
|
297
|
+
catch Sdk4me::Exception => ex
|
298
|
+
puts "Unable to monitor progress of the people export: #{ex.message}"
|
299
|
+
end
|
300
|
+
```
|
301
|
+
|
302
|
+
Note that blocking for the export to finish is recommended as you will get direct access to the exported file.
|
303
|
+
|
304
|
+
|
305
|
+
### Blocking
|
306
|
+
|
307
|
+
By default all actions on the 4me SDK Client will block until the 4me API is accessible, see the _max_retry_time_ option in the [configuration](#global-configuration). This is especially helpfull for flaky internet connections.
|
308
|
+
|
309
|
+
By setting the _block_at_rate_limit_ to `true` in the [configuration](#global-configuration) all actions will also block in case the [rate limit](http://developer.4me.com/v1/#rate-limiting) is reached. The action is retried every 5 minutes until the [rate limit](http://developer.4me.com/v1/#rate-limiting) is lifted again, which might take up to 1 hour.
|
310
|
+
|
311
|
+
|
312
|
+
### Exception handling
|
313
|
+
|
314
|
+
The standard methods `get`, `post`, `put` and `delete` will always return a Response with an [error message](http://developer.4me.com/v1/#http-status-codes) in case something went wrong.
|
315
|
+
|
316
|
+
By calling `response.valid?` you will know if the action succeeded or not, and `response.message` provides additinal information in case the response was invalid.
|
317
|
+
|
318
|
+
```
|
319
|
+
response = Sdk4me::Client.new.get('organizations/1a2b')
|
320
|
+
puts response.valid?
|
321
|
+
puts response.message
|
322
|
+
```
|
323
|
+
|
324
|
+
The methods `each` and `import` may throw an `Sdk4me::Exception` in case something failed, see the examples above.
|