Salesforce - Configure Incoming Webhook to Trigger a Flow

Moxo’s incoming webhook integration allows you to automatically kick off Moxo flows based on triggers in Salesforce. 

This guide will walk you through how to configure Moxo’s incoming webhook integration in Salesforce by creating an Apex trigger and calling the Moxo webhook via an Apex class. 

Step-by-Step Instructions:

  1. Identify the Trigger Event in Salesforce:
    • Determine which Salesforce object (e.g., Lead, Contact, Opportunity) will trigger the Moxo webhook. For example, you might want to trigger a Moxo flow when an Opportunity moves to Closed Won.
    • You'll be creating an Apex trigger for this object to send the webhook request.
  2. Create an Apex Trigger:
    • In Salesforce, navigate to Setup > Apex Triggers.
    • Create a new Apex Trigger for the object you want to use (e.g., Opportunity). Here’s an example of a trigger that will fire when an Opportunity moves to Closed Won:
      trigger OpportunityTrigger on Opportunity (after update) {
        for (Opportunity opp : Trigger.new) {
            if (opp.StageName == 'Closed Won' && Trigger.oldMap.get(opp.Id).StageName != 'Closed Won') {
                MoxoWebhookClass.sendMoxoWebhook(opp);
            }
        }
      }
  1. Create an Apex Class to Call Moxo’s Webhook:
    • Now, create an Apex class that sends a POST request to the Moxo webhook. This class will handle the actual HTTP callout.
    • Navigate to Setup > Apex Classes, and click New. Here’s an example of how to structure the Apex class:
      public class MoxoWebhookClass {
         @future(callout=true)
          public static void sendMoxoWebhook(Id oppId) {

             // Query the Opportunity and related data
              Opportunity opp = [SELECT Id, Name, Owner.Email, Owner.FirstName, Owner.LastName, AccountId 

                                 FROM Opportunity WHERE Id = :oppId];
                    
              List<Contact> contacts = [SELECT Email, FirstName, LastName 

                                        FROM Contact WHERE AccountId = :opp.AccountId];

             // Ensure there is at least one contact to use
             if (contacts.isEmpty()) {
                 System.debug('No contacts found for this opportunity\'s account.');
                 return;
             }
              Contact firstContact = contacts[0];  // Use the first contact for the request

             // Initialize HTTP request
             HttpRequest triggerFlowRequest = new HttpRequest();
             triggerFlowRequest.setEndpoint({Your_Moxo_Webhook_URL});  // Your actual Moxo webhook endpoint
             triggerFlowRequest.setMethod('POST');
             triggerFlowRequest.setHeader('Content-Type', 'application/json');
              triggerFlowRequest.setHeader('auth-mx', 'auth-secret');  // Replace with your actual auth secret

             // Build the JSON body for the webhook request
             String emailString = firstContact.Email;
             String jsonBody = '{';
             jsonBody += '"reference_id": "' + opp.Id + '",';
             jsonBody += '"workspace_name": "Client Onboarding - ' + opp.Name + '",';
             jsonBody += '"viewer.emails": "' + emailString + '",';
             jsonBody += '"workspace_owner": "' + opp.Owner.Email + '",';  // Workspace owner email comes from Opportunity Owner
             jsonBody += '"role.account_manager.email": "' + opp.Owner.Email + '",';
             jsonBody += '"role.client.email": "' + firstContact.Email + '",';
             jsonBody += '"role.client.user_name": "' + firstContact.FirstName + ' ' + firstContact.LastName + '",';
             jsonBody += '"role.account_manager.user_name": "' + opp.Owner.FirstName + ' ' + opp.Owner.LastName + '"';
             jsonBody += '}';
              triggerFlowRequest.setBody(jsonBody);

             // Send the HTTP request
              Http http = new Http();

              HttpResponse res = http.send(triggerFlowRequest);

             // Log the response for debugging
             if (res.getStatusCode() == 200) {
                 System.debug('Moxo API call successful.');
             } else {
                 System.debug('Failed to send Moxo webhook: ' + res.getStatusCode() + ' ' + res.getBody());
             }
         }
      }

 

Ensure the placeholder for {Your_Moxo_Webhook_URL} is replaced with the actual incoming webhook URL provided by Moxo.  

This example Apex class assumes API Key authentication, which allows you to configure a name and key value in Moxo that you also set in the HTTP request header. For example, if the key is “auth-mx” and the value is “auth-secret”, then the header will be “auth-mx:auth-secret”. Moxo also supports basic authentication.

It also assumes a structure where the primary contact for a client is listed under an Account associated with an Opportunity. In this example, the first contact related to the Opportunity's Account is used. If your Salesforce implementation uses Contact Roles (where contacts are assigned specific roles in relation to an Opportunity), you can modify this code to leverage the Contact Roles object to better identify the primary contact 

Depending on your Moxo flow template, you may need to customize the properties in the request body to match the fields Moxo expects. Make sure the property keys in the request body map to the correct fields in Salesforce.

  1. Test Your Webhook Configuration:
    • Test the Apex trigger and class to ensure that when a Opportunity is moved to Closed Won, the Moxo webhook is triggered successfully.
    • Use Salesforce Developer Console to monitor logs and verify if the HTTP callout is performed correctly.
  2. Review Required Permissions:
    • Ensure that your Salesforce org has proper callout permissions. You can do this by navigating to Setup > Remote Site Settings and adding the Moxo webhook URL as an approved remote site to allow Salesforce to send outbound requests.
  3. Deploy Your Trigger and Class:
    • Once you've tested and confirmed that the trigger works as expected, deploy it to production.


By following this guide, you’ll successfully integrate Moxo’s incoming webhooks with Salesforce using Apex triggers and classes, to automatically kick off Moxo workspaces based on triggers in Salesforce.