function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Jon SJon S 

Apex add file as attachment

Hi all,

I'm not very knowledgable in apex but I'm learning. I have a form that feeds information into salesforce and creates the Account object when submitted. When a person fills out the form and is required to upload a document, the form outputs a url of that document which populates a URL field in salesforce.

My goal is to save the uploaded documents as an attachment to the newly created Account object.

My issue is that I do not know (if there is way) how to somehow download that file from the form's output URL and save the actual document as the attachment for the Account object.

Also if there if anybody has suggestions on on re-writting the code in a better way, that'd be much aprreciated.

Thanks!

Apex Class:
public with sharing class CreateFileFromAcc {
    public void createFiles (List<Account> accsFromTrigger){ 
       
//The 4 custom fields output URLs
//Signed_EFT__c
//Uploaded_W_9_W_8__c
//COI_TEXT__c
//Signed_MSA__c

       	for(Account currentAccount : accsFromTrigger)    
        {
        Blob txtEft = Blob.valueOf(currentAccount.Signed_EFT__c);
        Attachment attach = new Attachment();
        attach.ParentId = currentAccount.Id;
        attach.Name = currentAccount.EFT_Name__c;
        attach.Body = txtEft;
        insert attach;
        }
        for(Account currentAccount : accsFromTrigger)    
        {
        Blob txtW9 = Blob.valueOf(currentAccount.Uploaded_W_9_W_8__c);
        Attachment attach = new Attachment();
        attach.ParentId = currentAccount.Id;
        attach.Name = currentAccount.W9_Name__c;
        attach.Body = txtW9;        
        insert attach;
        }
   		for(Account currentAccount : accsFromTrigger)    
        {
        Blob txtCoi = Blob.valueOf(currentAccount.COI_TEXT__c);
        Attachment attach = new Attachment();
        attach.ParentId = currentAccount.Id;
        attach.Name = currentAccount.COI_Name__c;
        attach.Body = txtCoi;
        attach.ContentType = currentAccount.COI_TEXT__c;        
        insert attach;
        }
        for(Account currentAccount : accsFromTrigger)    
        {
        Blob txtMsa = Blob.valueOf(currentAccount.Signed_MSA__c);
        Attachment attach = new Attachment();
        attach.ParentId = currentAccount.Id;
        attach.Name = currentAccount.MSA_Name__c;
        attach.Body = txtMsa;        
        insert attach;
        }
    }
}
Apex Trigger:
trigger CreateAccFile on Account (after insert)
{
	for (Account ac : Trigger.New)
	{
		if (ac.RecordTypeId == 'Test')//ACCOUNT RECORDTYPE
		{
	    CreateFileFromAcc cc = new CreateFileFromAcc();
	    cc.createFiles (Trigger.new);
		}
	    else
	    {
	    	createFileFromAcc cc = NULL;
	    }
	} 
}

 
pconpcon
To reiterate what you're asking, you have a form that saves the files externally.  Then it includes a link to those files in your newly created account record.  You want to then convert the file at that URL into a Salesforce attachment?

If that's correct, then you will need to make a callout against those endpoints and download the data there.  Then create the attachment in your callout.  Since this is going to be part of a trigger, you will need to make that callout as part of an @Future method.  For more information on making the callout, I recommend you look over this trailhead [1].

If this is incorrect, please let me know what I got wrong.

[1] https://developer.salesforce.com/trailhead/module/apex_integration_services
Jon SJon S
Hey pcon! Thanks for replying and yes your statement is correct. I am unfamiliar with the @Future method, if you have another reference to this that would be great. I will go through the trailhead you posted and I'll also research more about @Future.
pconpcon
You'll want to do a HTTP Callout [1] [2] and since they are not allowed inside a trigger you'll have to do that with an @Future(callout = true) [3].  That trailhead should be a good place to start, then this trailhead on async apex (specifically the "using future methods" module) would be a good place to start.

[1] https://developer.salesforce.com/page/Apex_Web_Services_and_Callouts
[2] https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_callouts_http.htm
[3] https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_future.htm
[4] https://developer.salesforce.com/trailhead/module/asynchronous_apex