Auto Convert Marketing Qualified Leads

Auto Convert Marketing Qualified Leads

Last Updated on April 19, 2022 by Rakesh Gupta

Big Idea or Enduring Question:

How do you set automation to auto-convert marketing qualified leads? 

When there is a chance of further negotiations with a lead, it can be converted into an account, contact, optionally an opportunity. In short, once the lead status has reached a certain stage, it can be qualified as a potential. On conversion, all the lead details are transferred in creating an account, contact, and optionally an opportunity. The lead conversion process is a manual process, if you want to automate it then you have to use Apex code. This article will help you to understand how to automate the lead conversion process using the Lightning Flow. 

Objectives:

After reading this blog post, the reader will be able to:

  • Use After-save Record-Triggered Flow to auto-convert marketing qualified leads 
  • Understand @InvocableMethod Annotation
  • Use Schedule-Triggered Flow to call an Apex method

Business Use Case

Pamela Kline is working as a System administrator in Universal Container. She has received a requirement from the management to auto-convert marketing qualified  (i.e. leads with Rating = Hot) leads and create an account and contact record.

Automation Champion Approach (I-do):

While this can be solved using various automation tools like Apex or Process Builder and Apex, we will use After-save Record-Triggered Flow and call an Apex method. To call an Apex method, add the Call Action element to your flow and select an Apex class with a @InvocableMethod Annotation. It means they allow us to extend the Lightning Flow by writing Apex code that meets certain criteria and then invoking the Apex from our Flows. If the class contains one or more invocable variables, manually enter values or reference field values from a related record. @InvocableMethod Annotation supports bulk operations. Lets begin the solution for the business use case.
 
In this article, we will use the call LeadConvert database class from Apex code. Make sure to review it. 
 
Before discussing it, let me show you a diagram of a Process Flow at a high level. Please spend a few minutes to go through the following Flow diagram and understand it.
 

Let’s begin building this automation process.

Guided Practice (We-do):

There are 2 steps to solve Pamela’s business requirement using Lightning Flow. We must: 

  1. Create an Apex class and test class
  2. Lightning Flow Steps:
    1. Define flow properties for record-triggered flow
    2. Adding an action to Call an Apex Class

Step 1: Create an Apex class and Test class   

  1. Click Setup.
  2. In the Quick Find box, type Apex Classes.
  3. Clicks on the New button.
  4. Copy code from GitHub and paste it into your Apex Class. 
  5. Click Save.

Repeat the above steps and click the Test class. You can get the code from my GitHub repo. 

Step 2.1: Lightning Flow – Define Flow Properties 

  1. Click Setup.
  2. In the Quick Find box, type Flows.
  3. Select Flows then click on the New Flows.
  4. Select the Record-Triggered Flow option and click on Next and configure the flow as follows: 
    1. How do you want to start building: Freeform
    2. Trigger the Flow When: A record is created or Updated
    3. Run Flow: After the record is saved
    4. Object: Lead
  5. Select All Conditions Are Met (AND)
  6. Set Conditions
    1. Row 1
      1. Field: Lead | Rating
      2. Operator: Equals 
      3. Value: Hot
  7. Choose the Option to Only when a record is updated to meet the condition requirements.
  8. Click Done.

Step 2.2: Lightning Flow – Call an Apex Class

The next step is to call the AutoConvertLeads class from flow so that when flow fires it auto-convert the leads.

  1. Under Toolbox, select Element
  2. Drag-and-drop Action element onto the Flow designer. 
  3. In the Action box, type AutoConvertLeads.
  4. Clicks on the AutoConvertLeads apex class
  5. Enter a name in the Label field; the API Name will auto-populate.
  6. Set Input Values: 
    1. Row 1:
      1. LeadIs{!$Record.Id}
  7. Click Done.

In the end, Steven’s Flow will look like the following screenshot: Once everything looks good, perform the below steps: 

  1. Click Save.
  2. Enter Flow Label the API Name will auto-populate.
  3. Click Show Advanced.
  4. Type: Record-Triggered Flow
  5. API Version for Running the Flow: 50
  6. Interview Label: Auto Convert Leads {!$Flow.CurrentDateTime}
  7. Click Save

Almost there! Once everything looks good, click the Activate button.

Proof of Concept

Now onwards, if a business user updates the Lead Rating to Hot, Lightning Flow will automatically convert such leads and create an account as well as a contact. 

  1. Currently, the lead Gaurav Pradhan is Open and the Rating is Warm as shown in the following screenshot:
  2. Now we update the Rating to Hot and see the flow magic. 
  3. Flow auto converts the Lead and create an Account and Contact or it.

