Skip to main content
Act-On Software

Legacy Process - Posting External Forms Using Classic Forms

The best way to collect customer data in Act-On is through our native forms. If your website uses a custom form that cannot be rebuild in Act-On, it is possible to push that form's submissions into the Act-On system.

 

Important note

There is an improved version of this process, available here.

This documentation should only be used by customers who have an existing implementation of this process.

 

For most simple webforms that have an existing database where submissions are posted to, we advise one of the below methods because these will pass information to Act-On transparently in the background, without affecting the URL your website visitors see once they complete the form (unlike the Action URL method described earlier).

Additionally, the JavaScript methods enable stronger validation against bot or blank submissions because they rely on your form's pre-existing validation.

Act-on offers a small script which will capture form submissions for custom HTML-based web forms and then pass along the submitted data to Act-On by programmatically scanning for submissions to your selected form. Form submissions will be captured only after they have passed validation if your validation code is client-side.

Notes:

  • For most forms already writing submission data to an external database, this is the easiest method and requires no adjustment of your existing form (other than adding the script somewhere within your web page). It is also designed to only function after your custom form validation has occurred.
  • Will pass form submitters to the post-submit response page that is defined within your own systems (the post-submit redirect is not handled by Act-On, unlike the action URL method)
  • May not work with forms that use 'onclick' functionality within the Submit button element
  • Forms with server-side verification are not compatible
  • Forms that utilize AJAX or have multiple submit events are not compatible
  • This script is very unlikely to work with multi-page forms, payment forms, login forms, or membership forms 

Step 1

For each form this is used with, we need an equivalent 'mirror' version of the form to be created within Act-On. For example, if a custom form on your website captures First Name, Last Name, and Email, you'll need to create a form within Act-On that also requests these fields. Your website visitors will never see this Act-On variant of your form -- we simply need to receive your custom form’s data.

Step 2

Next, you'll want to make sure the input names match so that information can be passed properly. In the form builder, you'll see an Edit button appear when hovering over any form field. Click Edit, and take a look at 'Data Field Name' on the resulting pop-up menu. You want to ensure that your 'Data Field Name' matches your custom form's HTML input name.

For example, if your First Name field in Act-On has a Data Field Name of 'fname', you'll want your custom form HTML to contain '<input name='fname'... ' for the equivalent field.

If you make any changes, be sure to click Next twice in the Act-On form builder until you get to the last step, where you can save your form.

Step 3

You'll want to copy your Act-On form's public URL. This is located under Content > Forms. Hover over your form and click the drop down arrow... > Get Public URL.

Step 4

When you have your specific URL, you'll want to grab these elements from the form’s public URL to plug into the script below:

  • Your server domain and subdomain, if applicable (such as yourcomapnyname.actonsoftware.com, or marketing.companyname.com if you use a custom URL for your account -- do not include 'http' or 'www' before the domain, or any characters after '.com' or '.org')
  • AID (Account ID) -- This will never change for your account
  • FID (Form ID) -- This will iterate for each unique form you have
  • DID (Data ID) -- This will most likely not change

Your form’s public URL will look like this. See the areas below in square brackets that contain the AID, FID, and DID:

http://[server]/acton/form/[aid]/[fid]:[did]/0/index.htm

and then fill it into the script in step 5.

Step 5

Please take a look the following script. However, before it is embedded on your web page, you’ll want to ensure the wwww, xxxx, yyyy, zzzz, and server elements are configured below:

<script type="text/javascript">
var aoProtocol = location.protocol;
if ( aoProtocol.indexOf('http') < 0 ) aoProtocol = 'http:';
var aoCAP = {
aid: 'wwww',
fid: 'xxxx',
did: 'd-yyyy',
server: 'your_subdomain_and_domain_here_without_http://www',
formName: 'zzzz',
protocol: aoProtocol
};
document.write( '<script type="text/javascript" src="'+aoCAP.protocol+'//'+aoCAP.server+'/acton/js/formcap.min.js"><'+'/script>' );

</script>

Above: Replace wwww with your AID, xxxx with your FID, and yyyy with your DID from your Act-On form's custom URL. These three elements are all present in your Act-On form’s public URL, as shown in step 4.

Step 6

Lastly, replace zzzz in step 5 with your custom form's name. This particular element is not from within your Act-On account -- it is present within your custom form’s HTML. For example, if you view the source of your form you should see something similar to <form name="formNameExample">.

Please note:

You can change “formName” to “formId” to use your custom form’s ID attribute, if instead you see <form ID="formIdExample">\

Formcap.js frequently asked questions

What if I don't see an ID or name attribute inside the <form> tag?

