Variations on inviting from Salesforce

Overview

Since our invite from Salesforce guide works off of the Conveyor API, we are able to easily customize the invite modal to your liking.

No NDA checkbox

If you would prefer to not show the NDA checkbox, simply use the below code in the InviteContact Apex Class we created:

public with sharing class InviteContact {
    // Fill this in with your API key:
    static final String apiKey = 'YOUR_KEY_HERE';
    
    static final String apiBase = 'https://api.conveyor.com/api/v2/';
    static final String postAuthorizationEndpoint = apiBase + 'exchange/authorizations';
    static final String fetchAccessGroupsEndpoint = apiBase + 'exchange/access_groups';
    
    @AuraEnabled
    public static String postAuthorization(Id contactId, String accessGroupIds){
        if(contactId == null){
            throw new MyException('Missing record ID');
        }

        List<Contact> contacts = [SELECT Email FROM Contact WHERE Id = :contactId];

        if(contacts.isEmpty() || String.isBlank(contacts[0].Email)){
            throw new MyException('Could not find the contact');
        }

        Contact c = contacts[0];
        String userName = UserInfo.getUserName();
        User activeUser = [Select Email From User where Username = : userName limit 1];
        String userEmail = activeUser.Email;

        HttpRequest req = new HttpRequest();
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.setHeader('X-API-KEY', apiKey);
        req.setEndpoint(postAuthorizationEndpoint);
        req.setMethod('POST');

        String reqBodyString = 'email=';
        reqBodyString += EncodingUtil.urlEncode(c.Email, 'UTF-8');
        reqBodyString += '&reviewer_email=';
        reqBodyString += EncodingUtil.urlEncode(userEmail, 'UTF-8');
        reqBodyString += '&access_group_ids=';
        reqBodyString += EncodingUtil.urlEncode(accessGroupIds, 'UTF-8');
        reqBodyString += '&nda_bypass=false';
        
        req.setBody(reqBodyString);

        HTTPResponse res = new Http().send(req);
        System.debug(res.getStatus());
        System.debug(res.getBody());

        return res.getBody();
    }
    
    @AuraEnabled
    public static String fetchAccessGroups(Id contactId){
        HttpRequest req = new HttpRequest();
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('X-API-KEY', apiKey);
        req.setEndpoint(fetchAccessGroupsEndpoint);
        req.setMethod('GET');

        HTTPResponse res = new Http().send(req);
        System.debug(res.getStatus());
        System.debug(res.getBody());

        return res.getBody();
    }

    public class MyException extends Exception{}
}

We removed this:

if (ndaBypass) {
    reqBodyString += 'true';
} else {
    reqBodyString += 'false';
}

And modified this:

...

// Removed the "Boolean ndaBypass" parameter
public static String postAuthorization(Id contactId, String accessGroupIds)

...

// Set this to "false" by default, but it can also be "true" if you want
reqBodyString += '&nda_bypass=false'; 

And then, in your Aura Component's "Component" section, use this code:

<aura:component controller="InviteContact" implements="force:hasRecordId,force:lightningQuickActionWithoutHeader" >
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:html tag="style">
        .cuf-content {
            padding: 0 0rem !important;
        }
        .slds-p-around--medium {
            padding: 0rem !important;
        }       
        .slds-modal__content{
            overflow-y:hidden !important;
            height:unset !important;
            max-height:unset !important;
        }
        .myCheckbox{
            display: inline-block;
            float: left;
        	margin-right: 10px;
        }
    </aura:html>
    
    <header class="slds-modal__header">
        <h2 id="modal-heading-01" class="slds-modal__title slds-hyphenate">Invite to Conveyor</h2>
    </header>
    
    <aura:attribute name="accessGroups" type="Map[]"/>
    <aura:attribute name="accessGroupIds" type="String[]"/>
    <div class="slds-modal__content slds-p-around_medium">
        <p>(Optional) Authorize this contact to view or download any need-to-know documents by adding the following access groups:</p>
        <br />
    	<aura:iteration items="{!v.accessGroups}" var="ag">
            <ui:inputCheckbox name="{!ag.id}" label="{!ag.name}" class="myCheckbox" change="{!c.onCheckAccessGroup}"/>
        </aura:iteration>        
    </div>    
    
    <footer class="slds-modal__footer">          
        <lightning:button name='Cancel' label='Cancel' onclick='{!c.closeModal}'/>
        <lightning:button variant="brand" name='Confirm' label='Invite' onclick='{!c.createAuth}'/>
    </footer>
</aura:component>

We removed:

<aura:attribute name="ndaBypass" type="Boolean"/>
<div class="slds-modal__content slds-p-around_medium">
    <p>If you already have an NDA on file, you can bypass the NDA so this contact doesn’t have to re-sign:</p>
    <br />
    <ui:inputCheckbox name="ndaBypass" label="Bypass the Rooms NDA for this user" class="myCheckbox" change="{!c.onCheckNdaBypass}"/>