Note: –  I will suggest you implement this first in your developer org, test it and then move it to production. The same approach will work for the case assignment rule. Download Apex and Test class from GitHub. 

Process Builder Approach

Formative Assessment:

I want to hear from you!  

What is one thing you learned from this post? How do you envision applying this new knowledge in the real world? 

Let me know by Tweeting me at @automationchamp, or find me on LinkedIn.

Have feedback, suggestions for posts, or need more information about Salesforce online training offered by me? Say hello, and leave a message!

152 thoughts on “Auto Convert Marketing Qualified Leads

  1. Sure thing, thank you so much! I have three problems, I can’t use the apex class to convert leads and look for existing accounts. I have also tried to use the first code you have shared that just converts leads but the {!Record.ID} can’t be pulled on my flow. Finally I can’t add screenshots to this request

    For some context, I have used the second apex class provided in this page but I am not successful at adding the test class.
    I tried the test class as is but it didn’t work. I tried my version of it considering everything that is mandatory on my org and it doesn’t work either.
    I attached two screenshots: the first image is the apex class saved in my sandbox, the second image belongs to the test I tried using in my sandbox (which I can’t save because I get errors).

  2. Hi Rakesh,

    I was able to create the Apex class and activate it but when creating the flow I can’t seem to be able to set the Input Values to LeadIs: {!$Record.Id}. I can’t find this option, not sure why.

    Could you please help me?

    Thanks in advace

  3. Having lots of difficulty with this Apex test class for AutoConvertLeads1. In my sandbox everything worked perfectly until I had to use a test class and get that coverage. I’ve made a flow to launch my Apex action and need to trigger the test properly. My Code is copied below:

    Autoconvertleads1.cls

    Public class AutoConvertLeads1
    { @InvocableMethod(label = ‘Auto Convert Leads’)
    public static void LeadAssign(List requestList) {

    LeadStatus CLeadStatus= [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true Limit 1];
    List MassLeadconvert = new List();
    for (Requests req: requestList){
    Database.LeadConvert Leadconvert = new Database.LeadConvert();
    Leadconvert.setLeadId(req.LeadId);
    Leadconvert.setAccountId(req.AccountId);
    Leadconvert.setConvertedStatus(CleadStatus.MasterLabel);
    Leadconvert.setDoNotCreateOpportunity(TRUE); //Remove this line if you want to create an opportunity from Lead Conversion
    MassLeadconvert.add(Leadconvert);
    }
    if (!MassLeadconvert.isEmpty())
    {
    List lcr = Database.convertLead(MassLeadconvert);
    }
    }

    public class Requests {
    @InvocableVariable(label = ‘LeadId’ required = true)
    public id LeadId;

    @InvocableVariable(label = ‘AccountId’ required = false)
    public Id AccountId;

    }
    }

    My testclass / Testautoconvertleads1.cls

    @isTest
    public class TestAutoConvertLeads1 {
    static testMethod void createnewlead () {
    User userToCreate = [Select id from user where profile.Name =’System Administrator’ AND IsActive = TRUE Limit 1];

    Test.startTest();
    Lead leadToCreate = new Lead();
    List Ids = New List();
    leadToCreate.ownerid = ‘0058c00000CTYG4’;
    leadtoCreate.FirstName = ‘Steferoni’
    leadToCreate.LastName =’Motchell’;
    leadToCreate.Company =’Salesforce’;
    leadToCreate.LeadSource =’Apollo’;
    leadToCreate.org_id__c =’1234′;
    leadToCreate.Status =’Untouched’;
    leadtoCreate.email = ‘stef@testtero.com’;
    leadtoCreate.Send_to_Auto_Convert__c = true;
    insert leadToCreate;

    List requests = new List();
    AutoConvertLeads1.Requests request = new AutoConvertLeads1.Requests ();
    request.LeadId = leadToCreate.id;
    requests.add (request);

    AutoConvertLeads1.LeadAssign (requests);

    Test.stopTest ();
    }
    }

    My test is failing with an error message:

    System.DmlException: ConvertLead failed. First exception on row 0; first error: CANNOT_UPDATE_CONVERTED_LEAD, This lead was already converted to the contact Steferoni Motchell on 7/10/2022.: []

    Stack Trace: Class.AutoConvertLeads1.LeadAssign: line 17, column 1
    Class.TestAutoConvertLeads1.createnewlead: line 25, column 1

    Would do anything for some help to get this worked out. Thank you!

  4. Hello,
    I’m getting the following errors
    An Apex error occurred: System.DmlException: ConvertLead failed. First exception on row 0; first error: DUPLICATES_DETECTED, You are creating a duplicate record. We recommend you use an existing record instead.: []

    Any idea how to force convert the lead?

    Thank you!

  5. Hi, I’m getting this error when running the TEST autoconvertleads1 class. Do you have an idea about what might be the issue?

    System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Account_Leads__c]: [Account_Leads__c]

  6. Couple questions, I got the apex code/flow working in my sandbox to convert the leads. Question #1) how can I obtain the record ID of the new Contact that is created from this? I want to add some additional data to the contact record if possible. Question #2) Have not figured out how to write a flow to check for an existing account? Only thing I know to check is potentially Company name, but what if there are multiple?

      1. Such a cool solution, thanks for sharing this code, Rakesh! It works like a charm, however I’m also stuck with the same question Michael has: how would I obtain the converted contact Id?

        I also need this one to further use within my flow (specifically we want to relate the newly converted contact to an existing case plus also set some more information on the new contact which doesn’t come from the lead). Sorry, probably a stupid question, I’m fairly new to all things APEX – would I need to adjust the APEX class to pass the converted contact Id back to the flow or how would I go about and query it within the flow? Any hints on this would be greatly appreciated!

  7. Getting this error when running the test Error Message System.DmlException: Insert failed. First exception on row 0; first error: INACTIVE_OWNER_OR_USER, operation performed with inactive user [0050X000007tqcd] as owner of lead: []
    Stack Trace Class.TestAutoConvertLeads.createnewlead: line 15, column 1
    What does it mean

  8. Rakesh thanks for posting this. I’m new to writing Apex and I’m getting an error that the Owner ID cannot be blank? When trying to deploy the test in Production I received errors from a few Apex Tests. Additionally, is it possible to set a field value when the test is executed? I need to ensure that the Lead Status isn’t missing. It’s also giving me that error in the Deployment Status log. I appreciate any help you can provide.

    1. Hello Rakesh
      This is what I was looking for.
      Thank you for making such a wonderful proposal! !!
      But this apex class causes an error in my environment.
      The number of errors is huge and I don’t know how to tell them, but the most common error is “Unexpected token’List’.”.
      Please let me know if you have any good suggestions on how to avoid this error.
      I am Japanese and am writing this comment through translation, I hope it works.

            1. Thank you!!
              All errors have been successfully resolved.
              If possible, please release a test class for this code so that you don’t need to ask any questions in the future.

            2. Hello rakesh
              I have successfully written a test class for this new code.
              If there are people who need it as much as I do, I suggest adding this to your github.
              I hope it helps you a little.

              Thank you

              @isTest
              public class TestAutoConvertLeads1 {
              static testMethod void createnewlead () {
              User userToCreate = [Select id from user where profile.Name =’System Administrator’ AND IsActive = TRUE Limit 1];

              Test.startTest ();
              Lead leadToCreate = new Lead ();
              List Ids = New List ();
              leadToCreate.ownerid = userToCreate.id;
              leadToCreate.LastName =’Gupta’;
              leadToCreate.Company =’Salesforce’;
              leadToCreate.LeadSource =’Partner Referral’;
              leadToCreate.Rating =”;
              leadToCreate.Status =”;
              insert leadToCreate;

              List requests = new List ();
              AutoConvertLeads1.Requests request = new AutoConvertLeads1.Requests ();
              request.LeadId = leadToCreate.id;
              requests.add (request);

              AutoConvertLeads1.LeadAssign (requests);

              Test.stopTest ();
              }
              }

                  1. Thanks for such a swift reply Rakesh, unfortunately the GitHub post still has the formatting from the post in the comments above. The List type structure is missing, and all of the quotes are the wrong style. Would you happen to have a version which hasn’t been posted on the site already?

    2. Rakesh, will this code also contain both the ability to auto-convert new leads AND identify those that are already an account and update the existing account?

        1. Thank you Rakesh,

          This has been very useful. I have been reviewing the Test Classes that people have been putting together but I continue to get errors. Is there code for this test case specifically on the apex code listed above?

  9. I have the Class working, thank you for the code! However, I cannot get the test class to work. I keep getting this error when I run the tests:
    Methods defined as TestMethod do not support Web service callouts
    As a result I cannot push the Class and ClassTest to my Production org. I have been fighting with it for two days now. Any thoughts?

  10. I continue to get the same error when running the Apex Test Class –
    Methods defined as TestMethod do not support Web service callouts Stack Trace: null
    I cannot figure out how to fix it !

  11. How can we add the outputs to this code. I am trying to use this in a flow that updates the opportunity record type as well. I need the outputs from the method to do it. Any suggestions?

    1. Here are my suggestion:

      – Use Get Element to find the values of current Lead after calling above Apex Class
      – Add an Update Elements to uodate the account
      – Where Id = ConvertedOpportunityId, update the recordTypeId

    1. Were you getting the I have the “Methods defined as TestMethod do not support Web service callouts” error? That is what I am getting, and still cannot get it to work,

        1. Holy crap I feel stupid! I read through the debug log, and found an old managed package that was kicking it out. Uninstalled it, and now we are golden! Thank you very much for your help, and I love this new functionality!!

  12. This was extremely helpful! I did make one minor edit to the test class due to an error. On line 4:
    User userToCreate = [Select id from user where profile.name=’System Administrator’ Limit 1];’

    I changed it to:
    User userToCreate = [Select id from user where profile.name=’System Administrator’ AND IsActive=TRUE Limit 1];’

    Without the “IsActive” filter, it may try to assign the Lead to an inactive user, causing an error.

    Thanks for this!!

  13. Hey! Question, I need help on your previous video “Auto Convert Qualified Lead using Lightning Flows”.

    How did you setup that apex class? I can’t find where or how to do it.

    I go setup->Apex classes but there is no ‘New’ button. Just ‘Developer Console’, ‘Run All Tests’, and and ‘Schedule Apex’.

    I’ve tried going through Developer Console->File->New->Apex Class but after I ‘OK’ after giving it a name it says “ENTITY_IS_LOCKED Can not create Apex Class on an active organization.” . How do I get passed that?

  14. Even before I asked you I thought about it and myself did not like the fact that I have to create few processes to solve one problem.

  15. Hi Rakesh,

    Instead of involving Apex class for the above given problem, can we solve it using Record Triggered flows?.

    Here is what I was thinking..

    On the lead Object I can create Lead Converted field of type checkbox.

    1Have a before save update trigger on the lead object which will update checkbox field on the lead object as soon as Rating is Hot

    2)Then After save trigger on the lead object which will check whether the checkbox field on the Lead object has been checked if it is then create an Account record, mapping its field to the field on the lead object.

    3)Have another trigger After Save Update Trigger on the Lead Record which will be used to create contact record .

    Any suggestions?

    Thanks

    1. Good thought process. Nice work.

      Do you think having three Flows to solve one business requirement is an optimal solution when you can achieve it using one Flow with few lines of code?

  16. Hi Rakesh, I tried the test class provided in GitHub and it does not work. Can you help with Test Class for the code in this page?

  17. Hi, thank you for the great Idea. This is cool. At it is working already quiet well.

    May I ask one question: How can I adjust the process so that the auto-convert only fires for existing accounts? I don’t want that new accounts are created automatically.

    Here is the current apex:

    Public class AutoConvertLeadsAccount
    {
    @InvocableMethod
    public static void LeadAssign(List LeadList)
    {
    List LeadAcc = new List();
    for(Lead L : LeadList){
    LeadAcc.add(L.Company);
    }
    list AccList = [SELECT ID, Name FROM Account WHERE Name IN :LeadAcc];
    LeadStatus CLeadStatus= [SELECT Id, MasterLabel FROM LeadStatus WHERE IsConverted=true Limit 1];
    List MassLeadconvert = new List();
    for(Lead L : LeadList){
    Database.LeadConvert Leadconvert = new Database.LeadConvert();
    for(Account A : AccList){
    if(L.Company == A.Name){
    Leadconvert.setAccountId(A.Id);
    Leadconvert.setDoNotCreateOpportunity(TRUE);
    }else{
    Leadconvert.setDoNotCreateOpportunity(TRUE);
    }
    }
    Leadconvert.setLeadId(L.Id);
    Leadconvert.setConvertedStatus(CLeadStatus.MasterLabel);
    Leadconvert.setDoNotCreateOpportunity(TRUE);//Remove this line if you want to create an opportunity from Lead Conversion
    MassLeadconvert.add(Leadconvert);
    }

    if (!MassLeadconvert.isEmpty()) {
    List lcr = Database.convertLead(MassLeadconvert);
    }
    }
    }

    thank you.

    Best
    RB

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.