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
Board salesforceBoard salesforce 

Box.com Integration with Trigger

Hi Techie's,
Please help me out
here the scenario when i insert a account record with name 'Test A' and the folder sholud be created with the 'Test A' in Box.com
As Box Supports OAUTH Authentication it is having with conflict with writing trigger ..can any one help on this 

Thanks ,
Ram
Best Answer chosen by Board salesforce
pconpcon
Answering this question here as well to cover better for search results.

To do this you will need to create a Custom Setting that stores your credentials (called BoxCCredentials in the code below) as well as a Visualforce page that is accessible only to the administrator.  This will create your access token and store it in the custom setting.
 
<apex:page controller="BoxController" action="{!redirectOnCallback}">
    <apex:outputPanel rendered="{!NOT(hasToken)}"><a href='{!authUrl}'>Login</a></apex:outputPanel>
    <apex:outputPanel rendered="{!hasToken}">Already has token</apex:outputPanel>
</apex:page>
BoxLogin.vfp
 
public class BoxController {
    @TestVisible private static String SETTING_NAME = 'CredentialsBox';
    @TestVisible private static String ACCESS_TOKEN_URL = 'https://api.box.com/oauth2/token';
    @TestVisible private static String AUTHORIZE_URL = 'https://api.box.com/oauth2/authorize';
    @TestVisible private static String FOLDER_URL = 'https://api.box.com/2.0/folders';

    @TestVisible private String access_token;
    @TestVisible private Boolean isCallback;
    
    /** The JSON result from a successful oauth call */
    public class OAuthResult {
        /** The access token */
        public String access_token {get; set;}
        
        /** The refresh token */
        public String refresh_token {get; set;}
    }
    
    /**
	* Validates the oauth code
	*
	* @param code The code to validate
	* @param redirect_uri The URL to redirect to after successful validation
	* @return The oauth result
	*/
	public static OAuthResult validateCode(String code, String redirect_uri) {
        String client_id = BoxCCredentials__c.getValues(SETTING_NAME).Client_Id__c;
        String client_secret = BoxCCredentials__c.getValues(SETTING_NAME).Client_Secret__c;

		List<String> urlParams = new List<String> {
			'grant_type=authorization_code',
			'code=' + EncodingUtil.urlEncode(code, 'UTF-8'),
			'client_id=' + EncodingUtil.urlEncode(client_id, 'UTF-8'),
			'client_secret=' + EncodingUtil.urlEncode(client_secret, 'UTF-8'),
			'redirect_uri=' + EncodingUtil.urlEncode(redirect_uri, 'UTF-8')
		};

		Http h = new Http();

		HttpRequest req = new HttpRequest();
		req.setEndpoint(ACCESS_TOKEN_URL);
		req.setMethod('POST');
		req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
		req.setHeader('Accept', 'application/json');
		String body = String.join(urlParams, '&');
		req.setBody(body);

		HttpResponse res = h.send(req);
		return (OAuthResult)(JSON.deserialize(res.getBody(), OAuthResult.class));
	}

    /**
    * Generic constructor
    */
    public BoxController() {
       this.isCallback = ApexPages.currentPage().getParameters().containsKey('code');

        if (BoxCCredentials__c.getValues(SETTING_NAME) != null) {
            this.access_token = BoxCCredentials__c.getValues(SETTING_NAME).Access_Token__c;
        }
    }

    /**
	* Gets the authroization URL
	*
	* @return The authorization url
	*/
    public String getAuthUrl() {
        Map<String, String> urlParams = new Map<String, String> {
			'client_id' => BoxCCredentials__c.getValues(SETTING_NAME).Client_Id__c,
			'redirect_uri' => getPageUrl(),
			'response_type' => 'code'
		};

		PageReference ref = new PageReference(AUTHORIZE_URL);
		ref.getParameters().putAll(urlParams);

		return ref.getUrl();
    }
    
    /**
    * Gets the page url
    * 
    * @return The page url
    */
    @testVisible
    private String getPageUrl() {
        String host = ApexPages.currentPage().getHeaders().get('Host');
        String path = ApexPages.currentPage().getUrl().split('\\?').get(0);
        
        return 'https://' + host + path;
    }
    
    /**
    * If the access token is set
    * 
    * @return If the access token is set
    */
    public Boolean getHasToken() {
        return (this.access_token != null);
    }
    
    /**
    * Validates the callback code and generates the access and refresh tokens
    * 
    * @return null to refresh the page
    */
    public PageReference redirectOnCallback() {
        if (this.isCallback) {
            String code = ApexPages.currentPage().getParameters().get('code');
            OAuthResult result = validateCode(code, this.getPageUrl());
            System.debug(result);
            
            BoxCCredentials__c creds = BoxCCredentials__c.getValues(SETTING_NAME);
            creds.Access_Token__c = result.access_token;
            creds.Refresh_Token__c = result.refresh_token;
            update creds;
        }
        
        return null;
    }
    
