├── demo_documents
└── World_Wide_Corp_salary.docx
├── .vscode
├── settings.json
├── extensions.json
└── launch.json
├── force-app
└── main
│ └── default
│ ├── classes
│ ├── TransformPDF.cls-meta.xml
│ ├── UnitTestExample.cls-meta.xml
│ ├── BulkSendWriteback.cls-meta.xml
│ ├── SendToNewContact.cls-meta.xml
│ ├── BulkSendingController.cls-meta.xml
│ ├── CreateMergeFieldInEnvelope.cls-meta.xml
│ ├── EmbeddedSigningController.cls-meta.xml
│ ├── InPersonSigningController.cls-meta.xml
│ ├── DocuSignStatusTriggerHandler.cls-meta.xml
│ ├── SendEnvelopeWithTabsController.cls-meta.xml
│ ├── SendEnvelopeFromTriggerController.cls-meta.xml
│ ├── SendEnvelopeWithReminderController.cls-meta.xml
│ ├── SendMultipleEnvelopesController.cls-meta.xml
│ ├── DocuSignStatusTriggerHandler.cls
│ ├── SendToNewContact.cls
│ ├── TransformPDF.cls
│ ├── UnitTestExample.cls
│ ├── SendEnvelope.cls
│ ├── EmbeddedSigningController.cls
│ ├── SendEnvelopeFromTriggerController.cls
│ ├── SendEnvelopeWithReminderController.cls
│ ├── InPersonSigningController.cls
│ ├── CreateMergeFieldInEnvelope.cls
│ ├── BulkSendingController.cls
│ ├── SendMultipleEnvelopesController.cls
│ ├── BulkSendWriteback.cls
│ └── SendEnvelopeWithTabsController.cls
│ ├── triggers
│ ├── Trigger_ContactAfterUpdate.trigger-meta.xml
│ └── Trigger_ContactAfterUpdate.trigger
│ ├── lwc
│ ├── embeddedSigningComponent
│ │ ├── embeddedSigningComponent.html
│ │ ├── embeddedSigningComponent.js-meta.xml
│ │ └── embeddedSigningComponent.js
│ └── .eslintrc.json
│ └── aura
│ └── .eslintrc.json
├── .prettierignore
├── sfdx-project.json
├── scripts
├── soql
│ └── account.soql
└── apex
│ └── hello.apex
├── .prettierrc
├── .eslintignore
├── .forceignore
├── config
└── project-scratch-def.json
├── .gitignore
├── LICENSE
├── package.json
└── README.md
/demo_documents/World_Wide_Corp_salary.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/docusign/code-examples-apex/HEAD/demo_documents/World_Wide_Corp_salary.docx
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "search.exclude": {
3 | "**/node_modules": true,
4 | "**/bower_components": true,
5 | "**/.sfdx": true
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "salesforce.salesforcedx-vscode",
4 | "redhat.vscode-xml",
5 | "dbaeumer.vscode-eslint",
6 | "esbenp.prettier-vscode"
7 | ]
8 | }
9 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/TransformPDF.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 58.0
4 | Active
5 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/UnitTestExample.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 56.0
4 | Active
5 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/BulkSendWriteback.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 58.0
4 | Active
5 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendToNewContact.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 58.0
4 | Active
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running prettier
2 | # More information: https://prettier.io/docs/en/ignore.html
3 | #
4 |
5 | **/staticresources/**
6 | .localdevserver
7 | .sfdx
8 | .vscode
9 |
10 | coverage/
--------------------------------------------------------------------------------
/force-app/main/default/classes/BulkSendingController.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 52.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/CreateMergeFieldInEnvelope.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 57.0
4 | Active
5 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/EmbeddedSigningController.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 50.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/InPersonSigningController.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 52.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/DocuSignStatusTriggerHandler.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 52.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendEnvelopeWithTabsController.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 52.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/triggers/Trigger_ContactAfterUpdate.trigger-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 58.0
4 | Active
5 |
--------------------------------------------------------------------------------
/sfdx-project.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageDirectories": [
3 | {
4 | "path": "force-app",
5 | "default": true
6 | }
7 | ],
8 | "namespace": "",
9 | "sfdcLoginUrl": "https://login.salesforce.com",
10 | "sourceApiVersion": "50.0"
11 | }
12 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendEnvelopeFromTriggerController.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 52.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendEnvelopeWithReminderController.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 52.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendMultipleEnvelopesController.cls-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 52.0
4 | Active
5 |
6 |
--------------------------------------------------------------------------------
/force-app/main/default/lwc/embeddedSigningComponent/embeddedSigningComponent.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/scripts/soql/account.soql:
--------------------------------------------------------------------------------
1 | // Use .soql files to store SOQL queries.
2 | // You can execute queries in VS Code by selecting the
3 | // query text and running the command:
4 | // SFDX: Execute SOQL Query with Currently Selected Text
5 |
6 | SELECT Id, Name FROM Account
7 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "none",
3 | "overrides": [
4 | {
5 | "files": "**/lwc/**/*.html",
6 | "options": { "parser": "lwc" }
7 | },
8 | {
9 | "files": "*.{cmp,page,component}",
10 | "options": { "parser": "html" }
11 | }
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/force-app/main/default/lwc/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["@salesforce/eslint-config-lwc/recommended", "prettier"],
3 | "overrides": [
4 | {
5 | "files": ["*.test.js"],
6 | "rules": {
7 | "@lwc/lwc/no-unexpected-wire-adapter-usages": "off"
8 | }
9 | }
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/force-app/main/default/aura/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["@salesforce/eslint-plugin-aura"],
3 | "extends": ["plugin:@salesforce/eslint-plugin-aura/recommended", "prettier"],
4 | "rules": {
5 | "func-names": "off",
6 | "vars-on-top": "off",
7 | "no-unused-expressions": "off"
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | **/lwc/**/*.css
2 | **/lwc/**/*.html
3 | **/lwc/**/*.json
4 | **/lwc/**/*.svg
5 | **/lwc/**/*.xml
6 | **/aura/**/*.auradoc
7 | **/aura/**/*.cmp
8 | **/aura/**/*.css
9 | **/aura/**/*.design
10 | **/aura/**/*.evt
11 | **/aura/**/*.json
12 | **/aura/**/*.svg
13 | **/aura/**/*.tokens
14 | **/aura/**/*.xml
15 | .sfdx
--------------------------------------------------------------------------------
/.forceignore:
--------------------------------------------------------------------------------
1 | # List files or directories below to ignore them when running force:source:push, force:source:pull, and force:source:status
2 | # More information: https://developer.salesforce.com/docs/atlas.en-us.sfdx_dev.meta/sfdx_dev/sfdx_dev_exclude_source.htm
3 | #
4 |
5 | package.xml
6 |
7 | # LWC configuration files
8 | **/jsconfig.json
9 | **/.eslintrc.json
10 |
11 | # LWC Jest
12 | **/__tests__/**
--------------------------------------------------------------------------------
/config/project-scratch-def.json:
--------------------------------------------------------------------------------
1 | {
2 | "orgName": "Org Name",
3 | "edition": "Developer",
4 | "features": [],
5 | "settings": {
6 | "lightningExperienceSettings": {
7 | "enableS1DesktopEnabled": true
8 | },
9 | "securitySettings": {
10 | "passwordPolicies": {
11 | "enableSetPasswordInApi": true
12 | }
13 | },
14 | "mobileSettings": {
15 | "enableS1EncryptedStoragePref2": false
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/force-app/main/default/lwc/embeddedSigningComponent/embeddedSigningComponent.js-meta.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 50.0
4 | true
5 |
6 | lightning__AppPage
7 | lightning__RecordPage
8 | lightning__HomePage
9 |
10 |
11 |
--------------------------------------------------------------------------------
/scripts/apex/hello.apex:
--------------------------------------------------------------------------------
1 | // Use .apex files to store anonymous Apex.
2 | // You can execute anonymous Apex in VS Code by selecting the
3 | // apex text and running the command:
4 | // SFDX: Execute Anonymous Apex with Currently Selected Text
5 | // You can also execute the entire file by running the command:
6 | // SFDX: Execute Anonymous Apex with Editor Contents
7 |
8 | string tempvar = 'Enter_your_name_here';
9 | System.debug('Hello World!');
10 | System.debug('My name is ' + tempvar);
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Launch Apex Replay Debugger",
9 | "type": "apex-replay",
10 | "request": "launch",
11 | "logFile": "${command:AskForLogFileName}",
12 | "stopOnEntry": true,
13 | "trace": true
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/DocuSignStatusTriggerHandler.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex11Step3
2 | public class DocuSignStatusTriggerHandler{
3 | @future (callout=true)
4 | // Handler for Order complete
5 | public static void handleOrderComplete(final Id contactId) {
6 | // Call the SendEnvelopeFromTriggerController class sendEnvelope method to invoke the DocuSign API's for sending envelope
7 | SendEnvelopeFromTriggerController.sendEnvelope(contactId);
8 | }
9 | }
10 | //ds-snippet-end:Apex11Step3
11 |
12 |
--------------------------------------------------------------------------------
/force-app/main/default/triggers/Trigger_ContactAfterUpdate.trigger:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex11Step4
2 | trigger Trigger_ContactAfterUpdate on Contact (after insert, after update, after delete) {
3 | if (trigger.isUpdate)
4 | {
5 | for(contact aC : trigger.new)
6 | {
7 | if (aC.DocuSign_Status__c=='Email DocuSign') // Test Field called on the contact. This is not a DocuSignStatus Object
8 | {
9 | DocuSignStatusTriggerHandler.handleOrderComplete(aC.Id);
10 | }
11 | }
12 | }
13 | }
14 | //ds-snippet-end:Apex11Step4
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # This file is used for Git repositories to specify intentionally untracked files that Git should ignore.
2 | # If you are not using git, you can delete this file. For more information see: https://git-scm.com/docs/gitignore
3 | # For useful gitignore templates see: https://github.com/github/gitignore
4 |
5 | # Salesforce cache
6 | .sfdx/
7 | .localdevserver/
8 |
9 | # LWC VSCode autocomplete
10 | **/lwc/jsconfig.json
11 |
12 | # LWC Jest coverage reports
13 | coverage/
14 |
15 | # SOQL Query Results
16 | **/scripts/soql/query-results
17 |
18 | # Logs
19 | logs
20 | *.log
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 | # Dependency directories
26 | node_modules/
27 |
28 | # Eslint cache
29 | .eslintcache
30 |
31 | # MacOS system files
32 | .DS_Store
33 |
34 | # Windows system files
35 | Thumbs.db
36 | ehthumbs.db
37 | [Dd]esktop.ini
38 | $RECYCLE.BIN/
39 |
--------------------------------------------------------------------------------
/force-app/main/default/lwc/embeddedSigningComponent/embeddedSigningComponent.js:
--------------------------------------------------------------------------------
1 | import { LightningElement, api } from 'lwc';
2 | import sendEnvelope from '@salesforce/apex/EmbeddedSigningController.sendEnvelope';
3 | import getEmbeddedSigningUrl from '@salesforce/apex/EmbeddedSigningController.getEmbeddedSigningUrl';
4 |
5 | export default class EmbeddedSigningComponent extends LightningElement {
6 |
7 | template = '2712xxxx-xxxx-xxxx-xxxx-xxxxf9b8fa5f';
8 | description = 'Embedded Signing';
9 | @api recordId;
10 | handleClick() {
11 | sendEnvelope({template: this.template, description: this.description, recordId: this.recordId})
12 | .then((envelopeId) => (
13 | getEmbeddedSigningUrl({
14 | envId: envelopeId,
15 | url: window.location.href
16 | })
17 | ))
18 | .then((signingUrl) => {
19 | window.location.href = signingUrl;
20 | })
21 | .catch((error) => {
22 | console.log('Error:');
23 | console.log(error);
24 | });
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2021 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.
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "salesforce-app",
3 | "private": true,
4 | "version": "1.0.0",
5 | "description": "Salesforce App",
6 | "scripts": {
7 | "lint": "npm run lint:lwc && npm run lint:aura",
8 | "lint:aura": "eslint **/aura/**",
9 | "lint:lwc": "eslint **/lwc/**",
10 | "test": "npm run test:unit",
11 | "test:unit": "sfdx-lwc-jest",
12 | "test:unit:watch": "sfdx-lwc-jest --watch",
13 | "test:unit:debug": "sfdx-lwc-jest --debug",
14 | "test:unit:coverage": "sfdx-lwc-jest --coverage",
15 | "prettier": "prettier --write \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\"",
16 | "prettier:verify": "prettier --list-different \"**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}\""
17 | },
18 | "devDependencies": {
19 | "@prettier/plugin-xml": "^0.12.0",
20 | "@salesforce/eslint-config-lwc": "^0.7.0",
21 | "@salesforce/eslint-plugin-aura": "^1.4.0",
22 | "@salesforce/sfdx-lwc-jest": "^0.9.2",
23 | "eslint": "^7.6.0",
24 | "eslint-config-prettier": "^6.11.0",
25 | "husky": "^4.2.1",
26 | "lint-staged": "^10.0.7",
27 | "prettier": "^2.0.5",
28 | "prettier-plugin-apex": "^1.6.0"
29 | },
30 | "husky": {
31 | "hooks": {
32 | "pre-commit": "lint-staged"
33 | }
34 | },
35 | "lint-staged": {
36 | "**/*.{cls,cmp,component,css,html,js,json,md,page,trigger,xml,yaml,yml}": [
37 | "prettier --write"
38 | ],
39 | "**/{aura|lwc}/**": [
40 | "eslint"
41 | ]
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendToNewContact.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex9Step1
2 | public class SendToNewContact {
3 | //ds-snippet-end:Apex9Step1
4 |
5 | //ds-snippet-start:Apex9Step4
6 | @InvocableMethod
7 | public static List sendEnvelope(List record) {
8 | Contact mySource = record.get(0);
9 | sendEnvelopeInFuture(mySource.Id);
10 | return Null;
11 | }
12 | //ds-snippet-end:Apex9Step4
13 |
14 | //ds-snippet-start:Apex9Step3
15 | @future(callout = true)
16 | public static void sendEnvelopeInFuture(Id mySourceId) {
17 | createAndSendEnvelope(mySourceId);
18 | }
19 | //ds-snippet-end:Apex9Step3
20 |
21 | //ds-snippet-start:Apex9Step2
22 | public static Id createAndSendEnvelope(Id mySourceId) {
23 | dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
24 | new dfsle.Entity(mySourceId)
25 | );
26 | Contact myContact = [SELECT Name, Email FROM Contact WHERE Id = :mySourceId LIMIT 1];
27 | dfsle.Recipient myRecipient = dfsle.Recipient.fromSource(
28 | myContact.Name,
29 | myContact.Email,
30 | null,
31 | 'Signer1',
32 | new dfsle.Entity(myContact.Id)
33 | );
34 | myEnvelope = myEnvelope.withRecipients(new List { myRecipient });
35 | dfsle.UUID myTemplateId = dfsle.UUID.parse('8dafd5dd-xxxx-xxxx-xxxx-542f35b227f7');
36 | dfsle.Document myDocument = dfsle.Document.fromTemplate(
37 | myTemplateId,
38 | 'Services Framework Agreement'
39 | );
40 | myEnvelope = myEnvelope.withDocuments(
41 | new List { myDocument }
42 | );
43 | myEnvelope = dfsle.EnvelopeService.sendEnvelope(
44 | myEnvelope,
45 | true
46 | );
47 | return myEnvelope.Id;
48 | }
49 | //ds-snippet-end:Apex9Step2
50 |
51 | //ds-snippet-start:Apex9Step1
52 | }
53 | //ds-snippet-end:Apex9Step1
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Apex Toolkit Code Examples
2 |
3 | ### Github repo: https://github.com/docusign/code-examples-apex
4 |
5 | This GitHub repo includes code examples for Docusign's Apex Toolkit. The Apex Toolkit is a set of predefined Apex methods, classes, and utilities that encapsulate a set of the Docusign eSignature API functionality similar to an SDK, enabling you to integrate Docusign and Salesforce functionality into your Apex code.
6 |
7 | ## Installation
8 |
9 | ### Prerequisites
10 |
11 | 1. A free [Docusign developer account](https://go.docusign.com/o/sandbox/); create one if you don't already have one.
12 | 1. A Salesforce Developer Edition (account).
13 | 1. [Install the Apex Toolkit](https://developers.docusign.com/docs/salesforce/how-to/apex-toolkit-install/).
14 | 1. Visual Studio Code. Your Visual Studio Code should be set up with the necessary [Salesforce development tools](https://trailhead.salesforce.com/content/learn/projects/set-up-your-lightning-web-components-developer-tools/install-development-tools) including the [Salesforce CLI](https://developer.salesforce.com/tools/sfdxcli).
15 | 1. The [Salesforce Extension Pack for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=salesforce.salesforcedx-vscode)
16 |
17 | ### Installation steps
18 |
19 | 1. Authorize your Salesforce Developer Account within Visual Studio Code. To do this press command + shift + P (on a Mac) or Ctrl + Shift + P (on Windows) to open the Command Palette. Then type SFDX:Authorize an Org and press Enter. In the browser window that opens, log into your Salesforce Developer Organization, then on
20 | the next screen, click Allow to grant access.
21 | 1. Download or clone the **code-examples-apex** repo.
22 | 1. Replace any placeholder IDs from the example code with template IDs or other IDs corresponding with your Docusign and Salesforce accounts.
23 | 1. Deploy the code to Salesforce. To do this, navigate to the force-app/main/default folder in the menu on the left and right-click default, then select SFDX: Deploy Source to Org. Now when you sign into your Salesforce Developer Edition (account) you will find the clases and Lightning Web Components defined in this project.
24 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/TransformPDF.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex8Step1
2 | public class TransformPDF {
3 | public static void sendEnvelope() {
4 | //ds-snippet-end:Apex8Step1
5 | //ds-snippet-start:Apex8Step2
6 | Id mySourceId = '0034xxxxxxxxxx4QAE'; // The Salesforce Contact ID of the sender
7 | // Create an empty envelope.
8 | dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
9 | new dfsle.Entity(mySourceId));
10 |
11 | // We will use a Salesforce Contact ID as a Recipient here
12 | Contact myContact = [SELECT Id, Name, Email FROM Contact WHERE Id = '0034xxxxxxxxxxcQAG'];
13 | // Use the Recipient.fromSource method to create the Recipient
14 | dfsle.Recipient myRecipient = dfsle.Recipient.fromSource(
15 | myContact.Name, // Recipient name
16 | myContact.Email, // Recipient email
17 | null, //Optional phone number
18 | 'Signer 1', //Role Name. Specify the exact role name from template
19 | new dfsle.Entity(myContact.Id));
20 | // Add Recipient to the Envelope
21 | myEnvelope = myEnvelope.withRecipients(new List { myRecipient });
22 | //ds-snippet-end:Apex8Step2
23 |
24 | //ds-snippet-start:Apex8Step3
25 | Id myFileId = [SELECT id from ContentVersion where ContentDocumentId = '0694xxxxxxxxxxyQAD' LIMIT 1].id; // Content version ID of document to send
26 | dfsle.Document myDocument = dfsle.DocumentService.getDocuments(ContentVersion.getSObjectType(), new Set { myFileId }).get(0);
27 | myDocument.withPdfOptions(new dfsle.Document.PdfOptions(
28 | true, // Whether to transform PDF form fields
29 | 1)); // The recipient for which to apply the tags
30 |
31 | //Add document to the Envelope
32 | myEnvelope = myEnvelope.withDocuments(new List { myDocument });
33 | //ds-snippet-end:Apex8Step3
34 |
35 | //ds-snippet-start:Apex8Step4
36 | // Send the envelope
37 | myEnvelope = dfsle.EnvelopeService.sendEnvelope(
38 | myEnvelope,
39 | true);
40 | //ds-snippet-end:Apex8Step4
41 |
42 | //ds-snippet-start:Apex8Step1
43 | }
44 | }
45 | //ds-snippet-end:Apex8Step1
--------------------------------------------------------------------------------
/force-app/main/default/classes/UnitTestExample.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex12Step1
2 | @IsTest
3 | public with sharing class UnitTestExample {
4 |
5 | @IsTest
6 | public static void testSendEnvelope() {
7 | //ds-snippet-end:Apex12Step1
8 |
9 | //ds-snippet-start:Apex12Step2
10 | // Mock the DocuSign eSignature API
11 | dfsle.TestUtils.setMock(new dfsle.ESignatureAPIMock());
12 |
13 | // Run the test as a DocuSign Sender. This is required by dfsle.EnvelopeService.sendEnvelope
14 | System.runAs(dfsle.UserMock.createDocuSignSender()) {
15 |
16 | // Create test data
17 | Account myAccount = new Account(Name = 'Test Account');
18 | insert myAccount;
19 |
20 | Contact myContact = new Contact(
21 | AccountId = myAccount.Id,
22 | FirstName = 'Test',
23 | LastName = 'Contact',
24 | Phone = '555-1234-5678',
25 | Email = 'test.contact@example.com');
26 | insert myContact;
27 |
28 | // Create a test envelope with one document and one recipient
29 | dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(new dfsle.Entity(myAccount.Id))
30 | .withDocuments(new List {
31 | dfsle.Document.fromTemplate(
32 | dfsle.UUID.randomUUID(),
33 | 'test template')
34 | })
35 | .withRecipients(new List {
36 | dfsle.Recipient.fromSource(
37 | myContact.FirstName + ' ' + myContact.LastName,
38 | myContact.Email,
39 | myContact.Phone,
40 | 'Signer 1',
41 | new dfsle.Entity(myContact.Id))
42 | });
43 | }
44 | //ds-snippet-end:Apex12Step2
45 |
46 | //ds-snippet-start:Apex12Step3
47 | // Perform the test
48 | Test.startTest();
49 | dfsle.Envelope myResult = dfsle.EnvelopeService.sendEnvelope(myEnvelope, true);
50 | Test.stopTest();
51 |
52 | // Verify the results
53 | System.assertNotEquals(null, myResult);
54 | //ds-snippet-end:Apex12Step3
55 |
56 | //ds-snippet-start:Apex12Step1
57 | }
58 | }
59 | //ds-snippet-end:Apex12Step1
60 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendEnvelope.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex1Step1
2 | public class SendEnvelope {
3 | public static void sendEnvelopeMethod(){
4 | //ds-snippet-end:Apex1Step1
5 |
6 | //ds-snippet-start:Apex1Step2
7 | Id mySourceId; // The ID of the initiating Salesforce object
8 | String templateId; // The ID of the DocuSign template
9 |
10 | // Create an empty envelope
11 | dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
12 | new dfsle.Entity(mySourceId));
13 | // The initiating Salesforce entity
14 | //ds-snippet-end:Apex1Step2
15 |
16 | //ds-snippet-start:Apex1Step3
17 | // We will use a Salesforce contact record as a Recipient here
18 | Contact myContact = [SELECT Id, Name, Email FROM Contact LIMIT 1];
19 |
20 | //use the Recipient.fromSource method to create the Recipient
21 | dfsle.Recipient myRecipient = dfsle.Recipient.fromSource(
22 | myContact.Name, // Recipient name
23 | myContact.Email, // Recipient email
24 | null, // Optional phone number
25 | 'Signer 1', // Role Name. Specify the exact role name from template
26 | new dfsle.Entity(myContact.Id)); // Source object for the recipient
27 |
28 | // Add a recipient to the envelope
29 | myEnvelope = myEnvelope.withRecipients(new List { myRecipient });
30 | //ds-snippet-end:Apex1Step3
31 |
32 | //ds-snippet-start:Apex1Step4
33 | // myTemplateId contains the DocuSign Id of the DocuSign Template
34 | dfsle.UUID myTemplateId = dfsle.UUID.parse(templateId);
35 |
36 | // create a new document for the Envelope
37 | dfsle.Document myDocument = dfsle.Document.fromTemplate(
38 | myTemplateId, // Template Id in dfsle.UUID format
39 | 'myTemplate'); // Name of the template
40 |
41 | //add document to the envelope
42 | myEnvelope = myEnvelope.withDocuments(new List { myDocument });
43 | //ds-snippet-end:Apex1Step4
44 |
45 | //ds-snippet-start:Apex1Step5
46 | // Send the envelope
47 | myEnvelope = dfsle.EnvelopeService.sendEnvelope(
48 | myEnvelope, // The envelope to send
49 | true); // True to send the envelope now
50 | //ds-snippet-end:Apex1Step5
51 | //ds-snippet-start:Apex1Step1
52 | }
53 | }
54 | //ds-snippet-end:Apex1Step1
--------------------------------------------------------------------------------
/force-app/main/default/classes/EmbeddedSigningController.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex2Step1
2 | public class EmbeddedSigningController {
3 | //ds-snippet-end:Apex2Step1
4 | /**
5 | * sendEnvelope method (String)
6 | * Get Salesforce user ID
7 | * Create an envelope
8 | * Specify embedded signing
9 | * Add a document template
10 | * Send the envelope immediately
11 | * Return the envelope ID to the controller as a string
12 | */
13 |
14 | //ds-snippet-start:Apex2Step2
15 | @AuraEnabled
16 | public static String sendEnvelope(String template, String description, Id recordId) {
17 | Id mySourceId = recordId; // The ID of the initiating Salesforce object
18 |
19 | // Create an empty envelope and add a Salesforce Document and embedded signer recipient
20 | // The embedded signer will be the current user with sequence and routing order 1 and role "Signer 1" by default
21 | dfsle.Envelope dsEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
22 | new dfsle.Entity(mySourceId)) // The initiating Salesforce entity--current SF user (salesperson)
23 | .withDocuments(new List {
24 | dfsle.Document.fromTemplate(dfsle.UUID.parse(template), description)
25 | })
26 | .withRecipients(new List {
27 | dfsle.Recipient.newEmbeddedSigner() // An embedded signer
28 | }
29 | );
30 |
31 | // Send the envelope.
32 | dsEnvelope = dfsle.EnvelopeService.sendEnvelope(
33 | dsEnvelope, // The envelope to send
34 | true // Send now?
35 | );
36 | // Return string value of DocuSign envelope ID
37 | return String.valueOf(dsEnvelope.docuSignId);
38 | }
39 | //ds-snippet-end:Apex2Step2
40 |
41 | /**
42 | * getEmbeddedSigningUrl method (String)
43 | * Get the envelope ID
44 | * Get the post-signing URL
45 | * Generate an embedded signing URL
46 | * Return the embedded signing URL as a string
47 | */
48 |
49 | //ds-snippet-start:Apex2Step3
50 | @AuraEnabled
51 | public static String getEmbeddedSigningUrl(String envId, String url) {
52 | Url mySigningUrl = dfsle.SigningService.getEmbeddedSigningUrl(
53 | dfsle.UUID.parse(envId), // envId value as a UUID
54 | new URL(url) // url value as a URL
55 | );
56 | // Return string value of Url to controller
57 | return mySigningUrl.toExternalForm();
58 | }
59 | //ds-snippet-end:Apex2Step3
60 | //ds-snippet-start:Apex2Step1
61 | }
62 | //ds-snippet-end:Apex2Step1
63 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendEnvelopeFromTriggerController.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex11Step1
2 | public with sharing class SendEnvelopeFromTriggerController {
3 | public class EnvelopeSendResponse {
4 |
5 | public String message {get; private set;}
6 | public Boolean status {get; private set;}
7 |
8 | public EnvelopeSendResponse(final String message, final Boolean status){
9 | this.message = message;
10 | this.status = status;
11 | }
12 | }
13 | //ds-snippet-end:Apex11Step1
14 |
15 | //ds-snippet-start:Apex11Step2
16 | public static EnvelopeSendResponse sendEnvelope(final Id mySourceId) {
17 | EnvelopeSendResponse response;
18 | try {
19 |
20 | // Capture customer details
21 | Contact myCustomer = [SELECT Id, Name, Email FROM Contact WHERE Id =:mySourceId];
22 |
23 | // Create an empty envelope
24 | dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope
25 | (new dfsle.Entity(mySourceId));
26 |
27 | // Setup recipient data
28 | dfsle.Recipient myRecipient = dfsle.Recipient.fromSource
29 | (myCustomer.Name, myCustomer.Email, null, 'Signer 1', new dfsle.Entity(mySourceId));
30 |
31 |
32 | // Add Recipient to the Envelope
33 | myEnvelope = myEnvelope.withRecipients(new List { myRecipient });
34 |
35 | // myTemplateId contains the DocuSign Id of the DocuSign Template
36 | dfsle.UUID myTemplateId = dfsle.UUID.parse('bf7ca600-XXXX-XXXX-XXXX-06e7f3b9e8ce');
37 |
38 | // Create a new document for the Envelope
39 | dfsle.Document myDocument = dfsle.Document.fromTemplate(
40 | myTemplateId, // templateId in dfsle.UUID format
41 | 'myTemplate'); // The name of the template
42 |
43 | // Add document to the Envelope
44 | myEnvelope = myEnvelope.withDocuments(new List { myDocument });
45 |
46 | // Send the envelope
47 | myEnvelope = dfsle.EnvelopeService.sendEnvelope(
48 | myEnvelope, // The envelope to send
49 | true); // Send now?
50 |
51 | response = new EnvelopeSendResponse('Envelope sent successfully', true);
52 | }
53 | catch(Exception ex) {
54 | response = new EnvelopeSendResponse(ex.getMessage(), false);
55 | }
56 | return response;
57 | }
58 | //ds-snippet-end:Apex11Step2
59 | //ds-snippet-start:Apex11Step1
60 | }
61 | //ds-snippet-end:Apex11Step1
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendEnvelopeWithReminderController.cls:
--------------------------------------------------------------------------------
1 | public class SendEnvelopeWithReminderController {
2 | public static void sendEnvelopeMethod(){
3 | Id mySourceId = '0XXXXXXXXXXXXXXXXE'; // The ID of the initiating Salesforce object.
4 |
5 | // Set up notification
6 | //ds-snippet-start:Apex6Step2
7 | dfsle.Notifications notifySigner = new dfsle.Notifications(
8 | true, // Indicates that the recipient should be reminded to sign
9 | 2, // Number of days to wait before sending a reminder
10 | 1, // Number of days between reminders
11 | true, // Whether or not the envelope expires and is voided
12 | 90, // How many days before the envelope expires
13 | 10, // Number of days before expiration to remind the recipient
14 | false // Placeholder for deprecated field
15 | );
16 | //ds-snippet-end:Apex6Step2
17 |
18 | //ds-snippet-start:Apex6Step3
19 | // Create an empty envelope.
20 | dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
21 | new dfsle.Entity(mySourceId));
22 | // The initiating Salesforce entity.
23 |
24 | // We will use a Salesforce contact record as a Recipient here
25 | // We will use a Salesforce contact record as a Recipient here
26 | Contact myContact = [SELECT Id, Name, Email FROM Contact WHERE Id = '00xxxxxxxxxxxxxxAR'];
27 |
28 | // Use the Recipient.fromSource method to create the Recipient
29 | dfsle.Recipient myRecipient = dfsle.Recipient.fromSource(
30 | myContact.Name, // Recipient name
31 | myContact.Email, // Recipient email
32 | null, // Optional phone number
33 | 'Signer 1', // Role Name. Specify the exact role name from template
34 | new dfsle.Entity(myContact.Id)); // Source object for the Recipient
35 |
36 | // Add Recipient to the Envelope
37 | myEnvelope = myEnvelope.withRecipients(new List { myRecipient });
38 |
39 | // myTemplateId contains the DocuSign Id of the DocuSign Template
40 | dfsle.UUID myTemplateId = dfsle.UUID.parse('8dafxxxx-xxxx-xxxx-xxxx-xxxxxxxx27f7');
41 |
42 | // Create a new document for the Envelope
43 | dfsle.Document myDocument = dfsle.Document.fromTemplate(
44 | myTemplateId, // templateId in dfsle.UUID format
45 | 'myTemplate'); // name of the template
46 |
47 | // Add document to the Envelope
48 | myEnvelope = myEnvelope.withDocuments(new List { myDocument });
49 | // Add notification to the envelope
50 | myEnvelope = myEnvelope.withNotifications(notifySigner);
51 | //ds-snippet-end:Apex6Step3
52 |
53 | // Send the envelope
54 | //ds-snippet-start:Apex6Step4
55 | myEnvelope = dfsle.EnvelopeService.sendEnvelope(
56 | myEnvelope, // The envelope to send
57 | true); // Indicates that the envelope should be sent now
58 | //ds-snippet-end:Apex6Step4
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/InPersonSigningController.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex7Step1
2 | public class InPersonSigningController {
3 | public static Id sendWithInPerson(){
4 | //ds-snippet-end:Apex7Step1
5 |
6 | //ds-snippet-start:Apex7Step2
7 | //Get the Salesforce account ID
8 | Opportunity myOpportunity = [SELECT Id FROM Opportunity WHERE Name = 'My Opportunity' LIMIT 1];
9 | // Create an empty envelope with Opportunity Id as the source Id
10 | dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(new dfsle.Entity(myOpportunity.Id));
11 | //ds-snippet-end:Apex7Step2
12 |
13 | //ds-snippet-start:Apex7Step3
14 | dfsle.Recipient InPerson = new dfsle.Recipient(
15 | null, //Source Id
16 | 'inPersonSigner',//Type of recipient
17 | 1, //Sequence
18 | 2, //routing order
19 | new dfsle.Recipient.Role('Customer',null), //role -used to match role
20 | //on template if using a template
21 | 'InPerson Signer', //inPerson Recipient name
22 | 'example@example.com', //inPerson Recipient Email
23 | null, //signing group
24 | null, //phone
25 | //Don't need recipient auth for embedded in SF cause you have SF auth
26 | //new dfsle.Recipient.Authentication(null, true, new List{'147852369'}),//Authentication - may need to adjust this - can be null
27 | null,//no Authentication
28 | null, //note
29 | null, //EmailSettings
30 | 'Host Name', //host name This is the name of the host for InPerson
31 | 'host@example.com', //host email email of host
32 | true, //sign now
33 | null, //source
34 | false, //read only
35 | false); //required
36 | // add Recipient to the Envelope
37 | myEnvelope = myEnvelope.withRecipients(new List { InPerson });
38 | //ds-snippet-end:Apex7Step3
39 |
40 | //ds-snippet-start:Apex7Step4
41 | // myTemplateId contains the DocuSign Id of the DocuSign Template
42 | dfsle.UUID myTemplateId = dfsle.UUID.parse('801c741b-xxxx-xxxx-xxxx-23a050e0dd51');
43 | // Create a new document for the Envelope
44 | dfsle.Document myDocument = dfsle.Document.fromTemplate(
45 | myTemplateId, // templateId in dfsle.UUID format
46 | 'myTemplate'); // Name of the template
47 |
48 | myEnvelope = myEnvelope.withDocuments(new List { myDocument });
49 | //ds-snippet-end:Apex7Step4
50 |
51 | //ds-snippet-start:Apex7Step5
52 | // Send the envelope
53 | myEnvelope = dfsle.EnvelopeService.sendEnvelope(
54 | myEnvelope, // The envelope to send
55 | true); // Send or Draft
56 |
57 | System.debug(myEnvelope.Id);
58 | return myEnvelope.Id;
59 | //ds-snippet-end:Apex7Step5
60 |
61 | //ds-snippet-start:Apex7Step1
62 | }
63 | }
64 | //ds-snippet-end:Apex7Step1
--------------------------------------------------------------------------------
/force-app/main/default/classes/CreateMergeFieldInEnvelope.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex10Step1
2 | public with sharing class CreateMergeFieldInEnvelope {
3 |
4 | @AuraEnabled
5 | public static void sendEnvelope() {
6 | //ds-snippet-end:Apex10Step1
7 |
8 | //ds-snippet-start:Apex10Step2
9 | Id mySourceId = '00XXXXXXXXXXXXXXAM'; // The ID of the initiating Salesforce Opportunity
10 |
11 | // Create an empty envelope
12 | dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
13 | new dfsle.Entity(mySourceId));
14 | // The initiating Salesforce entity
15 |
16 | // Add document to the envelope
17 | Id myDocumentId = '00XXXXXXXXXXXXXXA4'; // The ID of a document stored in a Salesforce library
18 | Id myFileId = [SELECT id from ContentVersion where ContentDocumentId = :myDocumentId LIMIT 1].id;
19 | myEnvelope = myEnvelope.withDocuments(dfsle.DocumentService.getDocuments(ContentVersion.getSObjectType(), new Set { myFileId }));
20 | //ds-snippet-end:Apex10Step2
21 |
22 | //ds-snippet-start:Apex10Step3
23 | //Define a merge field
24 | //This field will be associated with the initiating source object represented by mySourceId
25 | dfsle.Tab.MergeField myMergeField = new dfsle.Tab.MergeField (
26 | 'opportunity.name', //The data that this merge field will pull its value from
27 | null, //N/A
28 | null, //N/A
29 | true, //Allows writeback to the Salesforce object
30 | false //Whether or not the field is read only for the sender
31 | );
32 |
33 | //Create a text tab that will be mapped to the merge field
34 | dfsle.Tab myTextTab = new dfsle.TextTab()
35 | .withMergeField(myMergeField) //Associate this tab with the mergeField
36 | .withReadOnly(false) //true = read only or locked
37 | .withPosition(new dfsle.Tab.Position(1, 1, 200, 300, null, null))
38 | .withDataLabel('Contact Name');
39 | //ds-snippet-end:Apex10Step3
40 |
41 |
42 | //ds-snippet-start:Apex10Step4
43 | // Create a new recipient
44 | Id myContactId = '00XXXXXXXXXXXXXXA4';
45 | Contact myContact = [SELECT Id, Name, Email FROM Contact WHERE Id = :myContactId];
46 |
47 | dfsle.Recipient myRecipient = dfsle.Recipient.fromSource(
48 | myContact.Name, // Signer name
49 | myContact.Email, // Signer email
50 | null, // Signer phone number
51 | null, // Template role n/a
52 | null) // No Salesforce association
53 | .withTabs(new List { // Associate the tabs with this recipient
54 | myTextTab
55 | });
56 |
57 | // Add recipient to the envelope
58 | myEnvelope = myEnvelope.withRecipients(new List { myRecipient });
59 | //ds-snippet-end:Apex10Step4
60 |
61 | //ds-snippet-start:Apex10Step5
62 | // Send the envelope
63 | myEnvelope = dfsle.EnvelopeService.sendEnvelope(
64 | myEnvelope, // The envelope to send
65 | true); // Send now?
66 | //ds-snippet-end:Apex10Step5
67 |
68 | //ds-snippet-start:Apex10Step1
69 | }
70 | }
71 | //ds-snippet-end:Apex10Step1
--------------------------------------------------------------------------------
/force-app/main/default/classes/BulkSendingController.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex3Step1
2 | public with sharing class BulkSendingClass{
3 | //ds-snippet-end:Apex3Step1
4 |
5 | /**
6 | * buildList Method
7 | * Requires Chatter group ID
8 | * Create a persistant list of group members
9 | * Return an ID of the list
10 | */
11 |
12 | //ds-snippet-start:Apex3Step2
13 | @AuraEnabled
14 | public static Id buildList(){
15 |
16 | Id myGroupId = '0FXXXXXXXXXXXXXXAC'; // Substitute this value with your Chatter group ID
17 | // Build a list membership from a Chatter group
18 | // Recipient authentication, email settings, or private notes may be overridden using the Recipient.with* methods
19 | // Envelope email settings and notifications may also be overridden per copy using the Envelope.with* methods
20 |
21 | List myBulkCopies = new List();
22 | for (CollaborationGroupMember m : [
23 | SELECT Member.Id, Member.Name, Member.Email
24 | FROM CollaborationGroupMember
25 | WHERE CollaborationGroupId = :myGroupId
26 | ]) {
27 | myBulkCopies.add(dfsle.Envelope.newBulkCopy(
28 | dfsle.Recipient.newBulkRecipient(
29 | m.Member.Name,
30 | m.Member.Email,
31 | new dfsle.Entity(m.Member.Id) // Source Salesforce object
32 | )
33 | .withRole('SignerOne')
34 | ));
35 | }
36 |
37 | // Create the bulk list. This list persists after sending and may be reused for multiple batches of envelopes
38 | dfsle.BulkList myList = dfsle.BulkSendService.createLists(new List {
39 | dfsle.BulkList.newList(
40 | 'My bulk list', // List name
41 | myBulkCopies, // Envelope copies
42 | new dfsle.Entity(myGroupId)) // The Salesforce source object
43 | })[0];
44 |
45 | // Save the ID for later operations
46 | Id myListId = myList.id;
47 | System.debug(LoggingLevel.INFO, myListId);
48 | return myListId;
49 |
50 | }
51 | //ds-snippet-end:Apex3Step2
52 |
53 |
54 | //ds-snippet-start:Apex3Step3
55 | @future(callout=true)
56 | /**
57 | * bulkSendEnvelopes method
58 | * Use myListId from buildList method
59 | * Assign myStatusId to the result of the BulkSendService call
60 | */
61 | public static void bulkSendEnvelopes(Id myListId){
62 |
63 | dfsle.UUID myTemplateId = dfsle.UUID.parse('3d9fac4b-xxxx-xxxx-xxxx-6cd70d70f8ed'); // Substitute with your template ID
64 | dfsle.Document myDocument = dfsle.Document.fromTemplate(
65 | myTemplateId, // templateId in dfsle.UUID format
66 | 'myTemplate'); // name of the template
67 |
68 | // Create the draft bulk envelope. This will have exactly one placeholder bulk recipient
69 | dfsle.Envelope myEnvelope = dfsle.BulkSendService.getDraftEnvelope(
70 | new List { myDocument }, null); // Optional Salesforce source entity
71 |
72 | // Send envelope with a placeholder bulk recipient
73 | dfsle.BulkList.Result myResult = dfsle.BulkSendService.sendEnvelope(myListId, myEnvelope);
74 |
75 | }
76 | //ds-snippet-end:Apex3Step3
77 |
78 | //ds-snippet-start:Apex3Step1
79 | }
80 | //ds-snippet-end:Apex3Step1
81 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendMultipleEnvelopesController.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex4Step1
2 | public with sharing class SendMultipleEnvelopesController {
3 | public static void SendMultipleEnvelopes() {
4 | //ds-snippet-end:Apex4Step1
5 |
6 | //ds-snippet-start:Apex4Step2
7 | // Get up to 99 contacts in the "Prepared" offer stage
8 | List contacts = [SELECT Id, Name FROM Contact WHERE OfferStage__c = 'Prepared' LIMIT 99];
9 |
10 | // Build a list of offer envelopes to send
11 | List envelopes = new List();
12 | for (Contact c : contacts) {
13 | // Get an empty envelope with org defaults
14 | envelopes.add(dfsle.EnvelopeService.getEmptyEnvelope(new dfsle.Entity(c.Id))
15 | // Customize the email subject and message
16 | .withEmail('Offer Letter for ' + c.Name, c.Name + ', please review and sign the enclosed offer letter.')
17 | // Add linked offer letter to envelope
18 | .withDocuments(dfsle.DocumentService.getLinkedDocuments(
19 | ContentVersion.getSObjectType(),
20 | new Set { c.Id },
21 | true))
22 | // Add the contact as a recipient
23 | .withRecipients(dfsle.RecipientService.getRecipients(
24 | Contact.getSObjectType(),
25 | new Set { c.Id })));
26 | }
27 | //ds-snippet-end:Apex4Step2
28 |
29 | //ds-snippet-start:Apex4Step3
30 | // Send the envelopes and determine which envelopes were sent successfully
31 | // Filter out unsuccessfully sent envelopes
32 | List contactsToUpdate = new List();
33 | List sentEnvelopes = new List();
34 | for (dfsle.Envelope envelope : dfsle.EnvelopeService.sendEnvelopes(envelopes)) {
35 | if (envelope.error == null) {
36 | // Envelope sent successfully
37 | sentEnvelopes.add(envelope);
38 | contactsToUpdate.add(new Contact(
39 | Id = envelope.source.id,
40 | OfferStage__c = 'Out for Signature'));
41 | } else {
42 | // Handle send error
43 | System.debug('Envelope error: ' + envelope.error);
44 | }
45 | }
46 |
47 | // Update the Contact offer stage to "Out for Signature"
48 | update contactsToUpdate;
49 | //ds-snippet-end:Apex4Step3
50 |
51 | //ds-snippet-start:Apex4Step4
52 | List savedEnvelopes = dfsle.EnvelopeService.saveSentEnvelopes(sentEnvelopes);
53 | //ds-snippet-end:Apex4Step4
54 |
55 | //ds-snippet-start:Apex4Step5
56 | // Build a list of Contact IDs to query
57 | Set contactIds = new Set();
58 | for (dfsle.Envelope envelope : savedEnvelopes) {
59 | contactIds.add(envelope.source.id);
60 | }
61 |
62 | // Retrieve the most recent envelope statuses from the Salesforce source objects
63 | // The status results are sorted oldest to newest
64 | List statuses = dfsle.StatusService.getStatus(
65 | contactIds, // Envelope source object IDs
66 | 99); // Maximum number of records to return
67 |
68 | // Display or take action on the returned statuses
69 | //ds-snippet-end:Apex4Step5
70 | //ds-snippet-start:Apex4Step1
71 | }
72 | }
73 | //ds-snippet-end:Apex4Step1
74 |
--------------------------------------------------------------------------------
/force-app/main/default/classes/BulkSendWriteback.cls:
--------------------------------------------------------------------------------
1 | public class BulkSendWriteback {
2 | //ds-snippet-start:Apex13Step4
3 | @AuraEnabled
4 | public static Id buildList(){
5 |
6 | List myBulkCopies = new List();
7 | //SOQL is used to gather up the list of recipients to send to. In this case we get all contacts who have the bulk send checkbox set as true
8 | for (Contact m : [SELECT Contact.FirstName, Contact.LastName, Contact.Email, Contact.Id FROM contact where contact.Bulk_Send__c = true LIMIT 5])
9 | {
10 |
11 | //To use merge fields and document writeback with bulk sending we have to add in the following custom fields. You first need to add them to your account under "Settings" -> "Envelope Custom Fields"
12 | // You need to create two envelope custom fields with the Field Name set as ##SFSource and ##SFDocumentWriteBack
13 | // https://developers.docusign.com/docs/salesforce/apex-toolkit-reference/customfield.html
14 | dfsle.CustomField sourceId = new dfsle.CustomField('text', '##SFSource', m.Id+'~Contact', null, false, true); // DocuSign custom field to capture Salesforce record Id. Replace ##SFSource with the name for your custom field
15 | dfsle.CustomField writeBackId = new dfsle.CustomField('text', '##SFDocumentWriteBack', m.Id+'~NamePDF~0~1', null, false, true); // DocuSign custom field to initiate document write back to Salesforce.
16 |
17 | //Create our recipients for the envelope
18 | myBulkCopies.add(dfsle.Envelope.newBulkCopy(
19 | dfsle.Recipient.newBulkRecipient(
20 | m.FirstName + ' ' + m.LastName,
21 | m.Email,
22 | null) // Source Salesforce object
23 | //The role needs to match up exactly with the role on your template.
24 | .withRole('Signer'))
25 | .withCustomFields(new List{ sourceId, writeBackId })); // DocuSign Custom Fields
26 | }
27 | // Create the bulk list. This list persists after sending and may be reused for multiple batches of envelopes
28 | dfsle.BulkList myList = dfsle.BulkSendService.createLists(new List {
29 | dfsle.BulkList.newList(
30 | 'My bulk list', // List name
31 | myBulkCopies, // Envelope copies
32 | null) // The Salesforce source object
33 | })[0];
34 | // Save the ID for later operations
35 | Id myListId = myList.id;
36 | System.debug(LoggingLevel.INFO, myListId);
37 | return myListId;
38 |
39 | }
40 | //ds-snippet-end:Apex13Step4
41 |
42 | //ds-snippet-start:Apex13Step5
43 | @future(callout=true)
44 | /**
45 | * bulkSendEnvelopes method
46 | * Use myListId from buildList method
47 | */
48 | public static void bulkSendEnvelopes(Id myListId){
49 |
50 | dfsle.UUID myTemplateId = dfsle.UUID.parse('3df1fb4c-xxxx-xxxx-xxxx-cdf3cb0fe6b1'); // Substitute with your template ID
51 | dfsle.Document myDocument = dfsle.Document.fromTemplate(
52 | myTemplateId, // templateId in dfsle.UUID format
53 | 'myTemplate'); // name of the template
54 |
55 | // Create the draft bulk envelope. This will have exactly one placeholder bulk recipient
56 | dfsle.Envelope myEnvelope = dfsle.BulkSendService.getDraftEnvelope(
57 | new List { myDocument }, null); // Optional Salesforce source entity
58 |
59 | // Send envelope with a placeholder bulk recipient
60 | dfsle.BulkList.Result myResult = dfsle.BulkSendService.sendEnvelope(myListId, myEnvelope);
61 | System.debug(myResult);
62 | }
63 | //ds-snippet-end:Apex13Step5
64 |
65 | }
--------------------------------------------------------------------------------
/force-app/main/default/classes/SendEnvelopeWithTabsController.cls:
--------------------------------------------------------------------------------
1 | //ds-snippet-start:Apex5Step1
2 | public with sharing class SendEnvelopeWithTabsController {
3 |
4 | @AuraEnabled
5 |
6 | public static void sendEnvelopeWithTabs() {
7 | //ds-snippet-end
8 | //ds-snippet-start:Apex5Step2
9 | Id mySourceId = '00XXXXXXXXXXXXXXAM'; // The ID of the initiating Salesforce object
10 |
11 | // Create an empty envelope
12 | dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
13 | new dfsle.Entity(mySourceId));
14 | // The initiating Salesforce entity
15 | //ds-snippet-end
16 |
17 | //ds-snippet-start:Apex5Step3
18 | Id myDocumentId = '06XXXXXXXXXXXXXXAQ'; // The ID of a document stored in a Salesforce library
19 | Id myFileId = [SELECT id from ContentVersion where ContentDocumentId = :myDocumentId LIMIT 1].id;
20 |
21 | // Add document to the envelope
22 | myEnvelope = myEnvelope.withDocuments(dfsle.DocumentService.getDocuments(ContentVersion.getSObjectType(), new Set { myFileId }));
23 | //ds-snippet-end
24 |
25 | // Create an Initial Here tab
26 | //ds-snippet-start:Apex5Step4
27 | dfsle.Tab myInitialHereTab = new dfsle.InitialHereTab()
28 | .withRequired(true) // Signing optional
29 | .withPosition(new dfsle.Tab.Position(
30 | 1, // The document to use
31 | 1, // Page number on the document
32 | 320, // X position
33 | 290, // Y position
34 | null, // Default width
35 | null)); // Default height
36 |
37 | // Create a Text tab
38 | dfsle.Tab myTextTab = new dfsle.TextTab()
39 | .withRequired(true) // Signer must enter value
40 | .withPosition(new dfsle.Tab.Position(
41 | 1, // The document to use
42 | 1, // Page number on the document
43 | 210, // X position
44 | 305, // Y position
45 | 100, // 100 pixels wide
46 | null)); // Default height
47 |
48 | // Create a Sign Here tab
49 | dfsle.Tab mySignHereTab = new dfsle.SignHereTab()
50 | .withScale(1.5) // 1.5 scale
51 | .withRequired(true) // Signing mandatory
52 | .withAnchor(new dfsle.Tab.Anchor(
53 | 'signed', // Anchor string
54 | false, // Do not allow white space in anchor string
55 | false, // Anchor string is not case sensitive
56 | 'right', // Horizontal alignment in relation to the anchor text
57 | true, // Ignore if the anchor text is not present in the document
58 | true, // Must match the value of the anchor string in its entirety
59 | 'pixels', // Unit of the x and y offset properties
60 | 20, // X offset
61 | 0)); // Y offset
62 |
63 | // Create a Date Signed tab
64 | dfsle.Tab myDateSignedTab = new dfsle.DateSignedTab()
65 | .withFormatting(new dfsle.Tab.Formatting(
66 | 'Helvetica', // Font
67 | 'default', // Font color
68 | 14, // 14pt size,
69 | true, // Bold
70 | false, // Italic
71 | false, // Underline
72 | false, // Conceal value
73 | false)) // Fixed width
74 | .withPosition(new dfsle.Tab.Position(
75 | 1, // The document to use
76 | 1, // Page number on the document
77 | 330, // X position
78 | 470, // Y position
79 | null, // Default width
80 | null)); // Default height
81 | //ds-snippet-end
82 |
83 |
84 | // Create a new recipient
85 | //ds-snippet-start:Apex5Step5
86 | dfsle.Recipient myRecipient = dfsle.Recipient.fromSource(
87 | 'Lily TheGSD', // Signer name
88 | 'lilythegsd@gmail.com', // Signer email
89 | null, // Signer phone number
90 | 'Signer 1', // Signer role
91 | null) // No Salesforce association
92 | .withTabs(new List { // Associate the tabs with this recipient
93 | myInitialHereTab,
94 | myTextTab,
95 | mySignHereTab,
96 | myDateSignedTab
97 | });
98 |
99 | // Add recipient to the envelope
100 | myEnvelope = myEnvelope.withRecipients(new List { myRecipient });
101 | //ds-snippet-end
102 |
103 | // Send the envelope
104 | //ds-snippet-start:Apex5Step6
105 | myEnvelope = dfsle.EnvelopeService.sendEnvelope(
106 | myEnvelope, // The envelope to send
107 | true); // Send now?
108 | //ds-snippet-end
109 | //ds-snippet-start:Apex5Step1
110 | }
111 | }
112 | //ds-snippet-end
--------------------------------------------------------------------------------