This script requires a name="nameExample" or id="idExample" inside your <form> tag (within your custom form's HTML) in order to be able to target your form. To successfully integrate with this JavaScript-based external post method, you will need to add one of these attributes to your form's HTML inside the <form> tag.

Where should I place this script?

It can be placed anywhere on your page where JavaScript can run (head or body), though we advise placing it at the foot of your page.

What if I place this script on a page that doesn't contain the correct form?

The external formcap.js script will load, but it will take no action and there should not be any detrimental effect on your web page.

Can I use this multiple times on the same page because I have more than one form per web page?

There is no harm in using multiple formcap.js scripts on the same web page.

One function of this script is that it will load the full formcap.js external script located at http://www.yoursubdomain.domain.com/acton/js/formcap.js on your page once per page-load, so multiple instances of the above script will load that external script multiple times. If you want to save the few Kilobytes of redundancy this would create, all you need to do is omit the document.write line from the extra instances of the script to avoid this redundant file loading.

Yes -- these properties are case-sensitive because Javascript is case-sensitive. These are properties of the script itself, and don't correspond to your form's HTML capitalization. For example, you can use <form id="myID"> or <form ID="myID"> or <form name="myName"> or <form NAME="myName"> and so on.

Go to the URL with your custom form, submit the form, and check the Developer tools or Javascript console in your browser. Most often, the source of the problem is a syntax error such as a missing single-quote. The developer interface of your browser should highlight any script errors it catches. If it still is not functioning or you see an unrelated error, please contact support@actonsoftware.com.

  • Solutions to some common console errors:
    • "SyntaxError: Expected token '}'" is caused by a missing quote. Please ensure all single quotes or double quotes are properly paired (every opening quote needs a closing quote of the same type). This also may be caused by a smart quote, which should be replaced with a single quote.
    • "Property ‘submit’ of object #<HTMLFormElement> is not a function" is caused by your form's submit button having a name attribute of "submit". Please avoid using "submit" as your form input names.
 Completed examples

Simple custom form HTML script

Simple custom form HTML script

<!-- EXAMPLE PUBLIC URL FOR ACT-ON FORM, built using the form builder -->
http://www.marketing.actomatic.com/acton/form/1234/0002:d-0001/0/in...

<!-- simple EXTERNAL form example that would be hosted elsewhere -->
<form name='contactUs'>
<!-- remember to replace the action URL in this example with your own, obtained through Reports > Forms and Media -->
<input name='firstname" type='text' placeholder='First Name'>
<input name="lastname" type="text" placeholder='Last Name'>
<input name='email' type='text' placeholder='Email'>
<input type='submit' value='submit' >
</form>

<!-- script below to place on the webpage containing your custom external form -->
<script>
var aoProtocol = location.protocol;
if ( aoProtocol.indexOf('http') < 0 ) aoProtocol = 'http:';
var aoCAP = {
aid: '1234',
fid: '0002',
did: 'd-0001',
server: 'marketing.actomatic.com',
formName: 'contactUs',
protocol: aoProtocol,
};
document.write( '<script type="text/javascript" src="'+aoCAP.protocol+'//'+aoCAP.server+'/acton/js/formcap.min.js"><'+'/script>' );
</script>

<!-- EXAMPLE PUBLIC URL FOR ACT-ON FORM, built using the form builder -->
http://www.yourcompanyname.actonsoftware.com/acton/form/4321/003b:d...

<!-- simple EXTERNAL form example that would be hosted elsewhere -->
<form ID='freeTrial'>
<input name="firstname" type="text" placeholder='First Name'>
<input name='lastname' type='text' placeholder='Last Name'>
<input name='email' type='text' placeholder='Email'>
<input type='submit' value='submit' >
</form>


<!-- script below to place on the webpage containing your custom external form -->
<script>
var aoProtocol = location.protocol;
if ( aoProtocol.indexOf('http') < 0 ) aoProtocol = 'http:';
var aoCAP = {
aid: '4321',
fid: '003b',
did: 'd-0001',
server: 'yourcompanyname.actonsoftware.com',
formId: 'freeTrial',
protocol: aoProtocol,
};
document.write( '<script type="text/javascript" src="'+aoCAP.protocol+'//'+aoCAP.server+'/acton/js/formcap.min.js"
 <'+'/script>' );
</script>

Advanced (customizable function for your form validation)

The above formcap.js script implementation is appropriate for the vast majority of online forms. However, it attempts to be fully automated. In the case of more complex forms (such as forms using ajax or other server-side validation functionality), the above formcap.js script has been customized below to fire when called and not attempt to "wait" for the form submit event. 

If you use one of many form ajax implementations for example, you have a "success" code path, where Javascript can be run upon successful form field validation by your own validation system. This script is designed to be called from the "success" code path, or at any other time once the fields have been validated already but before the user has been redirected to a different URL.

Notes: 

  • May not work with forms that use 'onclick' functionality within the Submit button element
  • Forms with server-side verification are not compatible
  • Forms that utilize AJAX or have multiple submit events are not compatible
  • This script is very unlikely to work with multi-page forms, payment forms, login forms, or membership forms 

Step 1

For each form this is used with, we need an equivalent 'mirror' version of the form to be created within Act-On. For example, if a custom form on your website captures First Name, Last Name, and Email, you'll need to create a form within Act-On that also requests these fields. Your website visitors will never see this Act-On variant of your form -- we simply need to receive your custom form’s data.

Step 2

Next, you'll want to make sure the input names match so that information can be passed properly. In the form builder, you'll see an Edit button appear when hovering over any form field. Click Edit, and take a look at 'Data Field Name' on the resulting pop-up menu. You want to ensure that your 'Data Field Name' matches your custom form's HTML input name.

For example, if your First Name field in Act-On has a Data Field Name of 'fname', you'll want your custom form HTML to contain '<input name='fname'... ' for the equivalent field.

If you make any changes, be sure to click Next twice in the Act-On form builder until you get to the last step, where you can save your form.

Step 3

You'll want to copy your Act-On form's public URL. This is located under Content > Forms. Hover over your form and click More... > Get Public URL.

Step 4

When you have your specific URL, you'll want to grab these elements from the form’s public URL to plug into the script below:

  • Your server domain and subdomain, if applicable (such as yourcomapnyname.actonsoftware.com, or marketing.companyname.com if you use a custom URL for your account -- do not include 'http' or 'www' before the domain, or any characters after '.com' or '.org')
  • AID (Account ID) -- This will never change for your account
  • FID (Form ID) -- This will iterate for each unique form you have
  • DID (Data ID) -- This will most likely not change

Your form’s public URL will look like this. See the areas below in square brackets that contain the AID, FID, and DID:

http://[server]/acton/form/[aid]/[fid]:[did]/0/index.htm

and then fill it into the script in step 5.

Step 5

Please take a look the following script. However, before it is embedded on your web page, you’ll want to ensure the wwww, xxxx, yyyy, zzzz, and server elements are configured below

<script type="text/javascript">
var aoProtocol = location.protocol;
if ( aoProtocol.indexOf('http') < 0 ) aoProtocol = 'http:';
var aoCAP = {
aid: 'wwww',
fid: 'xxxx',
did: 'd-yyyy',
server: 'your_subdomain_and_domain_here_without_http://www',
formName: 'zzzz',
protocol: aoProtocol
};
var aoArr = aoArr || []; aoArr.push(aoCAP);

</script>

Above: Replace wwww with your AID, xxxx with your FID, and yyyy with your DID from your Act-On form's custom URL. These three elements are all present in your Act-On form’s public URL, as shown in step 4.

If you have used formcap.js before, please note how the above script is the same as the one employed formcap.js, with the exception of the last line (starting with var aoArr).

Step 6

Lastly, replace zzzz above with your custom form's name. This particular element is not from within your Act-On account -- it is present within your custom form’s HTML. For example, if you view the source of your form you should see something similar to <form name="formNameExample">.

Please note:

You can change “formName” to “formId” to use your custom form’s ID attribute, if instead you see <form ID="formIdExample">

Step 7

Paste the following second script somewhere else in your webpage (preferable above the first script in your code you created in the earlier steps):

function AoProcessForm(formelement) {

for (AoI = 0; AoI < aoArr.length; AoI++) {
  if ( aoArr[AoI].aid && aoArr[AoI].fid && aoArr[AoI].did && aoArr[AoI].server && ( aoArr[AoI].formId || aoArr[AoI].formName )) {
    var d = document,
    thisFormId = formelement.id || '',
    thisFormName = formelement.name || '',
    bi = function(i) {
      return d.getElementById(i)
    },
    bn = function(i) {
      return d.getElementsByName(i)[0]
    },
    names = [],
    values = [],
    params = {},
    w = window,
    targetIdOrName = aoArr[AoI].formName ? bn(aoArr[AoI].formName) : bi(aoArr[AoI].formId),
    len = targetIdOrName.elements.length,
    isLoaded = false,
    ud = 'undefined',
    st = function(f, i) {
      w.setTimeout(f, i)
    },
    ce = function(t) {
      return d.createElement(t)
    },
    gid = function(p) {
      var j, i = 0,
      n = Math.random,
      r = [],
      c = '0123456789abcdef'.split('');
      for (; i < 16; i++) r[i] = c[(0 | n() * 16) & 0xf];
      j = p + r.join('');
      return bi(j) == null ? j : gid(p);
    },
    addInput = function( form, name, value )
    {
      var el = ce('input');
      el.name = name;
      el.value = value;
      form.appendChild( el );
    },
    idifr = gid('aoCapT');

    if (aoArr[AoI].formName == thisFormName || aoArr[AoI].formId == thisFormId) {
      var dTarget = ce('div');
      dTarget.style.display = 'none';
      d.body.appendChild(dTarget);
      dTarget.innerHTML = '<iframe name="' + idifr + '" id="' + idifr + '"><\/iframe>'; // generate iframe

      var dForm = ce('form'), idform = gid('aoCapD');
      dForm.id = idform;
      dForm.style.display = "none";
      dForm.method = 'POST';
      dForm.enctype = 'multipart/form-data';
      dForm.acceptCharset = 'UTF-8';
      dForm.target = idifr; // form targets iframe
      dForm.action = (aoCAP.protocol || w.location.protocol) + '//' + aoCAP.server + '/acton/forms/userSubmit.jsp';
      d.body.appendChild(dForm); // generate form 

      for (i = 0; i < len; i++) {
        var el = targetIdOrName.elements[i];
        var name = typeof(el.name) != ud ? el.name : null;
        var value = typeof(el.value) != ud ? el.value : null;
        tagName = el.nodeName.toLowerCase();
        if (tagName == 'input' && (el.type == 'radio' || el.type == 'checkbox') && !el.checked) {
          name = null;
        } else if (tagName == 'select' && el.selectedIndex && el.selectedIndex != -1 && el.options[el.selectedIndex] && el.options[el.selectedIndex].value) 
        {
          value = el.options[el.selectedIndex].value
        };
        if (name != null && name != '') {
          names.push(name);
          values.push(el.value);
          console.log("Element name: " + el.name + " / Element value: " + el.value);
          params[name] = el.value;
        };
        addInput( dForm, el.name, el.value );
      }

      aoCAP.pid = 0;
      aoCAP.cuid = aoCAP.cuid || '';
      aoCAP.srcid = aoCAP.srcid || '';
      aoCAP.camp = aoCAP.camp || '';
      addInput( dForm, 'ao_a', aoArr[AoI].aid );
      addInput( dForm, 'ao_f', aoArr[AoI].fid );
      addInput( dForm, 'ao_d', aoArr[AoI].fid+":"+aoArr[AoI].did );
      addInput( dForm, 'ao_p', 0 );
      addInput( dForm, 'ao_jstzo', new Date().getTimezoneOffset() );
      addInput( dForm, 'ao_form_neg_cap', '' );
      addInput( dForm, 'ao_refurl', d.referrer );
      addInput( dForm, 'ao_cuid', aoCAP.cuid );
      addInput( dForm, 'ao_srcid', aoCAP.srcid );
      addInput( dForm, 'ao_camp', aoCAP.camp );
      bi(idform).submit();

      var dTargetFrame = bi( idifr );
        dTargetFrame.onload = function() { 
        isLoaded = true; 
      }; 
      var waitForSubmit = function()
      {
        this.count = "";
        if ( ! ( isLoaded || dTargetFrame.readyState == "complete" ) ) {
          st( waitForSubmit, 200 );
          this.count ++;
        } else if (this.count > 7) {
          return true;
          console.log("skipping dForm");
        }
      else {
        d.body.removeChild( dForm );
        d.body.removeChild( dTarget );
      }
    };

    st( waitForSubmit, 100 );

    }
  } else {
    console.log('aoCAP property missing');
    } 
  }
};

Step 8

Lastly, your call to the above function will need to be placed in the appropriate place for your form. Here is an example of a standard call to this function if a form has ID "myform":

document.getElementById("myform").addEventListener("submit", function(evt) {
evt.preventDefault();
setTimeout(AoProcessForm(this), 0);
}, true);

If you want to utilize the jQuery .ajax method:

Here is a common implementation, based on http://api.jquery.com/jQuery.ajax/

$.ajax({
async: false,
url: 'your-url-where-request-is-sent',
type: 'POST',
data: PostData,
success: function(data) {
setTimeout(AoProcessForm(this), 0);
// any other success behavior

}, error:function (xhr, ajaxOptions, thrownError){
// error behavior
}
});
Note: setTimeout(AoProcessForm(this), 0) may need to be customized to reference your form, rather than using this
 

PHP implementations

If your form utilizes server-side validation of inputs or is a more complex form (such as a username/password input, a checkout form, or membership form), you will want to use a server-side method for passing form data to Act-On.

Advantages

Disadvantages

  • More flexible and customizable
  • Can work with advanced forms, such as membership forms, checkout forms, or multi-part forms
  • Will pass form submitters to the post-submit response page that is defined within your own systems (the post-submit redirect is not handled by Act-On, unlike the action URL method)
  • Greater complexity; examples below are for demonstration and require customization to work

Below illustrates a simple query-string-based form data push using PHP's $_REQUEST array when the form submission's input values are received. This is a good template to use if you are using a language that is not documented here since the function below can be easily converted, or if PHP cURL is not available.

This generates a 1px-by-1px hidden iframe at the bottom of your web page, with the form submit info being passed to Act-On via a query-string in the iframe source. The iframe being present allows Act-On to update the visitor's cookie value and convert them from anonymous to known.

Step 1

For each form this is used with, we need an equivalent "mirror" version of the Form to be created within Act-On. For example, if your custom form on your website captures First Name, Last Name, and Email, you'll need to create a form within Act-On that also requests these fields. Your website visitors will never see this Act-On variant of your form -- we simply need to receive your custom form’s data.

Step 2

Next, you'll want to make sure the input names match so that information can be passed properly. In the form builder, you'll see an "Edit" button appear when mousing-over any form field. Click "Edit", and take a look at "Data Field Name" on the resulting pop-up menu -- you want to ensure that your "Data Field Name" matches your custom form's HTML input name.

For example, if your First Name field in Act-On has a Data Field Name of "fname", you'll want your custom form HTML to contain "<input name='fname'... " for the equivalent field.

If you make any changes, be sure to click “next” twice in the Act-On form builder until you get to the last step, where you can save your form.

Step 3

You'll want to grab your Act-On form's external post URL. This is located under Content > Form Post URLs. The external post URL is unique from your form's public URL, and is designed specifically for accepting incoming external submissions.

In the example below, we will use the external post URL “http://yourcompanyname.actonsoftware.com/acton/eform/9999/001a/d-ex.... An external post URL generated in your account will follow the same format.

Step 4

We will capture the input names and values, and then generate a URL query-string containing their data.The general format for this is external-post-url?firstname=submitterFirstName&lastname=submitterLastName&email=submitterEmail

For example:

http://yourcompanyname.actonsoftware.com/acton/eform/9999/0001/d-ext-0001

becomes

http://yourcompanyname.actonsoftware.com/acton/eform/9999/0001/d-ext-0001?firstname=John&lastname=Doe&email=john@doe.com 

This external-post URL with the query-string will then inserted into a hidden iframe as the "src=" attribute, thus submitting the data when the iframe loads as well as planting the cookie on the viewer's browser through the iframe.

Code Overview

Class to implement

/**
* Post form submission data to Act-On and convert visitors to known via 1px by 1px hidden iframe into Act-On
* that is generated programatically with the iframe source containing a query-string to pass form field values
* assumes PHP version 5 or newer
*/

class ActonIframeConnection 

{
  private $_postItems = array(); 
  private function getPostItems() 
  {
    return $this->_postItems;
  }

  /**
  * for setting your form's POST items (key is your form input's name, value is the input value)
  * @param string $key first part of key=value for form field submission (name in name=John)
  * @param string $value latter part of key=value for form field submission (John in name=John)
  */
  public function setPostItems($key,$value)
  {
    $this->_postItems[$key] = (string)$value;
  }

  /**
  * process form data for submission to your Act-On external form URL
  * @param string $extPostUrl your external post (Proxy URL) for your Act-On "proxy" form
  */
  public function processConnection($extPostUrl)
  {
    $fields = http_build_query($this->getPostItems()); // encode post items into query-string
    $extPostUrlWithQueryString = $extPostUrl . '?' . $fields; // assemble full URL w/ query-string of submission key-values for GET to Act-On
    $hiddenIframe = "<iframe style='position: absolute; bottom: 0px; right: 0px; border: none; height: 1px; width: 1px; background: none' src=" . $extPostUrlWithQueryString . "></iframe>"; // assemble hidden iframe containing URL to pass form submission data and update visitor's cookie value thru iframe
    echo $hiddenIframe;
  }
}

<!-- Below: simple example form -->

<form action="post_form_example.php" method="post">
<input name="first_name" placeholder="First Name" type="text">
<input name="last_name" placeholder="Last Name" type="text">
<input name="email_addr" placeholder="E-mail" type="text">
<input name="company" placeholder="Company" type="text">
<input name="phone" placeholder="Phone Number" type="text">
<input name="submit" type="submit" value="submit">
</form>

<?php
if ('POST' == $_SERVER['REQUEST_METHOD']) { 

// declare new ActonIframeConnection object
$post1 = new ActonIframeConnection;

// format: setPostItems('your Act-On data field name','your custom form html input name')
$post1->setPostItems('First Name',$_REQUEST['first_name']); 
$post1->setPostItems('Last Name',$_REQUEST['last_name']);
$post1->setPostItems('E-mail Address',$_REQUEST['email_addr']);
$post1->setPostItems('Company',$_REQUEST['company']);
$post1->setPostItems('Phone',$_REQUEST['phone']);

// processConnection method, with your external post URL passed as the argument
$post1->processConnection('http://yourcompanyname.actonsoftware.com/acton/eform/9999/0001/d-ex...');

};

?>

PHP example B: cURL implementation

This example requires that cURL is functioning on your web hosting platform.

Step 1

For each form this is used with, we need an equivalent "proxy" version of the Form to be created within Act-On. For example, if your custom form on your website captures First Name, Last Name, and Email, you'll need to create a form within Act-On that also requests these fields. Your website visitors will never see this Act-On variant of your form -- we simply need to receive your custom form’s data.

Step 2

Make note of the 'Data Field Name' for each of the inputs for your proxy form in Act-On. For instance, go to the E-mail Address input in your proxy form and click "edit" on the field. Note how there is a "Label" and "Data Field Name" portion, and the code below will need the latter for each field you hope to pass. For this method, these do not need to match the "name" attribute of your external form HTML.

Step 3

You'll want to grab your Act-On form's external post URL. This is located under Content > Form Post URLs. The external post URL is unique from your form's public URL, and is designed specifically for accepting incoming external submissions.

Step 4

Next you will want to paste the following code into your form's response page PHP content. You will need to make edits to the fields and external post URL as needed, so please see the comments below in the code:

Class for handling cURL connection and Act-On cookie value manipulation:

/**
* Post form submission data to Act-On and convert visitors to known via cURL, allowing no direct touch 
* between Act-On and your website vistitor's browser to be necessary
*/

class ActonConnection 
{

  protected $_postItems = array();

  protected function getPostItems()
  {
    return $this->_postItems;
  }

/**
* for setting your form's POST items (key is your form input's name, value is the input value)
* @param string $key first part of key=value for form field submission (name in name=John)
* @param string $value latter part of key=value for form field submission (John in name=John)
*/
  public function setPostItems($key,$value)
  {
    $this->_postItems[$key] = (string)$value;
  }

  protected function getDomain($address)
  {
    $pieces = parse_url($address);
    $domain = isset($pieces['host']) ? $pieces['host'] : '';
    if (preg_match('/(?P<domain>[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs))
    {
      return $regs['domain'];
    }
    return false;
  }

  protected function getUserIP() 
  {
  //check proxy
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))
  {
    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
  }
  else
  {
    $ip = $_SERVER['REMOTE_ADDR'];
  }

  return $ip;
  }

  /**
  * process form data for submission to your Act-On external form URL
  * @param string $extPostUrl your external post (Proxy URL) for your Act-On "proxy" form
  */
  public function processConnection($extPostUrl)
  {

    $this->setPostItems('_ipaddr',$this->getUserIP()); // Act-On accepts manually defined IPs if using field name '_ipaddr'

    $fields = http_build_query($this->getPostItems()); // encode post items into query-string

    $handle = curl_init();
    curl_setopt($handle, CURLOPT_POST, 1);
    curl_setopt($handle, CURLOPT_URL, "$extPostUrl");
    curl_setopt($handle, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
    curl_setopt($handle, CURLOPT_COOKIE, $_SERVER['HTTP_COOKIE']);

    curl_setopt($handle, CURLOPT_HEADER, 1);
    curl_setopt($handle, CURLOPT_CUSTOMREQUEST, "POST");

    curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($handle, CURLOPT_POSTFIELDS, $fields);

    $response = curl_exec($handle);

    if($response === FALSE){
      $response = "cURL Error: " . curl_error($handle);
    }
    else
    {
      preg_match_all('/^Set-Cookie:\040wp\s*([^;]*)/mi', $response, $ra); // pull response "set-cookie" values from cURL response header 
      parse_str($ra[1][0], $cookie); // select the "set-cookie" for visitor conversion and store to array $cookie

      // set updated website visitor tracking cookie with processed "set-cookie" content from curl
      setrawcookie('wp' . key($cookie), implode(",", $cookie), time() + 86400 * 365, "/", $this->getDomain($extPostUrl)); //       set cookie expiry date to 1 year
    }

    curl_close($handle);
  }
}

Create new connection object based the above class, set input names and values, then process the connection in (must be done before your web page HTML loads due to cookie handling):


$post1 = new ActonConnection;
$post1->setPostItems('First Name',$_REQUEST['first_name']); // HTML input name attribute is "First Name", Act-On data field name should match that
$post1->setPostItems('Last Name',$_REQUEST['last_name']); // please note that Act-On does not accept filed names with punctuation marks in them, so rename as necessary
$post1->setPostItems('E-mail Address',$_REQUEST['email']);
$post1->processConnection('external-post-url-goes-here-as-argument'); // your external post URL ("Proxy Form URL")
 

Form data entry-points for custom solutions

Overview

For external post solutions that fall completely outside the realm of methods covered above, here are the tools you have at your disposal.

The information below is most relevant to those with complex systems, such as membership forms, payment forms, or those hoping to engineer an integration with Act-On via different logic or languages than other examples shown here.

Generates a URL for one of your existing Act-On forms. This URL can be used for POST or GET. Directing your form's <form> action attribute toward this URL is the process outlined in Using an action URL.

To generate a Proxy URL for an External Form, click on Content > Form Post URLs. Your Act-On form will need to have its input data field name match the <input> name attribute in your custom form, as outlined in the steps for Using an action URLThis URL will accept regular POSTs, but a standard form POST system will not capture the response cookie value from the Act-On server. This "set-cookie" value in the HTTP header response is what flags the form submitter as a known website visitor.

If you are handling this client-side

If you are handling this entirely server-side

  • By iframing the proxy URL in your visitors browser in an invisible frame (as shown in some of the examples in this article), the response header and cookie update occurs on the visitor's browser.
  • The JavaScript methods documented above are examples of this
  • Be sure to catch the http response header from the Act-On proxy URL in your custom method once you post/get data to it, and set the values recieved to the visitor's browser. Specifically, the Act-On tracking cookie is called wpXXXX (where XXXX is your account number), and its value is updated in the response header's "set-cookie" content.
  • The PHP-cURL method above is an example of this

Response header example from when a POST/GET is made to the proxy URL


string(1333) "HTTP/1.1 200 OKServer: Apache-Coyote/1.1
Set-Cookie: wpXXXX="WUVVDs-TYHY:UXWDMhktDTTWY:K-LQm-TTTUDDDTTVUHLDgNssD"; Version=1; Domain=.yourdomain.com; Max-Age=31536000; Expires=Fri, 08-May-2015 15:50:09 GMT; Path=/
P3P: CP="ALL CURa ADMa DEVa TAIa OUR BUS IND UNI COM NAV INT"
Content-Type: text/html;charset=UTF-8
Transfer-Encoding: chunkedDate: Thu, 08 May 2014 15:50:09 GMTConnection: close
Set-Cookie: ACTON=ACTON_101; path=/
 

You would want to capture the "set-cookie" value for wpXXXX and set that to your visitor's existing wpXXXX value.

Login URL

The "Login URL" is a feature of Act-On Account and Marketing lists allowing you to create list entries directly, without using a "Proxy Form". This works by providing you a specific URL that is unique to your Act-On account and specific list you are writing records to. The unique URL will then have the record data appended to it via a query-string.

Advantages

Disadvantages

  • Highly customizable 
  • Excellent solution for web developers integrating advanced forms (membership forms, login forms, payment forms and so on) due to its flexibility
  • Does not use an Act-On "proxy form", so the form report functionality normally available is not provided
  • Requires closer management of your lists and usage, due an an Act-On form no longer being the entry-point
  • Not a good solution if basic information such as visitor email is not always available

Login URLs are not enabled by default on Act-On accounts because they are an advanced feature. Contact support to request this feature, and we will quickly grant your request during regular business hours.

Once Login URLs are enabled, you will need to generate a Login URL for each list you would like to use. To generate a Login URL for one of your lists, navigate to the following: Contacts > Marketing Lists. Hover over the list you would like to use and click the drop down arrow > Click Maintenance > Click Get Login URL.

If you do not see the option to view the Login URL, be sure that you are using a regular list rather than a segment. The option may also have not been enabled for you account (contact support if that is the case).

Unlike other external post methods documented in this article, Login URLs do not require a "proxy form" to be created. They instead allow you to directly write records to an existing list.

Here is an example Login URL:

Do not use the above URL. It is provided for demonstration only and will not work.

Query-string component overview

The Login URL must have query-string name-value pairs appended to it in order to carry data, as any regular query-string would. These are the name-value pairs you want to use:

When this unique URL with the query-string is loaded in a browser, it loads the Act-On website visitor tracking pixel-graphic (the same graphic that is used in the website visitor tracking code). Unlike a regular website visitor tracking pixel-graphic being loaded however, with the login URL completed this tracking image will also update the visitor's cookie to mark them as a Known Visitor. 

Use-case

As far as when to use this functionality versus a different external post method, that is purely up to you. This feature is best suited for customers who prefer to mark a visitor as "known" outside of a form submissions, or after submitting a form that can't otherwise be integrated into Act-On.

Example implementation description:

  • You have a custom web portal where users authenticate using a non-email identifier, but you know their email address.
  • When the users log in, you pull their basic info (including email) from your internal database (not connected with Act-On) 
  • You programmatically generate a Login URL with query-string containing this information, and load it on the user's browser as an image or within an iframe to then track where the users go. 

Example JavaScript to implement a Login URL on a web page via an image:


var aoImage = document.createElement('img');
aoImage.loginURL = "{Login URL}"
aoImage.email = "{E-mail address to be pulled from your records}";
aoImage.firstName = "{First name to be pulled from your records}";
aoImage.lastName = "{Last name to be pulled from your records}";
aoImage.src = aoImage.loginURL + '?e=' + encodeURIComponent(aoImage.email) + '&First%20Name=' + encodeURIComponent(aoImage.firstName) + '&Last%20Name=' + encodeURIComponent(aoImage.lastName);
document.body.appendChild(aoImage);
 

The Login URL only needs to be used once to update the cookie on the visitor's browser (just like how an anonymous visitor only needs to submit a form once to be known). After that, you can use the regular visitor tracking code to receive updates.

Frequently Asked Questions

No, the Act-On API is not utilized. You could use the API to develop a further streamlined or custom solution however.

External posting sends submit data to Act-On only and will not track a view to the Act-On form typically. If you would like the "views" metric in Act-On forms to contain data, you can accomplish that with a simple trick however: Iframe in the Act-On "proxy" form's public URL you are using into your page inside a 1px by 1px "invisible" iframe. Embed the iframe on the same web page as your external form.

Yes. Because visitor conversion is an important component of Act-On, all documented methods here will convert visitors and display them as known.

This is not supported at this time. Information pre-filling or progressive profiling requires the Act-On-generated form. Please keep in mind that you can heavily modify the appearance and behavior of Act-On-generated forms via custom CSS and JavaScript, as covered in the article Customizing Act-On Form Appearance and Functionality.

The best course of action is to familiarize yourself with the underlying functionality of your current web-forms. If the developer of your form is available, you'll want to provide access to this article to him or her. While Act-On support can help, any server-side code that your form may use is not visible to us.

No, you absolutely do not and we encourage to developing a solution that you feel is best suited to your organization's technology and workflow. Just please keep in mind that converting visitors is an important component of form submissions and a simple HTTP post of your form input values will send data but not update the Act-On cookie value to convert the visitor.

Checkboxes in Act-On are grouped, with all checkboxes in your "proxy" form's checkbox block sharing the same name. In your custom form, each of your checkboxes may have a unique name.

To easily map this to Act-On, you can create one "proxy" form checkbox block (in the Act-On form builder) for each of your custom forms' checkboxes and match up the names.

You can also use a One Line Text block in your "proxy" form, since your "proxy" form only exists to receive data and input types do not need to match up for this.

To capture hidden field value from your external post/get, please use a One Line Text field in your Act-On proxy form. As with other mapping, your "Data Field Name" in Act-On should correspond with your external form's "name" attribute.

You can using an action URL, but not other methods offered on this document. You are not prevented from doing this with your own methods tailored to your specific site configuration, however. If you are building your own method to external post that is using POST (rather than GET) and is set to pass file values over to a matching field in your "Act-On proxy form", you should be able to upload files to Act-On. Just note the required encoding and type attributes in the <form> tag shown in the section "Using an action URL".

Yes, please have this code on every web page. The above methods rely on the tracking code running when when the visitor loads the page containing your external form.

Act-On places a cookie on the visitor's browser when they first visit one of your tracked web pages (if cookies are enabled). The name of the cookie is "wpXXXX", where XXXX is your account number.

This cookie contains a value generated by the Act-On server response. When the name and value of this cookie is posted to Act-On alongside form submission data containing their email address, the cookie value is changed. The cookie value, once set for a known visitor, will not change unless they resubmit a form with a new email address.

In addition to being converted from anonymous to known via a form submit, visitors are also converted when they click a link in an email sent through Act-On and go through the tracked-hyperlink redirect process we employ.

The following system field names can be used in hidden inputs within your custom form to pass the listed information into your Act-On signup list. These optional fields will work with any of the external form integration methods outlined above that utilize a "proxy form" and custom form with inputs with names matching the below.

By default, these fields are added to your Act-On form signup list and are completed when visitors complete Act-On-generated forms. For external forms, these are 100% optional, and leaving them out of your form will not cause any functionality to be lost. 

The following will work in any external post method above except for "Login URL"

_ipaddr

_ipaddr: IP addresses are used in form submissions to attribute a location to the website visitor. They are used for geo-IP website visitor reporting and contribute to the region-based alerts feature of Act-On. This raw IP information can also be seen in your form's sign-up list, in the system field '_IPADDR'.

  • If you are using a custom method or need to manually define the visitor's IP when they are submitting a form, you may pass that value under the field '_ipaddr'. 
  • Normally, Act-On will capture the IP from the form submitter from any standard Act-On form or if any of the above external post methods are used. For the vast majority of external post use-cases, the above field does not need to be manually defined.
  • Note how this is utilized in the PHP-cURL method, because otherwise that method would end up capturing the IP of your web server (rather than the website visitor's, due to the connection being passed through your server).
  • Example HTML for basic IP manual definition:
<input type="hidden" name="_ipaddr" value="123.123.123.123">
  • If the above were placed in your external form, Act-On would attribute your website visitors to IP "123.123.123.123" rather than the IP received in the form submission itself. 

ao_camp

ao_camp: designed to correspond with a SalesForce campaign but can use used for other purposes; sets values to the Act-On default sign-up list column "_CAMPAIGN"

  • "ao_camp" should be the name attribute in one of your posted HTML form inputs
  • Usage example:
    • On your custom external form, you have an input with "ao_camp" as the name, which is what Act-On is looking for in the post to pass this field. Example HTML:
<input type="hidden" name="ao_camp" value="">
  • You will want to set the value of this input manually via HTML if it is static, or via either JavaScript or server-side code if it is a dynamic value.

ao_refurl

ao_refurl: previously visited URL; sets values to the Act-On default sign-up list column "_REFERRER"

  • "ao_refurl" should be the name attribute in one of your posted HTML form inputs
  • Usage example:
    • On your custom external form, you have an input with "ao_refurl" as the name, which is what Act-On is looking for in the post to pass this field. Example HTML:
<input type="hidden" name="ao_refurl" value="">
  • You also set some way to set this hidden input to contain the referrer. For example, you can place this line of javascript below your form so that it sets the value to be the referrer once the form has loaded:
<script>document.getElementsByName('ao_refurl')[0].value = document.referrer</script>
  • Was this article helpful?