    private class ParentFolder {
        public String id;
        
        public ParentFolder(String id) {
            this.id = id;
        }
    }
    
    private class Folder {
        public String name;
        ParentFolder parent;
        
        public Folder(String name, String parentId) {
            this.name = name;
            this.parent = new ParentFolder(parentId);
        }
    }
    
    /**
    * Static method to create the folder inside of the box account
    * 
    * @param accountId The account id to create the folder for
    */
    @Future(callout = true)
    public static void createFolder(Id accountId) {
        if (BoxCCredentials__c.getValues(SETTING_NAME) == null) {
            return;
        }

        String access_token = BoxCCredentials__c.getValues(SETTING_NAME).Access_Token__c;
        Folder folder_info = new Folder(accountId, '0');
        
        HttpRequest request=new HttpRequest();
        request.setEndpoint(FOLDER_URL); 
        request.setMethod('POST');
        request.setHeader('Authorization', 'Bearer ' + access_token);
        String body = JSON.serialize(folder_info);
        System.debug(body);
        request.setBody(body);
        
        Http p = new Http();
        HttpResponse response = p.send(request);
    }
}
BoxController.cls
 
trigger BoxInsert on Account (after insert) {
    for (Account a : Trigger.new) {
        BoxController.createFolder(a.Id);
    }
}
BoxInsert.trigger
  1. Save these files
  2. Add api.box.com to your Remote Site Settings
  3. Goto /apex/BoxLogin
  4. Click Login
  5. You should see "Already has token" (It might refresh the page and Login still shows up.  If that happens just refresh the page)
  6. Insert an account
  7. View that folder has been created in your box.com account
After this, every time you insert an account, it will pull the access_token from the custom setting.  What this does not cover is how to regenerate the access_token with the refresh_token.  I'll leave that up to you.  Worst case, you delete the Access_Token__c from your credentials custom setting and then revisit the BoxLogin page to generate a new one.

 

All Answers

pconpcon
Answering this question here as well to cover better for search results.

To do this you will need to create a Custom Setting that stores your credentials (called BoxCCredentials in the code below) as well as a Visualforce page that is accessible only to the administrator.  This will create your access token and store it in the custom setting.
 
<apex:page controller="BoxController" action="{!redirectOnCallback}">
    <apex:outputPanel rendered="{!NOT(hasToken)}"><a href='{!authUrl}'>Login</a></apex:outputPanel>
    <apex:outputPanel rendered="{!hasToken}">Already has token</apex:outputPanel>
</apex:page>
BoxLogin.vfp
 
public class BoxController {
    @TestVisible private static String SETTING_NAME = 'CredentialsBox';
    @TestVisible private static String ACCESS_TOKEN_URL = 'https://api.box.com/oauth2/token';
    @TestVisible private static String AUTHORIZE_URL = 'https://api.box.com/oauth2/authorize';
    @TestVisible private static String FOLDER_URL = 'https://api.box.com/2.0/folders';

    @TestVisible private String access_token;
    @TestVisible private Boolean isCallback;
    
    /** The JSON result from a successful oauth call */
    public class OAuthResult {
        /** The access token */
        public String access_token {get; set;}
        
        /** The refresh token */
        public String refresh_token {get; set;}
    }
    
    /**
	* Validates the oauth code
	*
	* @param code The code to validate
	* @param redirect_uri The URL to redirect to after successful validation
	* @return The oauth result
	*/
	public static OAuthResult validateCode(String code, String redirect_uri) {
        String client_id = BoxCCredentials__c.getValues(SETTING_NAME).Client_Id__c;
        String client_secret = BoxCCredentials__c.getValues(SETTING_NAME).Client_Secret__c;

		List<String> urlParams = new List<String> {
			'grant_type=authorization_code',
			'code=' + EncodingUtil.urlEncode(code, 'UTF-8'),
			'client_id=' + EncodingUtil.urlEncode(client_id, 'UTF-8'),
			'client_secret=' + EncodingUtil.urlEncode(client_secret, 'UTF-8'),
			'redirect_uri=' + EncodingUtil.urlEncode(redirect_uri, 'UTF-8')
		};

		Http h = new Http();

		HttpRequest req = new HttpRequest();
		req.setEndpoint(ACCESS_TOKEN_URL);
		req.setMethod('POST');
		req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
		req.setHeader('Accept', 'application/json');
		String body = String.join(urlParams, '&');
		req.setBody(body);

		HttpResponse res = h.send(req);
		return (OAuthResult)(JSON.deserialize(res.getBody(), OAuthResult.class));
	}

