sfdc 2.1.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. checksums.yaml +6 -14
  2. data/README.md +405 -3
  3. data/lib/sfdc/mash.rb +2 -0
  4. data/lib/sfdc/version.rb +1 -1
  5. metadata +17 -18
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- Y2U1NDhlNzYyNmY0OTRkOTY4YThhNjVlOWIzZjM3YWEwMzU5ZDE2NA==
5
- data.tar.gz: !binary |-
6
- NjkxNWRkYmI5MWE2NjQ5OWY1NjY1NWVlNjgwZDZjMjQxZmRjMzU1Yg==
7
- !binary "U0hBNTEy":
8
- metadata.gz: !binary |-
9
- M2JkYzEwNzc4MzNkMmI4Y2Q5Zjk0NWMxZWU4OTQxODgzY2M3N2FmYjkyYzQ5
10
- NTRmMGI3NjliODM4MDc0NjAzZWYxNWNjOTVjZGEyYjVlN2Y2NzZhMjI4MmZi
11
- ZTVmN2RmYjJlOTU5OThlZjdlMDc4MzYzYjFlOGNkODg2ZjcyMzI=
12
- data.tar.gz: !binary |-
13
- OTJiMTljYzEyYzBiM2ZiYzA4MzM2NDQxMmJiZGQwMDY3OWZhMjI5N2MyOTgy
14
- NjNmOTVkYjdkZWMxYmY2NmYxZDdkMTUwMzNlOWJjYjRhYzdhNjVlNDVmMzkw
15
- ZDYwOGI1YWZkZjU1MDQ4YTk0ODJjZDcxZTY0NzRjZWY4OTI4MzY=
2
+ SHA1:
3
+ metadata.gz: 1cde2f301c54d22121161db5bac74ea65c32e521
4
+ data.tar.gz: 3eb6cdafae8ccdb49435ce4ce5e21a8141451b65
5
+ SHA512:
6
+ metadata.gz: 7460858cd9ce5f2e739d6082a2b05678288324ba16ecc75b05b81c5ec99d18cbdda57d5c47ada7ce68f26a4b80c6c8e9c9dd1716e4c1be2ec3a3f4aa953482a3
7
+ data.tar.gz: 51fabb05af717c93781679fb0f884df1fba00cb99fce6633e8f7cfe8f7a775afebb6fb432325137e7a9a91388a89d3f91cfe37908ae14dffaa00fbbcfc3a5a0f
data/README.md CHANGED
@@ -1,6 +1,19 @@
1
1
  # Sfdc
2
2
 
