databasedotcom_cloudfuji 1.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,20 @@
1
+ The MIT License
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,166 @@
1
+ =databasedotcom
2
+ databasedotcom is a gem to enable ruby applications to access the SalesForce REST API. If you use bundler, simply list it in your Gemfile, like so:
3
+
4
+ gem 'databasedotcom'
5
+
6
+ If you don't use bundler, install it by hand:
7
+
8
+ gem install databasedotcom
9
+
10
+ =Documentation
11
+
12
+ Reference documentation is available at rubydoc.info[http://rubydoc.info/github/heroku/databasedotcom/master/frames]
13
+
14
+ =Source
15
+
16
+ Source is available at github[http://github.com/heroku/databasedotcom]
17
+
18
+ = Contributions
19
+
20
+ To contribute, fork this repo, make changes in your fork, then send a pull request. No pull requests without accompanying tests will be accepted. To run tests in your fork, just do
21
+
22
+ bundle install
23
+ rake
24
+
25
+ = Usage
26
+ == Initialization
27
+ When you create a Databasedotcom::Client object, you need to configure it with a client id and client secret that corresponds to one of the Remote Access Applications configured within your Salesforce instance. The Salesforce UI refers to the client id as "Consumer Key", and to the client secret as "Consumer Secret".
28
+
29
+ You can configure your Client object with a client id and client secret in one of several different ways:
30
+ === Configuration from the environment
31
+ If configuration information is present in the environment, the new Client will take configuration information from there.
32
+
33
+ export DATABASEDOTCOM_CLIENT_ID=foo
34
+ export DATABASEDOTCOM_CLIENT_SECRET=bar
35
+
36
+ Then
37
+
38
+ client = Databasedotcom::Client.new
39
+ client.client_id #=> foo
40
+ client.client_secret #=> bar
41
+
42
+ === Configuration from a YAML file
43
+ If you pass the name of a YAML file when you create a Client, the new Client will read the YAML file and take the client id and client secret values from there.
44
+
45
+ # databasedotcom.yml
46
+ #
47
+ ---
48
+ client_secret: bro
49
+ client_id: baz
50
+
51
+ Then
52
+
53
+ client = Databasedotcom::Client.new("databasedotcom.yml")
54
+ client.client_id #=> bro
55
+ client.client_secret #=> baz
56
+
57
+ === Configuration from a Hash
58
+ If you pass a hash when you create a Client, the new Client will take configuration information from that Hash.
59
+
60
+ client = Databasedotcom::Client.new :client_id => "sponge", :client_secret => "bob"
61
+ client.client_id #=> sponge
62
+ client.client_secret #=> bob
63
+
64
+ === Configuration precedence
65
+ Configuration information present in the environment always takes precedence over that passed in via a YAML file or a Hash.
66
+
67
+ export DATABASEDOTCOM_CLIENT_ID=foo
68
+ export DATABASEDOTCOM_CLIENT_SECRET=bar
69
+
70
+ Then
71
+
72
+ client = Databasedotcom::Client.new :client_id => "sponge", :client_secret => "bob"
73
+ client.client_id #=> foo
74
+ client.client_secret #=> bar
75
+
76
+ === Usage in an application deployed on Heroku
77
+ You can use the <tt>heroku config:add</tt> command to set environment variables:
78
+
79
+ heroku config:add DATABASEDOTCOM_CLIENT_ID=foo
80
+ heroku config:add DATABASEDOTCOM_CLIENT_SECRET=bar
81
+
82
+ Then, when you create your client like:
83
+
84
+ client = Databasedotcom::Client.new
85
+
86
+ it will use the configuration information that you set with <tt>heroku config:add</tt>.
87
+
88
+ === Connect to a SalesForce sandbox account
89
+ Specify the <tt>:host</tt> option when creating your Client, e.g,
90
+
91
+ Databasedotcom::Client.new :host => "test.salesforce.com", ...
92
+
93
+ == Authentication
94
+ The first thing you need to do with the new Client is to authenticate with Salesforce. You can do this in one of several ways:
95
+
96
+ === Authentication via an externally-acquired OAuth access token
97
+ If you have acquired an OAuth access token for your Salesforce instance through some external means, you can use it. Note that you have to pass both the token and your Salesforce instance URL to the <tt>authenticate</tt> method:
98
+
99
+ client.authenticate :token => "my-oauth-token", :instance_url => "http://na1.salesforce.com" #=> "my-oauth-token"
100
+
101
+ === Authentication via Omniauth
102
+ If you are using the gem within the context of a web application, and your web app is using Omniauth to do OAuth with Salesforce, you can authentication the Client direction via the Hash that Omniauth passes to your OAuth callback method, like so:
103
+
104
+ client.authenticate request.env['omniauth.auth'] #=> "the-oauth-token"
105
+
106
+ === Authentication via username and password
107
+ You can authenticate your Client directly with Salesforce with a valid username and password for a user in your Salesforce instance. Note that, if access to your Salesforce instance requires a {security token}[http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_concepts_security.htm], the value that you pass for <tt>:password</tt> must be the password for the user concatenated with her security token.
108
+
109
+ client.authenticate :username => "foo@bar.com", :password => "ThePasswordTheSecurityToken" #=> "the-oauth-token"
110
+
111
+ == Accessing the Sobject API
112
+ You can retrieve a list of Sobject defined in your Salesforce instance like so:
113
+
114
+ client.list_sobjects #=> ['User', 'Group', 'Contact']
115
+
116
+ Once you have the name of an Sobject, the easiest way to interact with it is to first materialize it:
117
+
118
+ contact_class = client.materialize("Contact") #=> Contact
119
+
120
+ By default, Sobject classes are materialized into the global namespace- if you want materialize into another module, you can easily do configure this:
121
+
122
+ client.sobject_module = My::Module
123
+ client.materialize("Contact") #=> My::Module::Contact
124
+
125
+ Materialized Sobject classes behave much like ActiveRecord classes:
126
+
127
+ contact = Contact.find("contact_id") #=> #<Contact @Id="contact_id", ...>
128
+ contact = Contact.find_by_Name("John Smith") #=> dynamic finders!
129
+ contacts = Contact.all #=> a Databasedotcom::Collection of Contact instances
130
+ contacts = Contact.find_all_by_Company("IBM") #=> a Databasedotcom::Collection of matching Contacts
131
+ contact.Name #=> the contact's Name attribute
132
+ contact["Name"] #=> same thing
133
+ contact.Name = "new name" #=> change the contact's Name attribute, in memory
134
+ contact["Name"] = "new name" #=> same thing
135
+ contact.save #=> save the changes to the database
136
+ contact.update_attributes "Name" => "newer name",
137
+ "Phone" => "4156543210" #=> change several attributes at once and save them
138
+ contact.delete #=> delete the contact from the database
139
+
140
+ See the documentation[http://rubydoc.info/github/heroku/databasedotcom/master/frames] for full details.
141
+
142
+ == Accessing the Chatter API
143
+ You can easily access Chatter feeds, group, conversations, etc.:
144
+
145
+ my_feed_items = Databasedotcom::Chatter::UserProfileFeed.find(client) #=> a Databasedotcom::Collection of FeedItems
146
+
147
+ my_feed_items.each do |feed_item|
148
+ feed_item.likes #=> a Databasedotcom::Collection of Like instances
149
+ feed_item.comments #=> a Databasedotcom::Collection of Comment instances
150
+ feed_item.raw_hash #=> the hash returned from the Chatter API describing this FeedItem
151
+ feed_item.comment("This is cool") #=> create a new comment on the FeedItem
152
+ feed_item.like #=> the authenticating user likes the FeedItem
153
+ end
154
+
155
+ me = Databasedotcom::Chatter::User.find(client, "me") #=> a User for the authenticating user
156
+ me.followers #=> a Databasedotcom::Collection of Users
157
+ me.post_status("what I'm doing now") #=> post a new status
158
+
159
+ you = Databasedotcom::Chatter::User.find(client, "your-user-id")
160
+ me.follow(you) #=> start following a user
161
+
162
+ See the documentation[http://rubydoc.info/github/heroku/databasedotcom/master/frames] for full details.
163
+
164
+ = License
165
+
166
+ This gem is licensed under the MIT License.
@@ -0,0 +1,7 @@
1
+ require 'databasedotcom/version'
2
+ require 'databasedotcom/core_extensions'
3
+ require 'databasedotcom/client'
4
+ require 'databasedotcom/sales_force_error'
5
+ require 'databasedotcom/collection'
6
+ require 'databasedotcom/sobject'
7
+ require 'databasedotcom/chatter'
@@ -0,0 +1,11 @@
1
+ require 'databasedotcom/chatter/feeds'
2
+ require 'databasedotcom/chatter/filter_feed'
3
+ require 'databasedotcom/chatter/feed_item'
4
+ require 'databasedotcom/chatter/comment'
5
+ require 'databasedotcom/chatter/like'
6
+ require 'databasedotcom/chatter/user'
7
+ require 'databasedotcom/chatter/group'
8
+ require 'databasedotcom/chatter/group_membership'
9
+ require 'databasedotcom/chatter/subscription'
10
+ require 'databasedotcom/chatter/conversation'
11
+ require 'databasedotcom/chatter/message'
@@ -0,0 +1,10 @@
1
+ require 'databasedotcom/chatter/record'
2
+
3
+ module Databasedotcom
4
+ module Chatter
5
+
6
+ # A comment posted on a FeedItem.
7
+ class Comment < Record
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,100 @@
1
+ require 'databasedotcom/chatter/record'
2
+
3
+ module Databasedotcom
4
+ module Chatter
5
+ # A thread of private messages. When calling +Conversation.find+ or +Conversation.all+, you must pass +:user_id => <my_user_id>+ in the _parameters_
6
+ #
7
+ # Conversation.all(@client, :user_id => "me")
8
+ # Conversation.find(@client, "conversationId", :user_id => "f80ad89f9d98d89dfd89")
9
+ class Conversation < Record
10
+
11
+ # Creates a new Conversation and sets its +id+ and +url+ to values obtained from the server response.
12
+ def initialize(client, response)
13
+ super
14
+ @id ||= @raw_hash["conversationId"]
15
+ @url ||= @raw_hash["conversationUrl"]
16
+ end
17
+
18
+ # Find the Conversation identified by _cid_ and archive it. Returns the updated Conversation.
19
+ #
20
+ # Conversation.archive(@client, "fakeid")
21
+ def self.archive(client, cid)
22
+ url = "/services/data/v#{client.version}/chatter/users/me/conversations/#{cid}"
23
+ response = client.http_patch(url, nil, :archived => "true")
24
+ Conversation.new(client, response.body)
25
+ end
26
+
27
+ # Find the Conversation identified by _cid_ and unarchive it. Returns the updated Conversation.
28
+ #
29
+ # Conversation.unarchive(@client, "fakeid")
30
+ def self.unarchive(client, cid)
31
+ url = "/services/data/v#{client.version}/chatter/users/me/conversations/#{cid}"
32
+ response = client.http_patch(url, nil, :archived => "false")
33
+ Conversation.new(client, response.body)
34
+ end
35
+
36
+ # Find the Conversation identified by _cid_ and mark it as read. Returns the updated Conversation.
37
+ #
38
+ # Conversation.mark_read(@client, "fakeid")
39
+ def self.mark_read(client, cid)
40
+ url = "/services/data/v#{client.version}/chatter/users/me/conversations/#{cid}"
41
+ response = client.http_patch(url, nil, :read => "true")
42
+ Conversation.new(client, response.body)
43
+ end
44
+
45
+ # Find the Conversation identified by _cid_ and mark it as unread. Returns the updated Conversation.
46
+ #
47
+ # Conversation.mark_unread(@client, "fakeid")
48
+ def self.mark_unread(client, cid)
49
+ url = "/services/data/v#{client.version}/chatter/users/me/conversations/#{cid}"
50
+ response = client.http_patch(url, nil, :read => "false")
51
+ Conversation.new(client, response.body)
52
+ end
53
+
54
+ # Gets all messages for the Conversation specified by _cid_ and the User specified by _uid_. Returns a Collection of Message objects.
55
+ def self.messages(client, uid, cid)
56
+ conversation = self.find(client, cid, :user_id => uid)
57
+ collection = Databasedotcom::Collection.new(client, nil, conversation.raw_hash["messages"]["nextPageUrl"], conversation.raw_hash["messages"]["previousPageUrl"], conversation.raw_hash["messages"]["currentPageUrl"])
58
+ conversation.raw_hash["messages"]["messages"].each do |item|
59
+ collection << Message.new(client, item)
60
+ end
61
+ collection
62
+ end
63
+
64
+ # Archive this Conversation.
65
+ def archive
66
+ self.class.archive(self.client, self.id)
67
+ end
68
+
69
+ # Unarchive this Conversation.
70
+ def unarchive
71
+ self.class.unarchive(self.client, self.id)
72
+ end
73
+
74
+ # Mark this Conversation as read.
75
+ def mark_read
76
+ self.class.mark_read(self.client, self.id)
77
+ end
78
+
79
+ # Mark this Conversation as unread.
80
+ def mark_unread
81
+ self.class.mark_unread(self.client, self.id)
82
+ end
83
+
84
+ # Return a Collection of messages from this Conversation.
85
+ def messages
86
+ collection = Databasedotcom::Collection.new(client, nil, self.raw_hash["messages"]["nextPageUrl"], self.raw_hash["messages"]["previousPageUrl"], self.raw_hash["messages"]["currentPageUrl"])
87
+ self.raw_hash["messages"]["messages"].each do |item|
88
+ collection << Message.new(client, item)
89
+ end
90
+ collection
91
+ end
92
+
93
+ protected
94
+
95
+ def self.search_parameter_name
96
+ :Q
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,64 @@
1
+ require 'json'
2
+
3
+ module Databasedotcom
4
+ module Chatter
5
+ # Parent class of all feeds and inherits from Collection. This class is not intended to be instantiated. Methods should be called on subclasses, which are all are dynamically defined (except for FilterFeed). Defined feeds are *NewsFeed*, *UserProfileFeed*, *RecordFeed*, *ToFeed*, *PeopleFeed*, *GroupsFeed*, *FilesFeed*, *CompanyFeed*, and *FilterFeed*.
6
+ class Feed < Collection
7
+
8
+ # Returns an enumerable Feed of FeedItem objects that make up the feed with the specified _id_. Should not be called as a class method on Feed, but as a method on subclasses.
9
+ #
10
+ # NewsFeed.find(@client) #=> [#<FeedItem ...>, #<FeedItem ...>, ...]
11
+ # PeopleFeed.find(@client, "userid") #=> [#<FeedItem ...>, #<FeedItem ...>, ...]
12
+ # FilterFeed.find(@client, "me", "000") #=> [#<FeedItem ...>, #<FeedItem ...>, ...]
13
+ #
14
+ # _id_prefix_ is only applicable for FilterFeed.
15
+ def self.find(client, id="me", id_prefix=nil)
16
+ path_components = %w(services data)
17
+ path_components << "v#{client.version}"
18
+ path_components.concat(%w(chatter feeds))
19
+ path_components << feed_type
20
+ path_components << id unless feed_type == "company"
21
+ path_components << id_prefix
22
+ path_components << "feed-items"
23
+ path = "/" + path_components.compact.join('/')
24
+ result = client.http_get(path)
25
+ response = JSON.parse(result.body)
26
+ collection = self.new(client, nil, response["nextPageUrl"], response["previousPageUrl"], response["currentPageUrl"])
27
+ response["items"].each do |item|
28
+ collection << FeedItem.new(client, item)
29
+ end
30
+ collection
31
+ end
32
+
33
+ # Posts a FeedItem to a Feed specified by _user_id_. Should not be called as a class method on Feed, but as a method on subclasses.
34
+ #
35
+ # UserProfileFeed.post(@client, "me", :text => "This is a status update about Salesforce.", :url => "http://www.salesforce.com")
36
+ #
37
+ # Returns the newly created FeedItem.
38
+ def self.post(client, user_id, parameters)
39
+ url = "/services/data/v#{client.version}/chatter/feeds/#{feed_type}/#{user_id}/feed-items"
40
+ response = client.http_post(url, nil, parameters)
41
+ Databasedotcom::Chatter::FeedItem.new(client, response.body)
42
+ end
43
+
44
+ # Posts a file to a Feed specified by _user_id_. Should not be called as a class method on Feed, but as a method on subclasses.
45
+ #
46
+ # UserProfileFeed.post_file(@client, "me", File.open("MyFile"), "text/plain", "MyFile", :desc => "This is an uploaded text file.")
47
+ #
48
+ # Returns the newly created FeedItem.
49
+ def self.post_file(client, user_id, io, file_type, file_name, parameters={})
50
+ url = "/services/data/v#{client.version}/chatter/feeds/#{feed_type}/#{user_id}/feed-items"
51
+ response = client.http_multipart_post(url, {"feedItemFileUpload" => UploadIO.new(io, file_type, file_name), "fileName" => file_name}, parameters)
52
+ Databasedotcom::Chatter::FeedItem.new(client, response.body)
53
+ end
54
+
55
+ private
56
+
57
+ def self.feed_type
58
+ self.name.match(/.+::(.+)Feed$/)[1].resourcerize
59
+ end
60
+ end
61
+
62
+ FEED_TYPES = %w(News UserProfile Record To People Groups Files Company)
63
+ end
64
+ end
@@ -0,0 +1,40 @@
1
+ require 'databasedotcom/chatter/record'
2
+
3
+ module Databasedotcom
4
+ module Chatter
5
+
6
+ # An item in a Feed.
7
+ class FeedItem < Record
8
+
9
+ # Returns a Collection of comments that were posted on this FeedItem instance.
10
+ def comments
11
+ collection = Databasedotcom::Collection.new(self.client, self.raw_hash["comments"]["total"], self.raw_hash["comments"]["nextPageUrl"], nil, self.raw_hash["comments"]["currentPageUrl"])
12
+ collection.concat(self.raw_hash["comments"]["comments"])
13
+ end
14
+
15
+ # Returns a Collection of likes for this FeedItem instance.
16
+ def likes
17
+ collection = Databasedotcom::Collection.new(self.client, self.raw_hash["likes"]["total"], self.raw_hash["likes"]["nextPageUrl"], self.raw_hash["likes"]["previousPageUrl"], self.raw_hash["likes"]["currentPageUrl"])
18
+ collection.concat(self.raw_hash["likes"]["likes"])
19
+ end
20
+
21
+ # Like this FeedItem.
22
+ def like
23
+ result = self.client.http_post("/services/data/v#{self.client.version}/chatter/feed-items/#{self.id}/likes")
24
+ Like.new(self.client, result.body)
25
+ end
26
+
27
+ # Post a Comment on this FeedItem with content _text_.
28
+ def comment(text)
29
+ result = self.client.http_post("/services/data/v#{self.client.version}/chatter/feed-items/#{self.id}/comments", nil, :text => text)
30
+ Comment.new(self.client, result.body)
31
+ end
32
+
33
+ protected
34
+
35
+ def self.collection_from_response(response)
36
+ response["items"]
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,5 @@
1
+ require 'databasedotcom/chatter/feed'
2
+
3
+ Databasedotcom::Chatter::FEED_TYPES.each do |feed_type|
4
+ Databasedotcom::Chatter.const_set("#{feed_type}Feed", Class.new(Databasedotcom::Chatter::Feed))
5
+ end
@@ -0,0 +1,14 @@
1
+ module Databasedotcom
2
+ module Chatter
3
+ # Filter feeds contain items pertaining to both a user and another specified resource.
4
+ class FilterFeed < Feed
5
+
6
+ # Lists all FilterFeeds for the user with id _user_id_.
7
+ def self.feeds(client, user_id="me")
8
+ url = "/services/data/v#{client.version}/chatter/feeds/filter/#{user_id}"
9
+ result = client.http_get(url)
10
+ JSON.parse(result.body)
11
+ end
12
+ end
13
+ end
14
+ end