Search code examples
salesforce

Is it possible to create a Salesforce URL custom button that sends some POST data to a url endpoint before redirecting the user to a different page?


In Salesforce, I'm trying to create a URL custom button that accomplishes 2 things:

  1. Sends a small data payload to a url endpoint such as https://example1.com/example1.php. But the user should never be redirected to this page.

  2. After #1 has completed above, redirect the user to the actual desired url of an apex path to a component in my org.

I can get #1 to work if I create a JavaScript button and use REQUIRESCRIPT with an enclosed POST method using XMLHttpRequest().

I can also get #2 to work, but in a separate URL button using URLFOR syntax.

But I'm not sure if it's possible to combine the two behaviors in a single button. I know I can't use both REQUIRESCRIPT and URLFOR in the same button, so that idea is out the window.

{!REQUIRESCRIPT("/soap/ajax/37.0/connection.js")} // Required Salesforce script for making API calls

  function sendCustomData() {
    // Define the data to be sent to the other endpoint
    var customData = {
        'field1': 'value1',
        'field2': 'value2'
    };
    
    // Make an HTTP POST request to the desired endpoint with the custom data
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "https://example1.com/example1.php", true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.send(JSON.stringify(customData));
  }
sendCustomData();
{!URLFOR('/apex/my_component', null, [
    SourceID=Account.Id,
    PARAM1='Email~john.doe@example.com',
    PARAM2='Something'
  ])}

The only other option I can think of is to create a new URLFOR button that directs the user to a custom Visualforce page, and then handle both requests from that page to:

  1. Post the data to endpoing #1; then
  2. auto-redirect the user to the desired URL I was trying to construct in my original URLFOR button.

Am I thinking this through correctly? I'd prefer to avoid a custom Visualforce page, but just trying to confirm if I'm on the right track.

EDIT:

Here's the visualforce page route I was thinking of. The url in window.location.replace would need to be revised to not flag CSRF and to include the appropriate token, like a properly formatted URLFOR button would do. Which is why I'd like to avoid that route as well because for step 2 (the page I actually need the user redirected to) it'd have to be executed as if they clicked on a functional URLFOR button.

STEPS:

  1. Create a new Visualforce page called myPage:
<apex:page >
    <apex:includeScript value="https://code.jquery.com/jquery-3.6.0.min.js"/>
    <script>
        $(function() {
            // Send data via AJAX POST request
            $.ajax({
                url: 'https://example1.com/page1.php',
                type: 'POST',
                data: {
                    // data to be sent via POST
                }
            });
            // Redirect user to https://example2.com/page2.php
            window.location.replace('https://example2.com/page2.php');
        });
    </script>
</apex:page>
  1. Create a URL button that redirects to the myPage Visualforce page:
{!URLFOR('/apex/myPage')}

Solution

  • What exactly do you need connection.js for? XMLHttpRequest is a JS built-in, not something coming from that library.

    Have you tried merging them this way?

    function sendCustomData() {
        // Define the data to be sent to the other endpoint
        var customData = {
            'field1': 'value1',
            'field2': 'value2'
        };
        
        // Make an HTTP POST request to the desired endpoint with the custom data
        var xhr = new XMLHttpRequest();
        xhr.open("POST", "https://example1.com/example1.php", true);
        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.send(JSON.stringify(customData));
      }
    sendCustomData();
    
    location.href = `{!URLFOR('/apex/my_component', null, [
        SourceID=Account.Id,
        PARAM1='Email~john.doe@example.com',
        PARAM2='Something'
      ])}`;
    

    or any combination like waiting for call to complete and in callback (Promises?) do the redirect...

    Like vanilla js ;) "Make an AJAX call" but with redirect instead of alert