5

As part of the Winter 16 release, in addition to the lightning experience Salesforce rolled out some new Notes. I enabled the new notes, however we are keeping salesforce classic experience for now. I was hoping to get some help on the following questions. These are in the "Notes" list on the relevant pages (Lead, Contact, Account, Opportunity). I went ahead and hide the old Notes and Attachments section, and added the Notes to the layout. They are stored as ContentDocument object.

I had a few questions:

  1. How can I ensure these notes are being associated to the Account/Contact during a lead conversion event. I see this happening sometimes but not others, in fact I can view the note browsed to via the Files section of a Chatter User page, that its associated to a Lead but when I click that lead it mentions "Lead Converted".

  2. How can I query these using SOQL?


When I go into Developer Console and execute these queries:

SELECT COUNT(Id) FROM ContentDocument -> yields 3

SELECT COUNT(Id) FROM ContentDocument WHERE Id != '069o0000000HQVm' > yields 3

SELECT COUNT(Id) FROM ContentDocument WHERE Id = '069o0000000HQVm' > yields 1

I think this is related to some type of permission issue. If I explicitly share a note via the UI with myself (I am a SysAdmin but not Note Creator) I can query the note via SOQL however if I don't have permission I can't. Perhaps the solution is to create a default sharing permission.

  • What Ids do you get back if you just do SELECT Id from ContentDocument? – Daniel Ballinger Nov 10 '15 at 21:02
  • The 3 Id that are from the first query. Not everything. – Brad Ruderman Nov 10 '15 at 21:34
  • So, you get 3 distinct Id's in a query against ContentDocument. Does that set include '069o0000000HQVm'? I.e. are they the same set of Id's when you use the != operator? Does '069o0000000HQVm' only come back if you explicitly search for it. – Daniel Ballinger Nov 10 '15 at 21:37
  • 1
    Correct Daniel 069o0000000HQVm only comes back if I explicitly search for it. The records returned without specifying a where clause are records that I only have explicit access to. Despite that I have access to everything when using the where clause. – Brad Ruderman Nov 10 '15 at 21:54
  • As a hunch, can you check the query execution plan for the query without a where clause? If the leading operation type is Sharing with the lowest cost then it will only bring back results based on the sharing rules. The explicit query with the Id would bypass that and bring back the actual record. – Daniel Ballinger Nov 10 '15 at 22:07
2

With regards to the SOQL query and accessing all the ContentDocument records.

As you found, if you run a SOQL query against all the ContentDocument records, you get 3 records back (in your example case). But if you make a SOQL query for an explicit ContentDocument ID that doesn't come back in the first set of results you can access a 4th record.

I believe the difference comes from the selected query execution plan applying the record sharing rules. When you do the SOQL query without the where clause the query plan with the lowest cost has the Sharing type. In the documentation this is described as:

The query will use an index based on the sharing rules associated with the user who is executing the query. If there are sharing rules that limit which records that user can access, Salesforce can use those rules to optimize the query.

So, if the sharing plan has the lowest cost it will be used, and will only return records that have been shared to the current user.

Have a look at Using the with sharing or without sharing Keywords. If you can run your SOQL query in a without sharing context the sharing plan shouldn't come into affect and restrict the records that are returned.

To get the same level of access via the API's you should alter the user permissions:

Sharing
For most API calls, data that is outside of the logged-in user’s sharing model is not returned. Users are granted the most permissive access that is available to them, either through organization-wide defaults or manual record sharing, just as in the application.

User Permissions that Override Sharing

  • View All—Users can view all records associated with this object, regardless of sharing settings.
  • Modify All—Users can read, edit, delete, transfer, and approve all records associated with this object, regardless of sharing settings.
  • Modify All Data—users can read, edit, delete, transfer, and approve all records regardless of sharing settings. This permission is not an object-level permission, unlike “View All” and “Modify All.”

To protect the security of your data, give the logged-in user only the permissions needed to successfully execute all the calls made by the application. For large integration applications, “Modify All Data” may speed up call response times.

  • Thanks for this summary, though the user I am using is a SysAdmin and has all permissions, and is sharing is still being applied when calling VIA the api. I think there is a bug or some other unexpected behavior happening. I wonder if this has something to do with the data being Chatter related and not standard objects. – Brad Ruderman Nov 12 '15 at 18:27
0

I know this is a old post, but still thought of sharing what I have learned about this whole new Notes of salesforce.

For records, this implementation is way complex than you think. Since it involves Content there is no straight forward way for a user with API access to access the Notes from the new ContentNote object. While querying ContentNote via API, the access is controlled by ContentDcoumentLink.

When you create a Note from the UI, you will see records in ContentDocument,ContentVersion,ContentNote and ContentDocumentLink. ContentDocument and ContentVersion are the 2 common objects used for any type of content in salesforce.The 2 objects to worry about are ContentNote and ContentDocumentLink.

If you want a user to access the contentNote record from API, then there needs to be a record in ContentDocumentLink for that ContentNote record with LinkedEntityId = User or Chatter Group Id ContentDocumentId = ContentNoteId with couple of other field information.

For other field details on ContentDocumentLink please refer to the documentation.

One more think, if you want give a group of users access to all the ContentNotes that are created, then you can write a trigger on ContentVersion to automatically create a record in ContentDocumentLink to share the contentNote with the chatter group. You cannot use the other normal group of salesforce.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.