sfdc 2.1.0 → 2.1.1

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.
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: