Search code examples
csvsalesforceapex-data-loader

Mass Upload Files To Specific Contacts Salesforce


I need to upload some 2000 documents to specific users in salesforce. I have a csv file that has the Salesforce-assigned ContactID, as well as a direct path to the files on my desktop. Each contact's specific file url has been included in the csv. How can I upload them all at one and, especially, to the correct contact?


Solution

  • You indicated in the comments / chat that you want it as "Files".

    The "Files" object is bit more complex than Attachments, you'll need to do it in 2-3 steps. What you see as a File (you might see it referred to in documentation as Chatter Files or Salesforce Content) is actually several tables. There's

    • ContentDocument which can be kind of a file header (title, description, language, tags, linkage to many other areas in SF - because it can be standalone, it can be uploaded to certain SF Content Library, it can be linked to Accounts, Contacts, $_GOD knows what else)
    • ContentVersion which is well, actual payload. Only most recent version is displayed out of the box but if you really want you can go back in time
    • and more

    The crap part is that you can't insert ContentDocument directly (there's no create() call in the list of operations) .


    Theory

    So you'll need:

    1. Insert ContentVersion (v1 will automatically create for you parent ContentDocuments... it does sound bit ass-backwards but it works). After this is done you'll have a bunch of standalone documents loaded but not linked to any Contacts
    2. Learn the Ids of their parent ContentDocuments
    3. Insert ContentDocumentLink records that will connect Contacts and their PDFs

    Practice

    This is my C:\stacktest folder. It contains some SF cheat sheet PDFs.

    enter image description here

    Here's my file for part 1 of the load

    Title   PathOnClient    VersionData
    "Lightning Components CheatSheet"   "C:\stacktest\SF_LightningComponents_cheatsheet_web.pdf"    "C:\stacktest\SF_LightningComponents_cheatsheet_web.pdf"
    "Process Automation CheatSheet" "C:\stacktest\SF_Process_Automation_cheatsheet_web.pdf" "C:\stacktest\SF_Process_Automation_cheatsheet_web.pdf"
    "Admin CheatSheet"  "C:\stacktest\SF_S1-Admin_cheatsheet_web.pdf"   "C:\stacktest\SF_S1-Admin_cheatsheet_web.pdf"
    "S1 CheatSheet" "C:\stacktest\SF_S1-Developer_cheatsheet_web.pdf"   "C:\stacktest\SF_S1-Developer_cheatsheet_web.pdf"
    

    Fire Data Loader, select Insert, select showing all Salesforce objects. Find ContentVersion. Load should be straightforward (if you're hitting memory issues set batch size to something low, even 1 record at a time if really needed).

    You'll get back a "success file", it's useless. We don't need the Ids of generated content versions, we need their parents... Fire "Export" in Data Loader, pick all objects again, pick ContentDocument. Use query similar to this:

    Select Id, Title, FileType, FileExtension
    FROM ContentDocument
    WHERE CreatedDate = TODAY AND CreatedBy.FirstName = 'Ethan'
    

    You should see something like this:

    "ID","TITLE","FILETYPE","FILEEXTENSION"
    "0690g0000048G2MAAU","Lightning Components CheatSheet","PDF","pdf"
    "0690g0000048G2NAAU","Process Automation CheatSheet","PDF","pdf"
    "0690g0000048G2OAAU","Admin CheatSheet","PDF","pdf"
    "0690g0000048G2PAAU","S1 CheatSheet","PDF","pdf"
    

    Use Excel and magic of VLOOKUP or other things like that to link them back by title to Contacts. You wrote you already have a file with Contact Ids and titles so there's hope... Create a file like that:

    ContentDocumentId   LinkedEntityId  ShareType   Visibility 
    0690g0000048G2MAAU  0037000000TWREI V   InternalUsers
    0690g0000048G2NAAU  0030g000027rQ3z V   InternalUsers
    0690g0000048G2OAAU  0030g000027rQ3a V   InternalUsers
    0690g0000048G2PAAU  0030g000027rPz4 V   InternalUsers
    

    1st column is the file Id, then contact Id, then some black magic you can read about & change if needed in ContentDocumentLink docs.

    Load it as insert to (again, show all objects) ContentDocumentLink.

    Woohoo! Beer time.

    enter image description here

    enter image description here