5

I am getting an attachment via a Salesforce email service and in the Email service apex class logic, I query the user object by the email from address and set the ContentVersion owner as the user coming from the Query.

I am getting this error while performing this operation.

INVALID_STATUS, Documents in a user's private library must always be owned by that user.: [OwnerId]

Here is my code :

global Messaging.InboundEmailResult handleInboundEmail(Messaging.InboundEmail email, Messaging.InboundEnvelope envelope) {

        Messaging.InboundEmailResult result = new Messaging.InboundEmailresult();

        //Get users for the incoming email address and also community user
        List<User> lstUsersFromCommunity = [SELECT Id 
                                            FROM User 
                                            WHERE Profile.UserLicense.Name = 'Partner Community';
                                            AND Email =: email.fromAddress];

        //Process only if the incoming email address is belongs to a valid community user
        if(lstUsersFromCommunity.size() > 0){
            //Get the user from the results list
            User user = lstUsersFromCommunity.get(0);
            try{
                //Create a list of ContentVersion to store new ContentVersion records
                List<ContentVersion> lstVersion = new List<ContentVersion>(); 
                //Iterate over the incoming email attachments
                for (Messaging.Inboundemail.BinaryAttachment binaryAttachment : email.binaryAttachments) {
                    //New ContentVersion record
                    ContentVersion newContentVersion = new ContentVersion();
                    newContentVersion.versionData = binaryAttachment.body;
                    newContentVersion.OwnerId = user.Id;
                    newContentVersion.ContentLocation = 'S';
                    newContentVersion.SharingOption = 'A';
                    newContentVersion.Origin = 'H';
                    newContentVersion.title = email.subject;
                    newContentVersion.pathOnClient = binaryAttachment.fileName;
                    lstVersion.Add(newContentVersion);
                }
                insert lstVersion;
            }catch(Exception ex){
                System.debug('### EXCEPTION :  ' + ex.getLineNumber() + ' : ' + ex.getMessage());
            }
        }else{
            //No user in for the from email address
        }

        return result;
    }
1

2 Answers 2

10

Add this line:

newContentVersion.firstPublishLocationId= user.Id;

A more detailed explanation:

When documents are created via apex (contentversion object), you need to specify the library otherwise they will always be created in private library of the context user. Since you are querying a random user (and probably this user is not the context user of running code), your code tries to create document in context users private library but owner is coming from your user query.

To better understand the data model of contents, create a library in your org and upload a file by using user interface. (file will be uploaded to your private library). Then publish it to library you created. When you check the data model you will see 4 important objects

  • ContentVersion (version of your document)
  • ContentDocument (actual record of document it has a link to latest version) (created automatically when you insert contentversion)
  • ContentWorkspace (Libraries)
  • ContentWorkspaceDoc (Junction between libraries and ContentDocument) (created when you publish your content to a library)

So as you can see, Contentdocument is your actual record, you can have multiple versions linked to contentdocument(contentversion - in your code you create only first version). Contentdocument also is your relation to libraries behind the scene. last but not least, on contenversion object there is a firstpublishlocationID (this field can be filled with multiple objects including libraries(contentworkspace) and users).

1
  • 1
    Hi @oozkan Thanks for the Answer, I am getting this error any idea?: System.DmlException: Insert failed. First exception on row 0; first error: INVALID_ID_FIELD, You must specify a FirstPublishLocation where you have publish permission.: [FirstPublishLocationId] Commented May 7, 2018 at 10:01
4

I found from document :

FirstPublishLocationId is id of the location where the version was first published. If the version is first published into a user's personal library or My Files, the field will contain the ID of the user who owns the personal library or My Files. In Lightning Experience, if the first version is published into a public library, the field will contain the ID of that library. Accepts all record IDs supported by ContentDocumentLink (anything a file can be attached to, like records and groups). Setting FirstPublishLocationId allows you to create a file and share it with an initial record/group in a single transaction, and have the option to create more links to share the file with other records or groups later. When a file is created, it’s automatically linked to the record, and PublishStatus will change to Public from Pending/Personal. This field is only set the first time a version is published via the API. FirstPublishLocationId can’t be set to another ID when a new content version is inserted.

In my case, I set FirstPublishLocationId = userinfo.getUserId() instead of another content version ownerid, and error disappears.

1
  • I was able to use a lead id and it works Commented Aug 30, 2022 at 22:20

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .