Masahiko Sunami

Integrating Contact Form 7 with iContact

iContactHere is another post on integrating Contact Form 7 WordPress plugin to an email marketing service which I did for my recent client – this time with iContact. There are few ways to use iContact API, but I chose to use send HTTP post with json encoding. A convenient built-in WordPress function makes it relatively straightforward.

Happy coding!

Register your App

First, you need to create and register an application for your iContact account. Follow the steps outlined here. You can create a sandbox account if you want to test the integration before you apply it to your active lists. In either case, you will need the following information:

  • API Username (If using sandbox, this is a username for your sandbox account)
  • Application ID
  • Application Password
  • API URL (you will see this under Account Information when you set your application password. It should look like this: https://app.icontact.com/icp/a/123456/c/78901/)

Find List ID

You need a numeric ID for the list that you want to put your contact into. To find this, go to your iContact Homepage, and in the Contact Lists, hover over the name of the list that you want, and get the link URL. The URL should look like this:

https://app.icontact.com/icp/core/mycontacts/contacts/view/?token=01a2bc34de567f89012a34567b8c9de01&clear=1&groupid=12345&ordercol=date&orderdir=1

The List ID is the numeric value after “groupid=”. For the dummy example above, the ID is 12345.

Create Contact Form

Using Contact Form 7 plugin, create your contact form. For integration purposes, you want to set up First Name, Last Name, and Email fields. For the example below, the names of those input fields are “your-first-name”, “your-last-name”, and “your-email”. Optionally, you can create a checkbox for opt-in.

The Code

Put the following code in your function.php file for your theme folder. Replace List ID, API URL, Application ID, Account Username, and Application Password with your own:

function wpcf7_send_to_icontact($cfdata) {

// get the form content
$formdata = $cfdata->posted_data;
$contact_email = $formdata['your-email'];
$contact_fname = $formdata['your-first-name'];
$contact_lname = $formdata['your-last-name'];

// set list ID for the forms
$listId = '------List ID------';

//this is the base api post http url
$post_url = '------API URL------';

$headers = array(
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Api-Version' => '2.0',
'Api-AppId' => '------Application ID------', // app id here
'Api-Username' => '------Account Userame------', // this is the log in username
'Api-Password' => '------Application Password', // this is the password for api app
'user-agent' => 'Contact Form 7 Integration' // this can be whatever you want
);

$contact_data = json_encode(array(array(
'email' => $contact_email,
'firstName' => $contact_fname,
'lastName' => $contact_lname
)));

$contact_args = array(
'body' => $contact_data,
'method' => 'POST',
'headers' => $headers,
'sslverify' => false, // Set SSL verify to false because of server issues.
'timeout' => 30
);

// http post to add contact to iContact
$result = wp_remote_request($post_url.'contacts/', $contact_args);

// get the contact ID from the result
$result_body = json_decode(wp_remote_retrieve_body($result), true);
$contact_result = $result_body['contacts'];
$contact_full = $contact_result[0];
$contactId = $contact_full['contactId'];

$subscription_data = json_encode(array(array(
'contactId' => $contactId, 
'listId' => $listId,
'status' => 'normal'
)));

$args = array(
'body' => $subscription_data,
'method' => 'POST',
'headers' => $headers,
'sslverify' => false,
'timeout' => 30
);

// assign a newly added contact to a list.
$result_list = wp_remote_request($post_url.'subscriptions/', $args);

}
add_action( 'wpcf7_mail_sent', 'wpcf7_send_to_icontact', 1);

What this code does

In a nutshell, this code gets the input data from the contact form after email gets sent from the contact form, then first sends a HTTP post to iContact to add new contact to your account, and then sends a second HTTP post to put the new contact into a list.

The last line adds the action to Contact Form 7, so function “wpcf7_send_to_icontact” will run after a contact form is successfully sent.

add_action( 'wpcf7_mail_sent', 'wpcf7_send_to_icontact', 1);

The function first gathers relevant contact data. In this example, it’s pulling the first name, last name, and email address from the contact form data.

$formdata = $cfdata->posted_data;
$contact_email = $formdata['your-email'];
$contact_fname = $formdata['your-first-name'];
$contact_lname = $formdata['your-last-name'];

To send a HTTP post, it uses a built-in WordPress function, wp_remote_request. So after gathering the contact data, it prepares the necessary array. There are two main parts:

  • $contact_data is an array that matches the contact form data to the iContact contact fields. Note that field names are not the same as merge fields. You can reference this help doc: http://developer.icontact.com/documentation/contacts/
  • $headers contains the header information for HTTP post, and it specifies json encoding and required information for authentication.

Then this sends the HTTP post to add the contact:

$result = wp_remote_request($post_url.'contacts/', $contact_args);

$result you get here contains the ID for the new contact which you need to do the second HTTP post. The actual ID is tucked away in an array several layers deep and the whole thing is json encoded, so this decodes the $result and gets the ID:

$result_body = json_decode(wp_remote_retrieve_body($result), true);
$contact_result = $result_body['contacts'];
$contact_full = $contact_result[0];
$contactId = $contact_full['contactId'];

Then finally, it prepares the second array and sends the second HTTP Post to add the contact to a list:

$result_list = wp_remote_request($post_url.'subscriptions/', $args);

Debug

I used the following code to debug the code. The good thing about this integration method is that you get a clear result from the HTTP post call. So copy the following and put it in at the end of the wpcf7_send_to_icontact function. This will create a text file, “devlog.txt” in your server root folder (you may need to create it manually) and prints key variable contents and results from the HTTP post. You can add whatever variable you want to check in the $debug array.

IMPORTANT: Make sure that you either comment out/erase this part of the code once you are done, and erase the devlog.txt file otherwise you will be posting sensitive contact information on your server.

$debug = array(
'time' => date('Y.m.d H:i:s e P'),
'contact_arg' => $contact_args,
'result' => $result,
'result_body' => $result_body,
'contact_result' => $contact_result,
'contact_full' => $contact_full,
'contactId' => $contactId,
'subscription_post' => $subscription_data,
'result_list' => $result_list
);
$test_file = fopen('devlog.txt', 'a');
$test_result = fwrite($test_file, print_r($debug, TRUE));

More examples

Here is a variation of the code for having an opt-in check box. For this to work, create a checkbox with a name “icontact-opt-in” with a single option.

function wpcf7_send_to_icontact($cfdata) {

// get the form content
$formdata = $cfdata->posted_data;
$contact_email = $formdata['your-email'];
$contact_fname = $formdata['your-first-name'];
$contact_lname = $formdata['your-last-name'];

// run only if opt-in box is checked
if( $formdata['icontact-opt-in'] ) {

// set list ID for the forms
$listId = '------List ID------';

//this is the base api post http url
$post_url = '------API URL------';

$headers = array(
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Api-Version' => '2.0',
'Api-AppId' => '------Application ID------', // app id here
'Api-Username' => '------Account Userame------', // this is the log in username
'Api-Password' => '------Application Password', // this is the password for api app
'user-agent' => 'Contact Form 7 Integration' // this can be whatever you want
);

$contact_data = json_encode(array(array(
'email' => $contact_email,
'firstName' => $contact_fname,
'lastName' => $contact_lname
)));

$contact_args = array(
'body' => $contact_data,
'method' => 'POST',
'headers' => $headers,
'sslverify' => false, // Set SSL verify to false because of server issues.
'timeout' => 30
);

// http post to add contact to iContact
$result = wp_remote_request($post_url.'contacts/', $contact_args);

// get the contact ID from the result
$result_body = json_decode(wp_remote_retrieve_body($result), true);
$contact_result = $result_body['contacts'];
$contact_full = $contact_result[0];
$contactId = $contact_full['contactId'];

$subscription_data = json_encode(array(array(
'contactId' => $contactId, 
'listId' => $listId,
'status' => 'normal'
)));

$args = array(
'body' => $subscription_data,
'method' => 'POST',
'headers' => $headers,
'sslverify' => false,
'timeout' => 30
);

// assign a newly added contact to a list.
$result_list = wp_remote_request($post_url.'subscriptions/', $args);

} // end if
}
add_action( 'wpcf7_mail_sent', 'wpcf7_send_to_icontact', 1);

Here is another example for using form title to add contact to two different lists. It will not run unless the form title is a match.

function wpcf7_send_to_icontact($cfdata) {

// get the form content
$formdata = $cfdata->posted_data;
$contact_email = $formdata['your-email'];
$contact_fname = $formdata['your-first-name'];
$contact_lname = $formdata['your-last-name'];

//get the form title.
$formtitle = $cfdata->title;

// set list ID for the forms depending on the form used. only run if contact comes from these lists
if ( $formtitle == 'Contact Form Number 1' || $formtitle == 'Contact Form Number 2' ) {

if ( $formtitle == 'Contact Form Number 1' ) $listId = '------List ID for the first form------';
elseif ( $formtitle == 'Contact Form Number 2' ) $listId = '------List ID for the second form------';

//this is the base api post http url
$post_url = '------API URL------';

$headers = array(
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Api-Version' => '2.0',
'Api-AppId' => '------Application ID------', // app id here
'Api-Username' => '------Account Userame------', // this is the log in username
'Api-Password' => '------Application Password', // this is the password for api app
'user-agent' => 'Contact Form 7 Integration' // this can be whatever you want
);

$contact_data = json_encode(array(array(
'email' => $contact_email,
'firstName' => $contact_fname,
'lastName' => $contact_lname
)));

$contact_args = array(
'body' => $contact_data,
'method' => 'POST',
'headers' => $headers,
'sslverify' => false, // Set SSL verify to false because of server issues.
'timeout' => 30
);

// http post to add contact to iContact
$result = wp_remote_request($post_url.'contacts/', $contact_args);

// get the contact ID from the result
$result_body = json_decode(wp_remote_retrieve_body($result), true);
$contact_result = $result_body['contacts'];
$contact_full = $contact_result[0];
$contactId = $contact_full['contactId'];

$subscription_data = json_encode(array(array(
'contactId' => $contactId, 
'listId' => $listId,
'status' => 'normal'
)));

$args = array(
'body' => $subscription_data,
'method' => 'POST',
'headers' => $headers,
'sslverify' => false,
'timeout' => 30
);

// assign a newly added contact to a list.
$result_list = wp_remote_request($post_url.'subscriptions/', $args);

} // end if
}
add_action( 'wpcf7_mail_sent', 'wpcf7_send_to_icontact', 1);

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. Ari
    July 20, 2014 at 6:00 am

    Nice..! What I am looking for..!

  2. David Bleemel
    May 13, 2014 at 11:01 am

    I’m having trouble getting this to work with the opt-in checkbox. I’ve created a checkbox in CF7 named icontact-opt-in, but regardless of whether the box is checked or not, the contact is added to iContact. I’m also having some trouble adding certain fields. I can’t get zip field in iContact to populate with this code. Also, I have a custom field with multiple selections. Any special tricks to sending this field to iContact?

    Thanks!!

  3. amit sidhpura
    March 12, 2014 at 8:07 am

    Thanks!! Save a lot of time.

  4. Grow Social
    October 25, 2013 at 10:06 am

    Worked perfectly! Thanks so much!!

  5. Ken
    October 9, 2013 at 4:25 pm

    Thank you code is great. With regards to multiple forms – If we don’t want a particular form to post to iContact how should we handle the if-then statement?
    Thanks.

    • mas
      October 11, 2013 at 7:37 pm

      Hi Ken,
      If you have multiple forms and want particular form to not go to iContact, then you can just use something similar to my last example (but with only one if-then statement) and instead of
      $formtitle == 'Contact Form Number 1'
      you would want
      $formtitle != 'Contact Form Number 1'
      Make sure that you have right number of open { and closing } in your code.

  6. D.L. Trebor
    February 26, 2013 at 3:53 pm

    Thank you for sharing this code, and in a manner so clear and straightforward that even this coding newbie could grasp it! Got your second example (with the opt-in box) working perfectly on my first attempt. Hooray!

  7. Rich
    January 28, 2013 at 11:03 am

    Thank you so much for this post. I setup a form and its been working great.

    But no I would like to put a second form on my site with different fields and sen them to a different list.

    Is it possible to specify the a different contact form ID and make it go to a different list ID?

    Thanks

    • mas
      January 28, 2013 at 11:04 pm

      Hi Rich,
      Thanks for your comment. The last example shows how to add new contact to different list depending on the form used. If you have different fields for different forms, then you’ll need to prepare different $contact_data variable for the different form. Something like this:


      if ( $formtitle == 'Contact Form Number 1' ) {
      $listId = '------List ID for the first form------';
      $contact_data = json_encode(array(array(
      'email' => $contact_email,
      'firstName' => $contact_fname,
      'lastName' => $contact_lname,
      '---icontact field name---' => $formdata['---CF7 field name---'];
      )));
      } elseif ( $formtitle == 'Contact Form Number 2' ) {
      $listId = '------List ID for the second form------';
      $contact_data = json_encode(array(array(
      'email' => $contact_email,
      'firstName' => $contact_fname,
      'lastName' => $contact_lname,
      '---icontact field name---' => $formdata['---CF7 field name---'];
      )));
      }

      Make sure that you are using the correct field name and format for icontact. See here: http://developer.icontact.com/documentation/contacts/

      mas

  8. Kevin S
    December 29, 2012 at 1:17 pm

    Thanks a bunch for this! I was able to setup and test in the sandbox and then get it setup on the live server following your instructions. I’m using it for a newsletter subscription form and an opt-in on my contact form at http://segedi.com/.

    For the newsletter subscription form, I set the checkbox to be an acceptance checkbox so it would force the submitter to check the box. And it’s pre-checked. On the contact form, it’s regular checkbox, unchecked, so they can opt-in.

    Thanks again!

  9. Sam
    October 22, 2012 at 11:07 am

    I am very intrigued by your work here.

    I have a questions:
    On the List ID – when I hover on my list, I get https://app.icontact.com/icp/core/mycontacts/lists/edit/12345/?token=630b133a53cf316000843f6b006531a5 . So, I am guessing my list ID is 12345?

    Great work. I hadn’t been able to figure out how to do this. You seem to be the only person who has figured it out.

    I am wondering if this would still work for me because I use the ’email to download’ cf7 extension.

    Thanks!!

    • mas
      October 22, 2012 at 2:20 pm

      Hi Sam, Thanks for your comment. Yes that should be your list ID.

      I’m assuming your are referring to “Email before Download” plugin? I can’t say for sure that it will work, but if it uses Contact Form 7 to actually send the email, then I’d assume that that triggers an action hook “wpcf7_mail_sent”. Why not give it a try and see if it works?

      Do let me know if it works!

      • Sam
        November 7, 2012 at 9:12 am

        It works!!! (or at least about 95%)

        It seems to slow up the confirmation message people get below the submit button that says ‘sent successful’. It isn’t horrible but not as fast as it was.

        I have three forms (that way I can separate what email message they get (2 get their welcome message from “email to download”)). I have all three forms the same with the same field name. The problem is the one that uses Mail (2) to send out their welcome email via contact form 7…it won’t transfer companyname to business in the list. The other two are just fine and everything is transferred BUT only that field on that form.

        Any thoughts why?

        Thanks again for putting something like this together!!!

        • mas
          November 8, 2012 at 1:43 pm

          Since it has to execute two post to HTTP calls, it will take a little time to process them.

          Don’t quite understand the problem you mentioned, but here is how you can add “business” field in iContact. First, you have to pull the company name from the contact form (replace ‘company-name’ with your actual field name in contact form 7):

          $contact_company = $formdata['company-name'];

          And then put it into the $contact_data to send to iContact like this:

          $contact_data = json_encode(array(array(
          'email' => $contact_email,
          'firstName' => $contact_fname,
          'lastName' => $contact_lname,
          'business' => $contact_company
          )));
          

          Sending a mail using Mail(2) in Contact Form 7 shouldn’t really change anything I’d think…

      • Sam
        November 7, 2012 at 9:56 am

        Also, I have a question about your example into two different lists.

        Could that be used to separate into different lists depending on form name?

        if form title is 1= this list
        elseif, if form title is 2= that list
        elseif, if form title is 3= this other list

        I have three forms to help separate people…so it might be nice to have them separated in iContact too (instead of one large one).

        Thanks again…

        • mas
          November 8, 2012 at 1:44 pm

          Yeah that’s the second example code I put at the end of the post. It uses conditional statements for contact form names to put contact into different lists.

          If you have more than two list (as in the example) just add more elseif statements.