</div>    

Then, in the "Controller" (second) section, use the following code:

({
    doInit : function(cmp) {
        let action = cmp.get('c.fetchAccessGroups');
        action.setCallback(this, function(response){
            let state = response.getState();
            if (state === "SUCCESS") {
                try {
                    var accessGroups = JSON.parse(response.getReturnValue()).access_groups;
                    var accessGroupNames = [];
                    cmp.set("v.accessGroups", accessGroups);
                } catch (e) {
                    console.log(e)
                }
            } else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        $A.enqueueAction(action);
    },
    onCheckNdaBypass : function(cmp, event) {
        var checked = event.getSource().get("v.value");
        cmp.set("v.ndaBypass", checked);
    },
    onCheckAccessGroup : function(cmp, event) {
        var currentAccessGroups = cmp.get('v.accessGroupIds');
        var id = event.getSource().get("v.name");
        var checked = event.getSource().get("v.value");
        
        if (checked) {
	        currentAccessGroups.push(id);
        } else {
            var index = currentAccessGroups.indexOf(id);
            currentAccessGroups.splice(index, 1);
        }

        cmp.set("v.accessGroupIds", currentAccessGroups);
    },
    createAuth : function(cmp) {
        let action = cmp.get('c.postAuthorization');
        var currentAccessGroups = cmp.get('v.accessGroupIds');
        var accessGroupIds = currentAccessGroups.join(',');
        action.setParams(
            {
                contactId : cmp.get('v.recordId'),
                accessGroupIds : accessGroupIds
            }
        );
        action.setCallback(this, function(response){
            let state = response.getState();
            if (state === "SUCCESS") {
                let returnValue = "Successfully invited contact to Conveyor"
                try {
                    var jsonReturnValue = JSON.parse(response.getReturnValue());                    
                    
                    if (jsonReturnValue.error) {
                        returnValue = jsonReturnValue.error;
                    }
                } catch (e) {
                    console.log(e)
                }

                alert(returnValue)
                
                // Close the modal
                $A.get("e.force:closeQuickAction").fire();
            } else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        $A.enqueueAction(action);
    },
    closeModal : function(cmp) {
        $A.get("e.force:closeQuickAction").fire();
    }
})

We removed the following from the createAuth function:

var ndaBypass = cmp.get('v.ndaBypass');

And the action.setParams is now:

action.setParams(
    {
        contactId : cmp.get('v.recordId'),
        accessGroupIds : accessGroupIds
    }
);

Note that you can leave the onCheckNdaBypass function if you want. It will no longer be called, so it won't affect anything.

No Access Groups either

If you also don't want to show the access group checkboxes, you can use the following in the InviteContact Apex Class we created:

public with sharing class InviteContact {
    // Fill this in with your API key:
    static final String apiKey = 'iiqEWo2BPsxi5c4zOYBkv7zu_DybQ5L6hl0JVGvM1AM';
    
    static final String apiBase = 'https://api.conveyor.com/api/v2/';
    static final String postAuthorizationEndpoint = apiBase + 'exchange/authorizations';
    static final String fetchAccessGroupsEndpoint = apiBase + 'exchange/access_groups';
    
    @AuraEnabled
    public static String postAuthorization(Id contactId){
        if(contactId == null){
            throw new MyException('Missing record ID');
        }

        List<Contact> contacts = [SELECT Email FROM Contact WHERE Id = :contactId];

        if(contacts.isEmpty() || String.isBlank(contacts[0].Email)){
            throw new MyException('Could not find the contact');
        }

        Contact c = contacts[0];
        String userName = UserInfo.getUserName();
        User activeUser = [Select Email From User where Username = : userName limit 1];
        String userEmail = activeUser.Email;

        HttpRequest req = new HttpRequest();
        req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
        req.setHeader('X-API-KEY', apiKey);
        req.setEndpoint(postAuthorizationEndpoint);
        req.setMethod('POST');

        String reqBodyString = 'email=';
        reqBodyString += EncodingUtil.urlEncode(c.Email, 'UTF-8');
        reqBodyString += '&reviewer_email=';
        reqBodyString += EncodingUtil.urlEncode(userEmail, 'UTF-8');
        reqBodyString += '&nda_bypass=false';
        
        req.setBody(reqBodyString);

        HTTPResponse res = new Http().send(req);
        System.debug(res.getStatus());
        System.debug(res.getBody());

        return res.getBody();
    }
    
    @AuraEnabled
    public static String fetchAccessGroups(Id contactId){
        HttpRequest req = new HttpRequest();
        req.setHeader('Content-Type', 'application/json');
        req.setHeader('X-API-KEY', apiKey);
        req.setEndpoint(fetchAccessGroupsEndpoint);
        req.setMethod('GET');

        HTTPResponse res = new Http().send(req);
        System.debug(res.getStatus());
        System.debug(res.getBody());

        return res.getBody();
    }

    public class MyException extends Exception{}
}

We removed:

reqBodyString += EncodingUtil.urlEncode(userEmail, 'UTF-8');
reqBodyString += '&access_group_ids=';

And we modified:

...

// Removed the "String accessGroupIds" parameter
public static String postAuthorization(Id contactId)

...

And then, in your Aura Component's "Component" section, use this code:

<aura:component controller="InviteContact" implements="force:hasRecordId,force:lightningQuickActionWithoutHeader" >
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
    <aura:html tag="style">
        .cuf-content {
            padding: 0 0rem !important;
        }
        .slds-p-around--medium {
            padding: 0rem !important;
        }       
        .slds-modal__content{
            overflow-y:hidden !important;
            height:unset !important;
            max-height:unset !important;
        }
        .myCheckbox{
            display: inline-block;
            float: left;
        	margin-right: 10px;
        }
    </aura:html>
    
    <header class="slds-modal__header">
        <h2 id="modal-heading-01" class="slds-modal__title slds-hyphenate">Invite to Conveyor</h2>
    </header>
    
    <div class="slds-modal__content slds-p-around_medium">
        <p>Invite this contact to our Trust Portal on Conveyor</p>
    </div>
    
    <footer class="slds-modal__footer">          
        <lightning:button name='Cancel' label='Cancel' onclick='{!c.closeModal}'/>
        <lightning:button variant="brand" name='Confirm' label='Invite' onclick='{!c.createAuth}'/>
    </footer>
</aura:component>

We removed:

<aura:attribute name="accessGroups" type="Map[]"/>
<aura:attribute name="accessGroupIds" type="String[]"/>
<div class="slds-modal__content slds-p-around_medium">
    <p>(Optional) Authorize this contact to view or download any need-to-know documents by adding the following access groups:</p>
    <br />
    <aura:iteration items="{!v.accessGroups}" var="ag">
        <ui:inputCheckbox name="{!ag.id}" label="{!ag.name}" class="myCheckbox" change="{!c.onCheckAccessGroup}"/>
    </aura:iteration>
</div>

And added the following, so it's not just a blank modal:

<div class="slds-modal__content slds-p-around_medium">
    <p>Invite this contact to our Trust Portal on Conveyor</p>
</div>

Then, in the "Controller" (second) section, use the following code:

({
    doInit : function(cmp) {
        let action = cmp.get('c.fetchAccessGroups');
        action.setCallback(this, function(response){
            let state = response.getState();
            if (state === "SUCCESS") {
                try {
                    var accessGroups = JSON.parse(response.getReturnValue()).access_groups;
                    var accessGroupNames = [];
                    cmp.set("v.accessGroups", accessGroups);
                } catch (e) {
                    console.log(e)
                }
            } else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        $A.enqueueAction(action);
    },
    onCheckNdaBypass : function(cmp, event) {
        var checked = event.getSource().get("v.value");
        cmp.set("v.ndaBypass", checked);
    },
    onCheckAccessGroup : function(cmp, event) {
        var currentAccessGroups = cmp.get('v.accessGroupIds');
        var id = event.getSource().get("v.name");
        var checked = event.getSource().get("v.value");
        
        if (checked) {
	        currentAccessGroups.push(id);
        } else {
            var index = currentAccessGroups.indexOf(id);
            currentAccessGroups.splice(index, 1);
        }

        cmp.set("v.accessGroupIds", currentAccessGroups);
    },
    createAuth : function(cmp) {
        let action = cmp.get('c.postAuthorization');
        action.setParams(
            {
                contactId : cmp.get('v.recordId')
            }
        );
        action.setCallback(this, function(response){
            let state = response.getState();
            if (state === "SUCCESS") {
                let returnValue = "Successfully invited contact to Conveyor"
                try {
                    var jsonReturnValue = JSON.parse(response.getReturnValue());                    
                    
                    if (jsonReturnValue.error) {
                        returnValue = jsonReturnValue.error;
                    }
                } catch (e) {
                    console.log(e)
                }

                alert(returnValue)
                
                // Close the modal
                $A.get("e.force:closeQuickAction").fire();
            } else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
					console.log(errors);
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + errors[0].message);
                    }
                } else {
                    console.log(errors);
                }
            }
        });
        $A.enqueueAction(action);
    },
    closeModal : function(cmp) {
        $A.get("e.force:closeQuickAction").fire();
    }
})

We removed the following from the createAuth function:

var currentAccessGroups = cmp.get('v.accessGroupIds');
...
var accessGroupIds = currentAccessGroups.join(',');

And the action.setParams is now:

action.setParams(
    {
        contactId : cmp.get('v.recordId')
    }
);

Note that you can leave the onCheckAccessGroup function if you want. It will no longer be called, so it won't affect anything.