    /**
    * Generic constructor
    */
    public BoxController() {
       this.isCallback = ApexPages.currentPage().getParameters().containsKey('code');

        if (BoxCCredentials__c.getValues(SETTING_NAME) != null) {
            this.access_token = BoxCCredentials__c.getValues(SETTING_NAME).Access_Token__c;
        }
    }

    /**
	* Gets the authroization URL
	*
	* @return The authorization url
	*/
    public String getAuthUrl() {
        Map<String, String> urlParams = new Map<String, String> {
			'client_id' => BoxCCredentials__c.getValues(SETTING_NAME).Client_Id__c,
			'redirect_uri' => getPageUrl(),
			'response_type' => 'code'
		};

		PageReference ref = new PageReference(AUTHORIZE_URL);
		ref.getParameters().putAll(urlParams);

		return ref.getUrl();
    }
    
    /**
    * Gets the page url
    * 
    * @return The page url
    */
    @testVisible
    private String getPageUrl() {
        String host = ApexPages.currentPage().getHeaders().get('Host');
        String path = ApexPages.currentPage().getUrl().split('\\?').get(0);
        
        return 'https://' + host + path;
    }
    
    /**
    * If the access token is set
    * 
    * @return If the access token is set
    */
    public Boolean getHasToken() {
        return (this.access_token != null);
    }
    
    /**
    * Validates the callback code and generates the access and refresh tokens
    * 
    * @return null to refresh the page
    */
    public PageReference redirectOnCallback() {
        if (this.isCallback) {
            String code = ApexPages.currentPage().getParameters().get('code');
            OAuthResult result = validateCode(code, this.getPageUrl());
            System.debug(result);
            
            BoxCCredentials__c creds = BoxCCredentials__c.getValues(SETTING_NAME);
            creds.Access_Token__c = result.access_token;
            creds.Refresh_Token__c = result.refresh_token;
            update creds;
        }
        
        return null;
    }
    
    private class ParentFolder {
        public String id;
        
        public ParentFolder(String id) {
            this.id = id;
        }
    }
    
    private class Folder {
        public String name;
        ParentFolder parent;
        
        public Folder(String name, String parentId) {
            this.name = name;
            this.parent = new ParentFolder(parentId);
        }
    }
    
    /**
    * Static method to create the folder inside of the box account
    * 
    * @param accountId The account id to create the folder for
    */
    @Future(callout = true)
    public static void createFolder(Id accountId) {
        if (BoxCCredentials__c.getValues(SETTING_NAME) == null) {
            return;
        }

        String access_token = BoxCCredentials__c.getValues(SETTING_NAME).Access_Token__c;
        Folder folder_info = new Folder(accountId, '0');
        
        HttpRequest request=new HttpRequest();
        request.setEndpoint(FOLDER_URL); 
        request.setMethod('POST');
        request.setHeader('Authorization', 'Bearer ' + access_token);
        String body = JSON.serialize(folder_info);
        System.debug(body);
        request.setBody(body);
        
        Http p = new Http();
        HttpResponse response = p.send(request);
    }
}
BoxController.cls
 
trigger BoxInsert on Account (after insert) {
    for (Account a : Trigger.new) {
        BoxController.createFolder(a.Id);
    }
}
BoxInsert.trigger
  1. Save these files
  2. Add api.box.com to your Remote Site Settings
  3. Goto /apex/BoxLogin
  4. Click Login
  5. You should see "Already has token" (It might refresh the page and Login still shows up.  If that happens just refresh the page)
  6. Insert an account
  7. View that folder has been created in your box.com account
After this, every time you insert an account, it will pull the access_token from the custom setting.  What this does not cover is how to regenerate the access_token with the refresh_token.  I'll leave that up to you.  Worst case, you delete the Access_Token__c from your credentials custom setting and then revisit the BoxLogin page to generate a new one.

 
This was selected as the best answer
subbu naraharisettysubbu naraharisetty
hi pcon,
             i am doing this in lightning web component . how can i get code which u r passing as paramter in validateAouthcode method highlighted below.

public static OAuthResult validateCode(String code, String redirect_uri) {
pconpcon
Given how old this answer is, there have been things that have changed in the meantime.  I would currently suggest looking into using Named Credentials (https://help.salesforce.com/articleView?id=named_credentials_about.htm&type=5) instead and use the oAuth flow built into that.  But if you insist on using this via a LWC, you would need to mark this as @AuraEnabled and call it with the correct @wire as seen in this article (http://amitsalesforce.blogspot.com/2018/12/Invoke-Apex-Controller-from-Lightning-Web-Component.html) under "Apex Wire Method to Function with Parameters"