Chatter posts are stored using a series of relationships that follow a common pattern, illustrated in Figure 12.1. Starting from the right of the diagram, a Feed object, suffixed with the word Feed, contains Chatter posts. Feed objects exist for each Chatter-enabled parent object type. The parent object is on the left, and the line between them indicates that a single parent record can have zero to many posts.
Note
Feed objects are unusual for Force.com in that they are read-only. To insert or delete Chatter posts, you must use the generic FeedItem
object, discussed later in this chapter.
The Feed objects appear and disappear based on the Chatter configuration. For example, if Chatter is enabled on the Project__c
custom object, then an object named Project__Feed
exists, the object used to store posts related to Projects. If Chatter is later disabled for Project__c
, the Project__Feed
object is removed from the Force.com database.
The five types of post content, indicated by the Type
field of the Feed objects, are described here:
Text (TextPost)—This is the default type of Chatter post. It contains plaintext, with no HTML markup or rich formatting allowed. The text is contained in the Body
field. The sample code in this chapter focuses on the text post type because the other post types behave almost identically, differing only on the fields used to store data.
URL (LinkPost)—The Chatter user interface allows you to attach a single URL to a post, which appears immediately below the post text. The URL value is stored in the LinkUrl
field, with the URL label in Title
.
File (ContentPost)—From the Chatter user interface, you can select a file to attach to a post. The file can be a reference to another Chatter-attached file or uploaded from your local computer. The file content is base-64 encoded and placed in the ContentData
field. Several additional file-related metadata fields are also stored with the file: ContentFileName
and ContentDescription
(input by the user during upload), ContentType
(file MIME type), and ContentSize
(file size in bytes).
Field change (TrackedChange)—This post type is relevant only to feed-tracked changes. It is generated by Force.com itself and cannot be created by users or programs.
Status update (UserStatus)—Chatter users can change their status from their profile page or any Chatter user interface. This action triggers Force.com to insert a status update Chatter post, with the Body
field set to the new status.
The remainder of this subsection contains SOQL queries and Apex code snippets to demonstrate how to work with posts and their parent feed objects. They are organized into the following four scenarios:
Standard object feeds—When Chatter is enabled for an organization, most standard objects have corresponding Chatter feeds.
Custom object feeds—Every custom object that is Chatter-enabled by the administrator has its own feed.
User feeds—Separate feeds exist for the Chatter user profile as well as the standard User object.
Home tab feed—The Home tab has its own feed, called NewsFeed. This contains a collection of all the activity in followed records.
Caution
Understanding posts and feeds is critical because the rest of the section builds upon this knowledge.
When Chatter is enabled for an organization, feed objects exist for every standard object that supports Chatter. Listing 12.1 is an example of retrieving the ten most recent Chatter posts on the Contact object using the ContactFeed
object.
SELECT ParentId, Body, Type, CreatedBy.Name, CreatedDate
FROM ContactFeed
ORDER BY CreatedDate DESC LIMIT 10
To create a post on the Contact
object, you need the Id of a Contact record to serve as the parent of the post. This Id becomes the ParentId
column in FeedItem
. Force.com takes care of determining which feeds the post belongs to based on the type of object referenced by the ParentId
. This means you can use the same code to create posts regardless of the type of object you’re posting about.
The sample code in Listing 12.2 contains a method for creating a Chatter post. Pass it the Id of a Contact record in the recordId
argument, and the text of the post body in the text
argument. Make a note of the return value because it is used later to remove the post.
public Id post(Id recordId, String text) {
FeedItem post = new FeedItem(ParentId = recordId, Body = text);
insert post;
return post.Id;
}
You can quickly test the method in Listing 12.2 using the Execute Anonymous feature in the Developer Console or the Force.com IDE. For example: Id i = post([SELECT Id FROM Contact LIMIT 1].Id, 'test'),
Unlike creating posts, the code to delete posts is object-specific, not generic. It requires the specific feed object containing the post to be known. For example, if you created a post with a Contact record as the ParentId
, delete the post from the ContactFeed
object, as shown in Listing 12.3.
public void deleteContactPost(Id postId) {
ContactFeed post = [ SELECT Id FROM ContactFeed
WHERE Id = :postId ];
delete post;
}
Chatter posts on custom objects behave identically to standard objects, with two exceptions. The naming scheme for the feed objects is slightly different, and a feed object does not exist until Chatter is enabled on the custom object. For example, if you enable Chatter on the Project__c
object, the Project__Feed
Chatter object becomes available.
Listing 12.4 demonstrates a query for posts on the Project__c
object. As you can see, the columns are identical to that of the standard feed, but the FROM
clause refers to the Project__c
-specific feed object. To get any feed object’s name, strip the __c
from the end of your custom object’s API name and then add the __Feed
suffix. You can follow this pattern to access the posts of any custom object.
SELECT ParentId, Body, Type, CreatedBy.Name, CreatedDate
FROM Project__Feed
Note
The procedure for creating and deleting Chatter posts in custom objects is identical to that of standard objects.
UserFeed—UserFeed contains feed-tracked changes for fields on your User object, as well as posts by other users on your profile. You cannot query another user’s UserFeed unless you log in to Force.com as that user.
UserProfileFeed—The UserProfileFeed is a superset of the UserFeed. It includes Chatter from other objects followed by the user, such as groups. It requires the use of the Chatter REST API to query it, described later in this chapter.
The SOQL in Listing 12.5 returns the Chatter posts for the current user, the user logged in to Force.com and executing the query.
SELECT ParentId, Id, Type, CreatedById, CreatedDate
FROM UserFeed
Note
The procedure for creating and deleting Chatter posts in UserFeed is identical to that of standard objects.
If you’ve experimented with Chatter in the Force.com user interface, you might have noticed that the Home tab aggregates all the posts and comments you follow in one place. The Chatter appearing on the Home tab is accessible only via the Chatter REST API.
18.223.106.33