├── images
├── Consent.PNG
├── IntegratorKey.PNG
└── DeveloperConsole.JPG
├── src
├── classes
│ ├── DocuSignJWT.cls-meta.xml
│ ├── DocuSignRESTUtility.cls-meta.xml
│ ├── DocuSignJWT.cls
│ └── DocuSignRESTUtility.cls
├── customMetadata
│ ├── DocuSignRESTSettings.DSUserName.md
│ ├── DocuSignRESTSettings.DSAccountID.md
│ ├── DocuSignRESTSettings.RequestAuthDomain.md
│ ├── DocuSignRESTSettings.RequestPrivateKey.md
│ ├── DocuSignRESTSettings.RequestScope.md
│ ├── DocuSignRESTSettings.CLMv2ApiEndpoint.md
│ ├── DocuSignRESTSettings.RequestIntegratorKey.md
│ ├── DocuSignRESTSettings.RequestAuthContentType.md
│ ├── DocuSignRESTSettings.RequestAuthEndpoint.md
│ └── DocuSignRESTSettings.RequestAuthBody.md
├── objects
│ └── DocuSignRESTSettings__mdt.object
├── package.xml
└── layouts
│ └── DocuSignRESTSettings__mdt-DocuSignRESTSettings Layout.layout
├── .gitignore
├── LICENSE
└── README.md
/images/Consent.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docusign/code-examples-clm-apex/master/images/Consent.PNG
--------------------------------------------------------------------------------
/images/IntegratorKey.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docusign/code-examples-clm-apex/master/images/IntegratorKey.PNG
--------------------------------------------------------------------------------
/images/DeveloperConsole.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docusign/code-examples-clm-apex/master/images/DeveloperConsole.JPG
--------------------------------------------------------------------------------
/src/classes/DocuSignJWT.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 42.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/classes/DocuSignRESTUtility.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 42.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.DSUserName.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | Replace with UserName
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.DSAccountID.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | Replace with DocuSign Account Id
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.RequestAuthDomain.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | account-d.docusign.com
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.RequestPrivateKey.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | Replace with Private Key
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.RequestScope.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | signature spring_read spring_write
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.CLMv2ApiEndpoint.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | https://apina11.springcm.com/v2/
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.RequestIntegratorKey.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | Replace with Integrator Key
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.RequestAuthContentType.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | application/x-www-form-urlencoded
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.RequestAuthEndpoint.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | https://account-d.docusign.com/oauth/token
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/customMetadata/DocuSignRESTSettings.RequestAuthBody.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 |
6 | Value__c
7 | grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # GitIgnore for Salesforce Projects
2 | # Project Settings and MetaData
3 | .project
4 | .settings/
5 | .metadata
6 | build.properties
7 | config
8 |
9 | # Apex Log as optional
10 | apex-scripts/log
11 |
12 | # Eclipse specific
13 | salesforce.schema
14 | Referenced Packages
15 | bin/
16 | tmp/
17 | config/
18 | *.tmp
19 | *.bak
20 | local.properties
21 | .settings
22 | .loadpath
23 | .classpath
24 | *.cache
25 |
26 | # Mavensmate
27 | *.sublime-project
28 | *.sublime-settings
29 | *.sublime-workspace
30 | mm.log
31 |
32 | # OSX-specific exclusions
33 | .[dD][sS]_[sS]tore
--------------------------------------------------------------------------------
/src/objects/DocuSignRESTSettings__mdt.object:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Value__c
5 | false
6 | SubscriberControlled
7 |
8 | 131072
9 | LongTextArea
10 | 3
11 |
12 |
13 | DocuSignRESTSettings
14 | Public
15 |
16 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2018- DocuSign, Inc. (https://www.docusign.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/src/package.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | DocuSignRESTUtility
5 | DocuSignJWT
6 | ApexClass
7 |
8 |
9 | DocuSignRESTSettings__mdt.Value__c
10 | CustomField
11 |
12 |
13 | DocuSignRESTSettings.DSAccountID
14 | DocuSignRESTSettings.DSUserName
15 | DocuSignRESTSettings.RequestAuthBody
16 | DocuSignRESTSettings.RequestAuthContentType
17 | DocuSignRESTSettings.RequestAuthDomain
18 | DocuSignRESTSettings.RequestAuthEndpoint
19 | DocuSignRESTSettings.RequestIntegratorKey
20 | DocuSignRESTSettings.RequestPrivateKey
21 | DocuSignRESTSettings.RequestScope
22 | DocuSignRESTSettings.CLMv2ApiEndpoint
23 | CustomMetadata
24 |
25 |
26 | DocuSignRESTSettings__mdt
27 | CustomObject
28 |
29 |
30 | DocuSignRESTSettings__mdt-DocuSignRESTSettings Layout
31 | Layout
32 |
33 | 42.0
34 |
35 |
--------------------------------------------------------------------------------
/src/layouts/DocuSignRESTSettings__mdt-DocuSignRESTSettings Layout.layout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | false
5 | false
6 | true
7 |
8 |
9 |
10 | Required
11 | MasterLabel
12 |
13 |
14 | Required
15 | DeveloperName
16 |
17 |
18 | Edit
19 | Value__c
20 |
21 |
22 |
23 |
24 | Edit
25 | IsProtected
26 |
27 |
28 | Required
29 | NamespacePrefix
30 |
31 |
32 |
33 |
34 |
35 | false
36 | false
37 | true
38 |
39 |
40 |
41 | Readonly
42 | CreatedById
43 |
44 |
45 |
46 |
47 | Readonly
48 | LastModifiedById
49 |
50 |
51 |
52 |
53 |
54 | false
55 | false
56 | false
57 |
58 |
59 |
60 | false
61 | false
62 | false
63 | false
64 | false
65 |
66 |
--------------------------------------------------------------------------------
/src/classes/DocuSignJWT.cls:
--------------------------------------------------------------------------------
1 | /* This class is responsible for constructing the JSON Web Token */
2 | /* JSON Web Token will be sent to the DocuSign Authentication service for getting an access token which will be used in subsequent DocuSign API Calls */
3 | /* Visit https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken for additional information on JSON Web token in DocuSign API */
4 |
5 |
6 | public class DocuSignJWT {
7 |
8 | public String alg {get;set;} //RS256 for DocuSign REST integration
9 | public String iss {get;set;} // Integrator key
10 | public String sub {get;set;} // DSFProUserName from the user record
11 | public String aud {get;set;} // Authentication domain
12 | public String scope {get;set;} // signature scope
13 | public String privateKey {get;set;} //Private key
14 | public String exp {get;set;}
15 | public String iat {get;set;}
16 | public Map claims {get;set;}
17 | public Integer validFor {get;set;}
18 | public String cert {get;set;}
19 | public static final String HS256 = 'HS256';
20 | public static final String RS256 = 'RS256';
21 | public static final String NONE = 'none';
22 | private static final String STRING_EMPTY = '';
23 |
24 |
25 | //Constructor
26 | public DocuSignJWT(String alg,String sub,String iss, String privateKey,String scope,String aud) {
27 | this.alg = alg;
28 | this.sub = sub;
29 | this.iss = iss;
30 | this.privateKey = privateKey;
31 | this.scope = scope;
32 | this.validFor = 300;
33 | this.aud = aud;
34 | }
35 |
36 | //Method which returns the JSON Web Token
37 | public String issue() {
38 | String jwt = STRING_EMPTY;
39 |
40 | //Construct the JSON Web Token Header
41 | JSONGenerator header = JSON.createGenerator(false);
42 | header.writeStartObject();
43 | header.writeStringField('alg', this.alg);
44 | header.writeStringField('typ','JWT'); // Set as JWT
45 | header.writeEndObject();
46 | String encodedHeader = base64URLencode(Blob.valueOf(header.getAsString()));
47 |
48 | //Construct the JSON Body
49 | JSONGenerator body = JSON.createGenerator(false);
50 | body.writeStartObject();
51 | body.writeStringField('iss', this.iss);
52 | body.writeStringField('sub', this.sub);
53 | body.writeStringField('aud', this.aud);
54 | Long rightNow = (dateTime.now().getTime()/1000)+1;
55 | body.writeNumberField('iat', rightNow);
56 | body.writeNumberField('exp', (rightNow + validFor));
57 | body.writeStringField('scope', this.scope);
58 | if (claims != null) {
59 | for (String claim : claims.keySet()) {
60 | body.writeStringField(claim, claims.get(claim));
61 | }
62 | }
63 | body.writeEndObject();
64 |
65 | //JSON Web Token in this stage = encodedHeader + . + encodedBody
66 | jwt = encodedHeader + '.' + base64URLencode(Blob.valueOf(body.getAsString()));
67 |
68 | //Sign with Private key to create the signature
69 | if (this.alg == HS256 ) {
70 | Blob key = EncodingUtil.base64Decode(privateKey);
71 | Blob signature = Crypto.generateMac('hmacSHA256',Blob.valueof(jwt),key);
72 | jwt += '.' + base64URLencode(signature);
73 | }
74 | else if (this.alg == RS256 ) {
75 | Blob signature = null;
76 | if (cert != null) {
77 | signature = Crypto.signWithCertificate('rsa-sha256', Blob.valueOf(jwt), cert);
78 | } else {
79 | Blob privateKeyBlob = EncodingUtil.base64Decode(privateKey);
80 | //construct the signature
81 | signature = Crypto.sign('rsa-sha256', Blob.valueOf(jwt), privateKeyBlob);
82 | }
83 | jwt += '.' + base64URLencode(signature);
84 | } else if ( this.alg == NONE ) {
85 | jwt += '.';
86 | }
87 | return jwt;
88 |
89 | }
90 |
91 | //Utility method for returning the base64URLEncoded string for the input string
92 | private String base64URLencode(Blob input){
93 | String output = STRING_EMPTY;
94 | if (input != null) {
95 | output = encodingUtil.base64Encode(input);
96 | output = output.replace('+', '-');
97 | output = output.replace('/', '_');
98 | while ( output.endsWith('=')){
99 | output = output.subString(0,output.length()-1);
100 | }
101 | }
102 | return output;
103 | }
104 |
105 | }
106 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # code-examples-clm-apex
2 |
3 | ## Introduction:
4 | This repository will aid end users in connecting to the CLM API from Salesforce using [Apex](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_intro_what_is_apex.htm) and The REST API.
5 | We will be using JWT Authentication for authenticating to DocuSign REST API's and then performing a folder search using the REST API. This recipe will serve as a building block for users to customize and apply their own strategies while interacting with CLM from Salesforce using Apex.
6 |
7 | ## Pre-requisites:
8 | - [Get a Salesforce Developer account](https://developer.salesforce.com/signup)
9 |
10 | - [Get a DocuSign Developer account](https://go.docusign.com/o/sandbox)
11 |
12 | ## Flow:
13 | - Set up your DocuSign Integration Key.
14 | - Find your DocuSign User ID and API Account ID.
15 | - Installing the Github source.
16 | - Set up Salesforce Custom Metadata.
17 | - Set up Salesforce Remote Sites.
18 | - Complete the Access Token Demo.
19 |
20 | ## Step-by-Step Walkthrough
21 |
22 | ### 1. Set up your DocuSign Integration key
23 | - Login to your DocuSign Developer Account and select **Admin**.
24 | - Under **Integrations**, select **API and Keys**.
25 | - Select **Add Integration Key**
26 | - Provide an **App Description** and select **Save**
27 | - Click on the newly created Integrator Key. From the window that appears, note down the **Integrator Key**. This will be a unique GUID which will be associated with your Integration Key. You'll need to add this value to Salesforce later.
28 | - Select **Add URI** and add 'https://localhost'.
29 | - Select **Add RSA Key Pair** and note down the Private Key.
30 | You'll need to add the Private Key to Salesforce later. **Do not copy the ----BEGIN RSA PRIVATE KEY---- and ----END RSA PRIVATE KEY---- lines**.
31 | Select OK.
32 | We have chosen to generate the RSA Key Pair since we will generating the JWT token to pass to the authentication key using the Private Key that we have noted down. This Private Key will be signed with the header and body of the request to complete the JWT token. Please see [JSON Web Token (JWT) Grant](https://developers.docusign.com/esign-rest-api/guides/authentication/oauth2-jsonwebtoken) for additional information on JWT and token construction.
33 |
34 |
35 | 
36 |
37 | #### Impersonating user for API calls
38 | Since our recipe will be using the Integration key to make CLM API calls, we must ensure that a DocuSign user provides consent to the Integrator Key performing actions on their behalf. In this case the DocuSign user will be our Developer account user. For service integrations, you can set up a service user and grant consent on this user's behalf.
39 |
40 | To complete this step open the following URI in a browser:
41 |
42 | `https://account-d.docusign.com/oauth/auth?response_type=code&scope=signature%20impersonation%20spring_read%20spring_write&client_id=YOUR_KEY&redirect_uri=https://localhost`
43 |
44 | Make sure that:
45 | - For the client_id, you substitute the correct Integration Key for YOUR_INTEGRATION_KEY.
46 | - The value for the redirect_uri parameter matches the redirect URI configured for the Integration Key in your DocuSign Developer Account.
47 |
48 | When you open the URL in your browser, a consent screen displays. Select **Accept**.
49 |
50 | 
51 |
52 | After clicking Accept you will be redirected to the redirect URI you specified, indicating that consent was successfully granted.
53 |
54 | ### 2. Find your DocuSign User ID and API AccountID.
55 | - Log in to your DocuSign Developer Account and select **Admin**.
56 | - Under **'Integrations'**, select **API and Keys**.
57 | - Note down the **User ID** and **API Account ID**. You'll need to add these to your Salesforce Custom Metadata.
58 |
59 | ### 3. Install the GitHub Source:
60 | Deploy the files under the **src** folder to your Salesforce org. The src folder contains the a package.xml file which will help you to deploy the src.
61 | You can use [Workbench](https://workbench.developerforce.com/login.php) for installation:
62 | - Zip all the files such that folders and xml file present under the **src** folder are at the root of the zip file.
63 | - Log in to Workbench
64 | - Select **Migration -> Deploy**
65 | - Select the zip file created in the earlier step. Check the **Single Package** checkbox and click on **Next**
66 | - Select Deploy
67 |
68 |
69 |
70 | ### 4. Set up Salesforce Custom Metadata:
71 | - Once the source files have been deployed successfully to your Salesforce org, navigate to **Setup -> Custom metadata types**.
72 | - Click **Manage Records** under **DocuSignRESTSettings**
73 | - Replace the values in the settings with the values for your DocuSign instance:
74 | - DSAccount -> Your DocuSign API AccountID.
75 | - DSUserName -> Your DocuSign User ID.
76 | - RequestIntegratorKey -> Your Integration Key Id.
77 | - RequestPrivateKey -> Your Private Key.
78 |
79 | ### 5. Set up Salesforce Remote Sites:
80 | - Add 'https://account-d.docusign.com' as a Remote Site URL in your Salesforce instance.
81 | - Add the appropriate CLM REST API URL as a Remote Site URL in your Salesforce instance. You can find this in CLM Admin in the **Integrations** section of the **System Domains** page, or by consulting this chart:
82 |
83 | | | **North America** | **Europe** |
84 | |----------------|---------------------------------|---------------------------------|
85 | | **Test** | https://apiuatna11.springcm.com | https://apiuateu11.springcm.com |
86 | | **Production** | https://apina11.springcm.com | https://apieu11.springcm.com |
87 |
88 |
89 | ### 6. Complete the Access Token Demo:
90 | - Open the Developer Console
91 | - Press **CTRL + E** (open execute Anonymous code window)
92 | - Add the following line of code :
93 | `DocuSignRESTUtility.getAccessToken();`
94 | - Highlight the added line of code and press **Execute Highlighted**
95 | - Navigate to the generated log file and choose the *Debug Only* level to monitor the logs generated.
96 | - If the integration and setup are successfull you will notice a Status Code of 200 and the **ResponseAuthBody** parameter will also contain the `access_token`
97 |
98 | 
99 |
100 | ### 7. Search CLM for a folder using Apex:
101 | - Open the Developer Console
102 | - Press CTRL + E (open execute Anonymous code window)
103 | - Add the following line of code:
104 | `DocuSignRESTUtility.searchForFolder('SEARCH_QUERY');`
105 | - Highlight the added line of code and press **Execute Highlighted**
106 |
107 | This example should search your CLM instance for folders matching the search query.
108 |
109 | ## License
110 |
111 | The DocuSign CLM Apex code examples are licensed under the following [License](LICENSE).
112 |
--------------------------------------------------------------------------------
/src/classes/DocuSignRESTUtility.cls:
--------------------------------------------------------------------------------
1 | /* This class is responsible for searching for folders by making REST Callouts to DocuSign CLM */
2 | /* You can extend the searchForFolder method by invoking it from triggers / scheduled apex / batch jobs */
3 | /* You can also create invocable actions by referencing the searchForFolder method and use it in Process Builders */
4 |
5 | public class DocuSignRESTUtility {
6 |
7 | //Get Rest Configuration Setings from Custom Metadata provided as a part of the installation source
8 | private static Map settingsMap {
9 | //Getter Method
10 | get {
11 | //populate only if settingsMap is null
12 | if (settingsMap == null) {
13 | settingsMap = new Map();
14 | //Query the Custom Metadata and add it to the Map
15 | //Query against Custom Metadata does not count against the SOQL query Limit
16 | for (DocuSignRESTSettings__mdt setting : [Select DeveloperName,MasterLabel, Value__c from DocuSignRESTSettings__mdt]) {
17 | settingsMap.put(setting.MasterLabel, setting);
18 | }
19 | }
20 | return settingsMap;
21 | }
22 | //Blank Setter Method
23 | set {
24 | }
25 | }
26 |
27 | //This method will call the DocuSignJWT class to obtain an access token from DocuSign
28 | public static String getAccessToken() {
29 | String access_token = null;
30 |
31 | //Instantiate a request object
32 | HttpRequest req = new HttpRequest();
33 | //set the request METHOD
34 | req.setMethod('POST');
35 |
36 | //set the request endpoint
37 | String authendpoint = settingsMap.get('RequestAuthEndpoint').Value__c;
38 | System.Debug(LoggingLevel.INFO, '**RequestAuthEndpoint' + authendpoint);
39 | req.setEndPoint(authendpoint);
40 |
41 | //set the request headers
42 | //1. Content -type
43 | String authRequestContentType = settingsMap.get('RequestAuthContentType').Value__c;
44 | System.Debug(LoggingLevel.INFO, '**authRequestContentType ' + authRequestContentType);
45 | req.setHeader('Content-type', authRequestContentType);
46 |
47 | //2. Host
48 | String authRequestDomain = settingsMap.get('RequestAuthDomain').Value__c;
49 | System.Debug(LoggingLevel.INFO, '**authRequestDomain ' + authRequestDomain);
50 | req.setHeader('Host', authRequestDomain);
51 |
52 | //Body of the request
53 | String alg = 'RS256';
54 | String iss = settingsMap.get('RequestIntegratorKey').Value__c;
55 | String pkey = settingsMap.get('RequestPrivateKey').Value__c;
56 | String scope = settingsMap.get('RequestScope').Value__c;
57 | DocuSignJWT jwtObject = new DocuSignJWT(alg, settingsMap.get('DSUserName').Value__c, iss, pkey, scope, authRequestDomain);
58 |
59 | //Set the request body
60 | String requestBody = settingsMap.get('RequestAuthBody').Value__c + jwtObject .issue();
61 | System.Debug(LoggingLevel.INFO, '**RequestAuthBody' + requestBody);
62 | req.setBody(requestBody);
63 |
64 | //call the service
65 | Http http = new Http();
66 | HTTPResponse res = http.send(req);
67 |
68 | System.Debug(LoggingLevel.INFO, '**ResponseAuthBody' + res.getbody());
69 | System.Debug(LoggingLevel.INFO, '**ResponseAuth' + res);
70 |
71 | //Obtain the access token from the Response
72 | if (res.getStatusCode() == 200) {
73 | System.JSONParser parser = System.JSON.createParser(res.getBody());
74 | while (parser.nextToken() != null) {
75 | if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) && (parser.getText() == 'access_token')) {
76 | parser.nextToken();
77 | access_token = parser.getText();
78 | break;
79 | }
80 | }
81 | }
82 |
83 | return access_token;
84 |
85 | }
86 |
87 | @future(callout=true)
88 | public static void searchForFolder(string query) {
89 | //Get the access token
90 | String accessToken = getAccessToken();
91 | System.Debug(LoggingLevel.INFO, '***accessToken ' + accessToken);
92 |
93 | //Call CLM API if a non-empty access token is returned
94 | if (!String.isEmpty(accessToken)) {
95 | //instantiate an Http instance
96 | Http httpProtocol = new Http();
97 |
98 | //instantiate an HttpRequest instance
99 | HttpRequest request = new HttpRequest();
100 |
101 | //Set the request parameters
102 | // Request endpoint for folder search call
103 | String endpoint = settingsMap.get('CLMv2ApiEndpoint').Value__c + settingsMap.get('DSAccountID').Value__c + '/folders/search?search=' + query;
104 | System.Debug(LoggingLevel.INFO, '***endpoint ' + endpoint);
105 | request.setEndPoint(endpoint);
106 |
107 | //set the POST method
108 | request.setMethod('POST');
109 |
110 | //set Authentication Header
111 | request.setHeader('grant_type', 'Bearer');
112 | request.setHeader('Authorization', 'Bearer ' + accessToken);
113 |
114 | //set Accept Header
115 | request.setHeader('Accept', 'application/json');
116 |
117 | //set Content Type Header
118 | request.setHeader('Content-type', 'application/json');
119 |
120 | //set Empty Body - Check out https://developers.docusign.com/docs/clm-api/reference/Objects/Folders/Search/ for more details if required
121 | request.setBody('');
122 |
123 | //Make the request and capture the response
124 | HttpResponse response = httpProtocol.send(request);
125 | System.Debug(LoggingLevel.INFO, '***response.getBody() ' + response.getBody());
126 | System.debug(LoggingLevel.INFO, '***response.getStatus() ' + response.getStatus());
127 |
128 | //Parse the response
129 | String responseStatus = response.getStatus();
130 | if (responseStatus.equals('Created')) {
131 | DocuSignRESTUtility.FolderSearchResponse responseObject = new DocuSignRESTUtility.FolderSearchResponse();
132 | responseObject = (DocuSignRESTUtility.FolderSearchResponse)System.JSON.deserialize(response.getBody(), DocuSignRESTUtility.FolderSearchResponse.class);
133 | System.Debug(LoggingLevel.INFO, '***responseObject ' + responseObject);
134 | }
135 | }
136 | }
137 |
138 | //wrapper class for Folder Search Response
139 | public class FolderSearchResponse
140 | {
141 | public FolderItem[] Items { get; set; }
142 | public String Href { get; set; }
143 | public long Offset { get; set; }
144 | public String First { get; set; }
145 | public String Last { get; set; }
146 | public long Total { get; set; }
147 | }
148 |
149 | public class FolderItem
150 | {
151 | public String Name { get; set; }
152 | public DateTime CreatedDate { get; set; }
153 | public String CreatedBy { get; set; }
154 | public DateTime UpdatedDate { get; set; }
155 | public String UpdatedBy { get; set; }
156 | public String Description { get; set; }
157 | public Documents ParentFolder { get; set; }
158 | public String BrowseDocumentsUrl { get; set; }
159 | public AccessLevel AccessLevel { get; set; }
160 | public Documents Documents { get; set; }
161 | public Documents Folders { get; set; }
162 | public Documents ShareLinks { get; set; }
163 | public String CreateDocumentHref { get; set; }
164 | public String Href { get; set; }
165 | }
166 |
167 | public class AccessLevel
168 | {
169 | public boolean See { get; set; }
170 | public boolean Read { get; set; }
171 | public boolean Write { get; set; }
172 | public boolean Move { get; set; }
173 | public boolean Create { get; set; }
174 | public boolean SetAccess { get; set; }
175 | }
176 |
177 | public class Documents
178 | {
179 | public String Href { get; set; }
180 | }
181 |
182 | }
183 |
--------------------------------------------------------------------------------