How to create a Conga Composer List View Button (Lightning Experience).

Conga does not support customized code. Due to the complicated nature of supporting programmers and programming languages, the integration of Conga with Visualforce, Apex, and Javascript (or other programming languages) is not supported. The example code used below is specific to the Opportunity and will only work for Opportunity list view.

Integration Method

You can integrate Composer within Salesforce Lightning using the following steps:

  1. Create an Apex Class to reference as a set controller.
  2. Create a Visualforce page with a set controller referencing the Apex Class.
  3. Create a new button and select Visualforce for type.
  4. Enable Display checkboxes (for Multi-Record Selection) and select Visualforce Page as the Content Source.
  5. Add the newly created button to the list in Search Layouts.


From Step 1, your Apex Class should look like this:

public class OpportunityCMController { 
private final static String urlFieldName = 'Conductor__c';
private String partnerServerUrl;
private ApexPages.StandardSetController controller;
private List<String> opportunityIds = new List<Id>();

public String CMUrl {get; private set;}

public OpportunityCMController(ApexPages.StandardSetController controller) {
this.controller = controller;

for (Opportunity opportunity : (List<Opportunity>)controller.getSelected()){
opportunityIds.add(opportunity.Id);
}

partnerServerUrl = 'https://'+ApexPages.currentPage().getHeaders().get('Host')+'/services/Soap/u/26.0/'+UserInfo.getOrganizationId();
}

public PageReference prepareCMUrl() {
CMUrl = 'https://composer.congamerge.com' + 
'?SessionId=' + UserInfo.getSessionID() +
'&ServerUrl=' + partnerServerUrl +
'&Id=' + UserInfo.getUserId() +
'&QueryId=[Opps]a0346000009N2DH?pv0=' + '\''+ String.join(new List<String>(opportunityIds),'\'|\'')+'\'';


return null;
}
}



And now the Visualforce Page should look like this:

<apex:page standardController="Opportunity" extensions="OpportunityCMController" recordSetVar="opportunities" action="{!prepareCMUrl}">
<apex:outputPanel id="script">
<script type="text/javascript">
window.open("{!CMUrl}","_blank","width=640,height=480");
window.history.back();
</script>
</apex:outputPanel>
</apex:page>



The Test Apex Class (if deploying in Production) should look like this:

/**
* @description Test Class for the OpportunityCMController Class
*/
@isTest
public with sharing class OpportunityCMControllerTest {
    /**
    * @description setup - test data setup method
    */
    @testSetup
    public static void setup(){
        List<Account> testAccounts = new List<Account>();
        List<Opportunity> testOpps = new List<Opportunity>();
/**** Test Account record creation ****/
/**** Fields shown here are required for a Salesforce Developer Org ****/
/**** Requires updates for any required fields you may have ****/
        Account a = new Account();
            a.Name = 'ABC Company, Inc.';
            a.BillingState = 'CO';
            a.NumberOfLocations__c = 1;
                testAccounts.add(a);
        Account acct = new Account();
            acct.BillingState = 'OR';
            acct.NumberOfLocations__c = 2;        
            acct.Name = 'XYZ Company, Inc.';
                testAccounts.add(acct);
/**** end test account records ****/
/**** Test Opportuinity record creation ****/
/**** Fields shown here are required for a Salesforce Developer Org ****/
/**** Requires updates for any required fields you may have ****/
        Opportunity opp1 = new Opportunity();
          opp1.Name = 'Test Opp 1';
          opp1.CloseDate = Date.newInstance(2020, 01, 01); 
          opp1.StageName = 'Negotiating';
          opp1.Amount = 1;
          opp1.AccountId = a.Id;
            testOpps.add(opp1);
        Opportunity opp2 = new Opportunity();
          opp2.Name = 'Test Opp 21';
          opp2.CloseDate = Date.newInstance(2020, 02, 02); 
          opp2.StageName = 'Negotiating';
          opp2.Amount = 2;
          opp2.AccountId = a.Id;
            testOpps.add(opp2);            
/**** end test Opportuinity records ****/
/**** Insert the Test Records ****/
        insert testAccounts;
        insert testOpps;
    }
    /**
    * @description testMethod1 - Test Happy Path of code
    */
    public static testMethod void testMethod1() {
        List<sObject> opps = (List<Opportunity>)[Select ID From Opportunity LIMIT 2];
          System.debug('********************* opps: ' + opps);
        ApexPages.StandardSetController ssc = new ApexPages.StandardSetController(opps);
          ssc.setSelected(opps);
        OpportunityCMController ocmc = new OpportunityCMController(ssc);
          ocmc.prepareCMUrl();
/**** Actually run the test ****/
/**** 100% coverage based upon "OpportunityCMController" Class provided on Conga's Support Site ****/
        Test.startTest();
          PageReference pr = ocmc.prepareCMUrl();
        Test.stopTest();
    }  
}



Sample Query Dataset referenced in the Apex Class controlled:

select name, amount, stagename from opportunity where id IN ({pv0})