3
- TODO: Write a gem description
3
+ Sfdc is a ruby gem for the [Salesforce REST api](http://www.salesforce.com/us/developer/docs/api_rest/index.htm).
4
+
5
+ Features include:
6
+
7
+ * Support for interacting with multiple users from different orgs.
8
+ * Support for parent-to-child relationships.
9
+ * Support for aggregate queries.
10
+ * Support for the [Streaming API](#streaming)
11
+ * Support for blob data types.
12
+ * Support for GZIP compression.
13
+ * Support for [custom Apex REST endpoints](#custom-apex-rest-endpoints).
14
+ * Support for dependent picklists.
15
+ * Support for decoding [Force.com Canvas](http://www.salesforce.com/us/developer/docs/platform_connectpre/canvas_framework.pdf) signed requests. (NEW!)
16
+
4
17
 
5
18
  ## Installation
6
19
 
@@ -18,12 +31,401 @@ Or install it yourself as:
18
31
 
19
32
  ## Usage
20
33
 
21
- TODO: Write usage instructions here
34
+ Sfdc is designed with flexibility and ease of use in mind. By default, all api calls will
35
+ return [Hashie::Mash](https://github.com/intridea/hashie/) objects,
36
+ so you can do things like `client.query('select Id, (select Name from Children__r) from Account').Children__r.first.Name`.
37
+
38
+ ### Initialization
39
+
40
+ Which authentication method you use really depends on your use case. If you're
41
+ building an application where many users from different orgs are authenticated
42
+ through oauth and you need to interact with data in their org on their behalf,
43
+ you should use the OAuth token authentication method.
44
+
45
+ If you're using the gem to interact with a single org (maybe you're building some
46
+ salesforce integration internally?) then you should use the username/password
47
+ authentication method.
48
+
49
+ #### OAuth token authentication
50
+
51
+ ```ruby
52
+ client = Sfdc.new :oauth_token => 'oauth token',
53
+ :instance_url => 'instance url'
54
+ ```
55
+
56
+ Although the above will work, you'll probably want to take advantage of the
57
+ (re)authentication middleware by specifying a refresh token, client id and client secret:
58
+
59
+ ```ruby
60
+ client = Sfdc.new :oauth_token => 'oauth token',
61
+ :refresh_token => 'refresh token',
62
+ :instance_url => 'instance url',
63
+ :client_id => 'client_id',
64
+ :client_secret => 'client_secret'
65
+ ```
66
+
67
+ #### Username/Password authentication
68
+
69
+ If you prefer to use a username and password to authenticate:
70
+
71
+ ```ruby
72
+ client = Sfdc.new :username => 'foo',
73
+ :password => 'bar',
74
+ :security_token => 'security token'
75
+ :client_id => 'client_id',
76
+ :client_secret => 'client_secret'
77
+ ```
78
+
79
+ You can also set the username, password, security token, client id and client
80
+ secret in environment variables:
81
+
82
+ ```bash
83
+ export SALESFORCE_USERNAME="username"
84
+ export SALESFORCE_PASSWORD="password"
85
+ export SALESFORCE_SECURITY_TOKEN="security token"
86
+ export SALESFORCE_CLIENT_ID="client id"
87
+ export SALESFORCE_CLIENT_SECRET="client secret"
88
+ ```
89
+
90
+ ```ruby
91
+ client = Sfdc.new
92
+ ```
93
+ ### Proxy Support
94
+
95
+ You can specify a http proxy using the :proxy_uri option, as follows:
96
+
97
+ ```ruby
98
+ client = Sfdc.new :username => 'foo',
99
+ :password => 'bar',
100
+ :security_token => 'security token'
101
+ :client_id => 'client_id',
102
+ :client_secret => 'client_secret',
103
+ :proxy_uri => 'http://proxy.example.com:123'
104
+ ```
105
+ This paramter also will accept 'http://user@password:proxy.example.com:123' or using the environemnt variable PROXY_URI.
106
+
107
+ #### Sandbox Orgs
108
+
109
+ You can connect to sandbox orgs by specifying a host. The default host is
110
+ 'login.salesforce.com':
111
+
112
+ ```ruby
113
+ client = Sfdc.new :host => 'test.salesforce.com'
114
+ ```
115
+
116
+ #### Global configuration
117
+
118
+ You can set any of the options passed into Sfdc.new globally:
119
+
120
+ ```ruby
121
+ Sfdc.configure do |config|
122
+ config.client_id = 'foo'
123
+ config.client_secret = 'bar'
124
+ end
125
+ ```
126
+
127
+ ### Bang! methods
128
+
129
+ All the CRUD methods (create, update, upsert, destroy) have equivalent methods with
130
+ a ! at the end (create!, update!, upsert!, destroy!), which can be used if you need
131
+ to do some custom error handling. The bang methods will raise exceptions, while the
132
+ non-bang methods will return false in the event that an exception is raised. This
133
+ works similarly to ActiveRecord.
134
+
135
+ * * *
136
+
137
+ ### query
138
+
139
+ ```ruby
140
+ accounts = client.query("select Id, Something__c from Account where Id = 'someid'")
141
+ # => #<Sfdc::Collection >
142
+
143
+ account = records.first
144
+ # => #<Sfdc::SObject >
145
+
146
+ account.sobject_type
147
+ # => 'Account'
148
+
149
+ account.Id
150
+ # => "someid"
151
+
152
+ account.Name = 'Foobar'
153
+ account.save
154
+ # => true
155
+
156
+ account.destroy
157
+ # => true
158
+ ```
159
+
160
+ ### find
161
+
162
+ ```ruby
163
+ client.find('Account', '001D000000INjVe')
164
+ # => #<Sfdc::SObject Id="001D000000INjVe" Name="Test" LastModifiedBy="005G0000002f8FHIAY" ... >
165
+
166
+ client.find('Account', '1234', 'Some_External_Id_Field__c')
167
+ # => #<Sfdc::SObject Id="001D000000INjVe" Name="Test" LastModifiedBy="005G0000002f8FHIAY" ... >
168
+ ```
169
+
170
+ ### search
171
+
172
+ ```ruby
173
+ # Find all occurrences of 'bar'
174
+ client.search('FIND {bar}')
175
+ # => #<Sfdc::Collection >
176
+
177
+ # Find accounts match the term 'genepoint' and return the Name field
178
+ client.search('FIND {genepoint} RETURNING Account (Name)').map(&:Name)
179
+ # => ['GenePoint']
180
+ ```
181
+
182
+ ### create
183
+
184
+ ```ruby
185
+ # Add a new account
186
+ client.create('Account', Name: 'Foobar Inc.')
187
+ # => '0016000000MRatd'
188
+ ```
189
+
190
+ ### update
191
+
192
+ ```ruby
193
+ # Update the Account with Id '0016000000MRatd'
194
+ client.update('Account', Id: '0016000000MRatd', Name: 'Whizbang Corp')
195
+ # => true
196
+ ```
197
+
198
+ ### upsert
199
+
200
+ ```ruby
201
+ # Update the record with external ID of 12
202
+ client.upsert('Account', 'External__c', External__c: 12, Name: 'Foobar')
203
+ ```
204
+
205
+ ### destroy
206
+
207
+ ```ruby
208
+ # Delete the Account with Id '0016000000MRatd'
209
+ client.destroy('Account', '0016000000MRatd')
210
+ # => true
211
+ ```
212
+
213
+ ### describe
214
+
215
+ ```ruby
216
+ # get the global describe for all sobjects
217
+ client.describe
218
+ # => { ... }
219
+
220
+ # get the describe for the Account object
221
+ client.describe('Account')
222
+ # => { ... }
223
+ ```
224
+
225
+ ### picklist\_values
226
+
227
+
228
+ ```ruby
229
+ client.picklist_values('Account', 'Type')
230
+ # => [#<Sfdc::Mash label="Prospect" value="Prospect">]
231
+
232
+ # Given a custom object named Automobile__c with picklist fields
233
+ # Model__c and Make__c, where Model__c depends on the value of
234
+ # Make__c.
235
+ client.picklist_values('Automobile__c', 'Model__c', :valid_for => 'Honda')
236
+ # => [#<Sfdc::Mash label="Civic" value="Civic">, ... ]
237
+ ```
238
+
239
+ * * *
240
+
241
+ ### authenticate!
242
+
243
+ Performs an authentication and returns the response. In general, calling this
244
+ directly shouldn't be required, since the client will handle authentication for
245
+ you automatically. This should only be used if you want to force
246
+ an authentication before using the streaming api, or you want to get some
247
+ information about the user.
248
+
249
+ ```ruby
250
+ response = client.authenticate!
251
+ # => #<Sfdc::Mash access_token="..." id="https://login.salesforce.com/id/00DE0000000cOGcMAM/005E0000001eM4LIAU" instance_url="https://na9.salesforce.com" issued_at="1348465359751" scope="api refresh_token" signature="3fW0pC/TEY2cjK5FCBFOZdjRtCfAuEbK1U74H/eF+Ho=">
252
+
253
+ # Get the user information
254
+ info = client.get(response.id).body
255
+ info.user_id
256
+ # => '005E0000001eM4LIAU'
257
+ ```
258
+
259
+ * * *
260
+
261
+ ### File Uploads
262
+
263
+ Using the new [Blob Data](http://www.salesforce.com/us/developer/docs/api_rest/Content/dome_sobject_insert_update_blob.htm) api feature (500mb limit):
264
+
265
+ ```ruby
266
+ client.create 'Document', FolderId: '00lE0000000FJ6H',
267
+ Description: 'Document test',
268
+ Name: 'My image',
269
+ Body: Sfdc::UploadIO.new(File.expand_path('image.jpg', __FILE__), 'image/jpeg'))
270
+ ```
271
+
272
+ Using base64 encoded data (37.5mb limit):
273
+
274
+ ```ruby
275
+ client.create 'Document', FolderId: '00lE0000000FJ6H',
276
+ Description: 'Document test',
277
+ Name: 'My image',
278
+ Body: Base64::encode64(File.read('image.jpg'))
279
+ ```
280
+
281
+ _See also: http://www.salesforce.com/us/developer/docs/api_rest/Content/dome_sobject_insert_update_blob.htm_
282
+
283
+ * * *
284
+
285
+ ### Downloading Attachments
286
+
287
+ Sfdc also makes it incredibly easy to download Attachments:
288
+
289
+ ```ruby
290
+ attachment = client.query('select Id, Name, Body from Attachment').first
291
+ File.open(attachment.Name, 'wb') { |f| f.write(attachment.Body) }
292
+ ```
293
+
294
+ * * *
295
+
296
+ ### Custom Apex REST endpoints
297
+
298
+ You can use Sfdc to interact with your custom REST endpoints, by using
299
+ `.get`, `.put`, `.patch`, `.post`, and `.delete`.
300
+
301
+ For example, if you had the following Apex REST endpoint on Salesforce:
302
+
303
+ ```apex
304
+ @RestResource(urlMapping='/FieldCase/*')
305
+ global class RESTCaseController {
306
+ @HttpGet
307
+ global static List<Case> getOpenCases() {
308
+ String companyName = RestContext.request.params.get('company');
309
+ Account company = [ Select ID, Name, Email__c, BillingState from Account where Name = :companyName];
310
+
311
+ List<Case> cases = [SELECT Id, Subject, Status, OwnerId, Owner.Name from Case WHERE AccountId = :company.Id];
312
+ return cases;
313
+ }
314
+ }
315
+ ```
316
+
317
+ Then you could query the cases using Sfdc:
318
+
319
+ ```ruby
320
+ client.get '/services/apexrest/FieldCase', :company => 'GenePoint'
321
+ # => #<Sfdc::Collection ...>
322
+ ```
323
+
324
+ * * *
325
+
326
+ ### Streaming
327
+
328
+ Sfdc supports the [Streaming API](http://wiki.developerforce.com/page/Getting_Started_with_the_Force.com_Streaming_API), and makes implementing
329
+ pub/sub with Salesforce a trivial task:
330
+
331
+ ```ruby
332
+ # Sfdc uses faye as the underlying implementation for CometD.
333
+ require 'faye'
334
+
335
+ # Initialize a client with your username/password/oauth token/etc.
336
+ client = Sfdc.new :username => 'foo',
337
+ :password => 'bar',
338
+ :security_token => 'security token'
339
+ :client_id => 'client_id',
340
+ :client_secret => 'client_secret'
341
+
342
+ # Create a PushTopic for subscribing to Account changes.
343
+ client.create! 'PushTopic', {
344
+ ApiVersion: '23.0',
345
+ Name: 'AllAccounts',
346
+ Description: 'All account records',
347
+ NotifyForOperations: 'All',
348
+ NotifyForFields: 'All',
349
+ Query: "select Id from Account"
350
+ }
351
+
352
+ EM.run {
353
+ # Subscribe to the PushTopic.
354
+ client.subscribe 'AllAccounts' do |message|
355
+ puts message.inspect
356
+ end
357
+ }
358
+ ```
359
+
360
+ Boom, you're now receiving push notifications when Accounts are
361
+ created/updated.
362
+
363
+ _See also: http://www.salesforce.com/us/developer/docs/api_streaming/index.htm_
364
+
365
+ * * *
366
+
367
+ ### Caching
368
+
369
+ The gem supports easy caching of GET requests (e.g. queries):
370
+
371
+ ```ruby
372
+ # rails example:
373
+ client = Sfdc.new cache: Rails.cache
374
+
375
+ # or
376
+ Sfdc.configure do |config|
377
+ config.cache = Rails.cache
378
+ end
379
+ ```
380
+
381
+ If you enable caching, you can disable caching on a per-request basis by using
382
+ .without_caching:
383
+
384
+ ```ruby
385
+ client.without_caching do
386
+ client.query('select Id from Account')
387
+ end
388
+ ```
389
+
390
+ * * *
391
+
392
+ ### Logging/Debugging/Instrumenting
393
+
394
+ You can easily inspect what Sfdc is sending/receiving by setting
395
+ `Sfdc.log = true`.
396
+
397
+ ```ruby
398
+ Sfdc.log = true
399
+ client = Sfdc.new.query('select Id, Name from Account')
400
+ ```
401
+
402
+ Another awesome feature about Sfdc is that, because it is based on
403
+ Faraday, you can insert your own middleware. For example, if you were using
404
+ Sfdc in a rails app, you can setup custom reporting to
405
+ [Librato](https://github.com/librato/librato-rails) using ActiveSupport::Notifications:
406
+
407
+ ```ruby
408
+ client = Sfdc.new do |builder|
409
+ builder.insert_after Sfdc::Middleware::InstanceURL,
410
+ FaradayMiddleware::Instrumentation, name: 'request.salesforce'
411
+ end
412
+
413
+ # config/initializers/notifications.rb
414
+ ActiveSupport::Notifications.subscribe('request.salesforce') do |*args|
415
+ event = ActiveSupport::Notifications::Event.new(*args)
416
+ Librato.increment 'api.salesforce.request.total'
417
+ Librato.timing 'api.salesforce.request.time', event.duration
418
+ end
419
+ ```
420
+
421
+ ## Force.com Canvas
422
+
423
+ You can use Sfdc to decode signed requests from Salesforce. See [the example app](https://gist.github.com/4052312).
22
424
 
23
425
  ## Contributing
24
426
 
25
427
  1. Fork it
26
428
  2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
429
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
28
430
  4. Push to the branch (`git push origin my-new-feature`)
29
431
  5. Create new Pull Request
data/lib/sfdc/mash.rb CHANGED
@@ -51,6 +51,8 @@ module Sfdc
51
51
  case val
52
52
  when self.class
53
53
  val.dup
54
+ when Hash
55
+ duping ? val.dup : val
54
56
  when ::Hash
55
57
  val = val.dup if duping
56
58
  self.class.klass(val).new(val, @client)
data/lib/sfdc/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Sfdc
2
- VERSION = "2.1.0"
2
+ VERSION = "2.1.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sfdc
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bruce Yue
@@ -9,36 +9,36 @@ autorequire:
9
9
  bindir:
10
10
  - bin
11
11
  cert_chain: []
12
- date: 2013-04-09 00:00:00.000000000 Z
12
+ date: 2013-04-10 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: faraday
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - ~>
18
+ - - '>='
19
19
  - !ruby/object:Gem::Version
20
- version: 0.8.4
20
+ version: 0.8.7
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
- - - ~>
25
+ - - '>='
26
26
  - !ruby/object:Gem::Version
27
- version: 0.8.4
27
+ version: 0.8.7
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: faraday_middleware
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - ! '>='
32
+ - - '>='
33
33
  - !ruby/object:Gem::Version
34
- version: 0.8.8
34
+ version: 0.9.0
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - ! '>='
39
+ - - '>='
40
40
  - !ruby/object:Gem::Version
41
- version: 0.8.8
41
+ version: 0.9.0
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: json
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -71,14 +71,14 @@ dependencies:
71
71
  name: activesupport
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
- - - ! '>='
74
+ - - '>='
75
75
  - !ruby/object:Gem::Version
76
76
  version: '0'
77
77
  type: :runtime
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
- - - ! '>='
81
+ - - '>='
82
82
  - !ruby/object:Gem::Version
83
83
  version: '0'
84
84
  - !ruby/object:Gem::Dependency
@@ -99,14 +99,14 @@ dependencies:
99
99
  name: rake
100
100
  requirement: !ruby/object:Gem::Requirement
101
101
  requirements:
102
- - - ! '>='
102
+ - - '>='
103
103
  - !ruby/object:Gem::Version
104
104
  version: '0'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
- - - ! '>='
109
+ - - '>='
110
110
  - !ruby/object:Gem::Version
111
111
  version: '0'
112
112
  description: Salesforce API
@@ -159,19 +159,18 @@ require_paths:
159
159
  - lib
160
160
  required_ruby_version: !ruby/object:Gem::Requirement
161
161
  requirements:
162
- - - ! '>='
162
+ - - '>='
163
163
  - !ruby/object:Gem::Version
164
164
  version: '0'
165
165
  required_rubygems_version: !ruby/object:Gem::Requirement
166
166
  requirements:
167
- - - ! '>='
167
+ - - '>='
168
168
  - !ruby/object:Gem::Version
169
169
  version: '0'
170
170
  requirements: []
171
171
  rubyforge_project: sfdc
172
- rubygems_version: 2.0.3
172
+ rubygems_version: 2.0.0
173
173
  signing_key:
174
174
  specification_version: 4
175
175
  summary: Salesforce API
176
176
  test_files: []
177
- has_rdoc: