WordPress Plugin Update

We’ve updated our WordPress plugin to work with version 3.9 (just released this week) which fixes an issue with the editor button, and also includes site tracking.

image

image

We’ve also removed the “Add/Sync Subscriber” options and the forms will now always perform a sync (add or update). You can still access the Ajax option by checking the “Submit form without refreshing page” option.

Enabling site tracking will automatically add our site tracking code to the front-end of your WordPress site, so visitor data will be added to ActiveCampaign after someone signs up through a form, or lands on your site from a campaign link. However, when using forms this will only work when “Submit form without refreshing page” is UNchecked.

Let us know of any questions or problems!

Integrate ActiveCampaign with WHMCS

We are very excited to announce an integration with WHMCS for reseller functionality! The integration (which was developed and managed by a 3rd party) features include:

  1. Fully manage your ActiveCampaign reseller accounts directly through WHMCS.
  2. Set your own product pricing through the WHMCS control panel.
  3. cPanel users can have custom domains created for reseller accounts for true brand identity.

This integration is available now from 123Coders in the WHMCS app store. Please refer to the developer’s site for questions and support.

WordPress Plugin Update

We’ve updated our WordPress plugin to make it easier to embed your forms onto a post or page. You can still paste the ActiveCampaign shortcode anywhere, and now you can also choose it from the toolbar:

image

The form you click will appear as a shortcode in the post body. This way you don’t need to know the form ID, or copy/paste the shortcode from the settings page.

image

Note: You’ll still need to connect to your ActiveCampaign account from the settings page and choose what forms you want to use.

When the page is loaded on the public side, the subscription form will appear in place of the shortcode!

image

Let us know if we can improve our WordPress integration any further.

“New List” Webhook Available

We’ve added a webhook notification that runs whenever a new list is created for an ActiveCampaign account.

image

Since the software is mainly driven by lists, this is useful if you need to be notified whenever a new list is created. Resellers utilizing common webhooks across all of their accounts will also benefit from this because all other webhooks require at least one list relation, meaning your accounts will always have the necessary hooks set up even when new lists are created in the future.

Here is an example webhook payload that ActiveCampaign will send when a new list is created:

type: list_add
date_time: 2013-09-25 15:31:45
initiated_from: api
initiated_by: api
list[id]: 7
list[userid]: 1
list[name]: List 3 (API)
list[sender_addr1]: 123 S. Street
list[sender_addr2]:
list[sender_city]: New York
list[sender_state]: NY
list[sender_zip]: 88383
list[sender_country]: USA
list[sender_url]: http://test.com
list[sender_reminder]: You signed up on our website.
list[fulladdress]: My, Inc., 123 S. Street , New York, NY 88383, USA

With this data you could create additional webhooks that notify you of account activity for that list:

$post_data = array(
  "name" => "Test",
  "url" => "http://example.com/webhook-subscribe.php",
  "lists[7]" => "7",
  "action[subscribe]" => "subscribe",
  "init[public]" => "public",
  "init[admin]" => "admin",
  "init[api]" => "api",
  "init[system]" => "system",
);

$response = $ac->api("webhook/add", $post_data);

Another thing you could do is create custom fields for that list:

$post_data = array(
  "title" => "interest",
  "perstag" => "interest",
  "type" => "1",
  "req" => "0",
  "show_in_list" => "1",
  "p[7]" => "7",
);

$response = $ac->api("list/field_add", $post_data);

Above we create a text custom field called “interest” that is associated with the new list.

Anything that requires the new list ID can now easily be done using this webhook.

Import Capsule CRM Opportunities

Our automatic contact importer lets you target specific email campaigns to certain segments of your CRM. If you’ve created opportunities in Capsule, you might want to import the associated contact and any additional contacts added to the opportunity.

image

You can now easily import opportunities into your ActiveCampaign list(s). As the opportunity expands to other contacts, they will be brought into ActiveCampaign automatically.

image

Let us know if we can improve our Capsule integration (or other integrations) in any way!

Detecting API Errors

image

Although you’ve carefully crafted your ActiveCampaign application to flow smoothly, it’s hard to know exactly when an unforeseen error will occur, which can possibly break your script and cost you time and money.

Our API attempts to provide basic information on any errors or problems that happened during a request. There’s typically two types of errors that can occur with an API request:

  1. Service level
  2. Application level

We strive for the highest uptime possible, but even we sometimes experience service disruptions that involve anything from code issues to server-level or network problems. Service level errors involve anything from network requests timing out to the service being unavailable, or even raw errors printing out. You may receive an indecipherable response, or possibly no response at all! In these cases the issue is always resolved on our end in a timely manner. Your ActiveCampaign application could attempt to detect these types of errors, but since it’s hard to predict exactly what (and how) things will be returned (if anything is returned in the first place) your only real action is to inform your users of the ActiveCampaign service disruption and to monitor updates through our available incident channels.

Application level errors are clean, graceful error messages returned from the ActiveCampaign application, and almost always indicate improper usage, such as attempting to load a contact that doesn’t exist or passing an invalid API key. Application level errors are less severe than service level errors, and will always provide a human-readable error message that can be expected in the same format. These errors usually have to be fixed by the API developer (the external application using the ActiveCampaign API), as opposed to the actual creators of the ActiveCampaign service (us).

When using the API, think of ActiveCampaign as your driver. When you make an API request, you are essentially telling ActiveCampaign to route you to your intended destination or goal (such as finding a campaign report, or adding a contact). If ActiveCampaign can route you to your destination, it’s considered a successful request. If not, it will try to tell you why (such as a roadblock that occurred during the drive).

Let’s look at an example request for a user’s details:

https://ACCOUNT.api-us1.com/admin/api.php
?api_key=fca40895042f8b0e7...dcd830e82802d85838cbc8a8b
&api_action=user_view
&api_output=json
&id=1

Assuming the above request does not experience a service level error, ActiveCampaign will attempt to look up the user with ID 1 for the associated account. If found, their data is returned along with some fixed keys that tell you a little about your request:

{
  "id": "1",
  "username": "admin",
  "first_name": "Test",
  "last_name": "Test",
  "email": "test@test.com",
  "last_login": "2013-09-12 07:13:46",
  "sourceid": "0",
  "sourceupdated": null,
  "productset": null,
  "a_now": "2013-09-12 09:39:22",
  "groups": "3",
  "result_code": 1,
  "result_message": "Success: Something is returned",
  "result_output": "json"
}

If the request was successful (meaning ActiveCampaign was able to get you to your destination), you’ll see a result_code being set to 1. The result_message will also provide a generic positive message such as "Success: Something is returned".

The HTTP response code should also be 200 in this case.

Now let’s try to load a contact using an ID that doesn’t exist:

https://ACCOUNT.api-us1.com/admin/api.php
?api_key=fca40895042f8b0e7...dcd830e82802d85838cbc8a8b
&api_action=user_view
&api_output=json
&id=999999999

If the request was not successful, result_code will be 0 and result_message will provide a description of what went wrong.

{
  "result_code": 0,
  "result_message": "Failed: Nothing is returned",
  "result_output": "json"
}

In this case the HTTP response code will be 404.

Our PHP API wrapper will also include an alternative success key (returns 1 or 0), also an error key which provides the error message if success is 0, or empty if success is 1. There will also be a http_code that returns the HTTP status code of the request (almost always 200 unless something went wrong).

{
  "result_code": 0,
  "result_message": "Failed: Nothing is returned",
  "result_output": "json",
  "success": 0,
  "error": "Failed: Nothing is returned",
  "http_code": 404
}

The important thing to take away is that both of the above requests are considered successful on the service level, but one of them failed on the application level.

Your ActiveCampaign applications can capture these errors and proceed gracefully in order to avoid disrupting the user with a broken application.

Using our PHP wrapper, your code flow could go something like this:

$response = $ac->api("user/view?id=1");

if ((int)$response->success) {
  // successful response - continue as planned.
}
else {
  // error occurred - provide the user some information.
  echo "We're sorry! Your request failed with the following error: " . $response->error;
  echo " (HTTP code " . $response->http_code . ").";
}

As always, let us know of any questions or concerns you may have!

WordPress Integration Update

We’ve updated our WordPress plugin to allow use of the shortcode (to embed a subscription form) without requiring that the widget be enabled (and dragged to a sidebar). This was a common complaint as most users just want to quickly embed a form into a blog post or page without having to also put the form in the sidebar.

There’s a new settings page that shows up in WordPress that provides similar options that appear through the widget:

image

Anywhere you want your chosen subscription form to appear just use the [activecampaign] shortcode.

image

If you want to customize the appearance of your subscription form, you do all that in the ActiveCampaign “Integration” section, then update the settings in WordPress again (the changes will then come across).

Let us know of any questions or problems!

Zapier Integration Updates

We’ve updated our Zapier integration to include two new triggers:

  1. Contact note added
  2. ActiveCampaign service incident reported

You’ll recall we revamped the contact details page a short while back, allowing notes to be entered for every contact. You can add notes associated with all lists, or individual lists. Zapier can track notes associated with individual lists:

image

image

One example of using this trigger could be to push ActiveCampaign contact notes into Highrise as contact notes:

image

You can also now track (through Zapier) anytime our service has an incident as listed on our status page. This lets you push that information to any other app or service you use.

An example of using this trigger could be to push ActiveCampaign service incidents to Google Talk as an instant message:

image

Happy automating! Let us know if you’d like anything else to be available through Zapier.

Creating, Testing, and Scheduling Campaigns via the API

The ActiveCampaign API provides developers the ability to access functionality and data associated with their ActiveCampaign accounts, allowing possibilities like custom interfaces or white-labeled email marketing features.

One common scenario that resellers come across is being able to provide the ability to create, test, and schedule email campaigns – all via the API.

A typical flow might go something like this:

  1. Create a campaign.
  2. Preview/test the campaign.
  3. Schedule the campaign to be sent.

All of this can be done using our API, and here we’ll show you how.

We’ll be demonstrating with our PHP API wrapper to keep the code examples concise. First set up your account URL and key:

define("ACTIVECAMPAIGN_URL", "https://ACCOUNT.api-us1.com");
define("ACTIVECAMPAIGN_API_KEY", "fca40895042f...2802d85838cbc8a8b");
require_once("../activecampaign-api-php/includes/ActiveCampaign.class.php");
$ac = new ActiveCampaign(ACTIVECAMPAIGN_URL, ACTIVECAMPAIGN_API_KEY);

Let’s create the campaign. First we’ll need to add our email message:

$post_data = get_object_vars(json_decode('{
  "format": "mime",
  "subject": "TEST from API",
  "fromemail": "newsletter@test.us",
  "fromname": "Test Company",
  "htmlconstructor": "editor",
  "html": "<h1>My Test Message</h1>\n\n<p>This is a test message created via the API.</p>",
  "textconstructor": "editor",
  "text": "# My Test Message\n\nThis is a test message created via the API.",
  "p[25]": "25",
  "p[12]": "12"
}'));

$message = $ac->api("message/add", $post_data);

The result should look something like this:

stdClass Object
(
  [id] => 168
  [subject] => TEST from API
  [result_code] => 1
  [result_message] => Email Message added
  [result_output] => json
  [success] => 1
)

We’ll use the message ID from above (168) when creating the campaign:

$post_data = get_object_vars(json_decode('{
  "type": "single",
  "segmentid": "0",
  "name": "TEST from API",
  "status": "0",
  "public": "1",
  "tracklinks": "all",
  "trackreads": "1",
  "p[16]": "16",
  "m[' . $message->id . ']": "100"
}'));

$campaign = $ac->api("campaign/create", $post_data);

You’ll notice the value for “status” is 0, which means “draft.”

The API result will look like this:

stdClass Object
(
  [id] => 130
  [result_code] => 1
  [result_message] => Campaign saved
  [result_output] => json
  [success] => 1
)

We’ll need the campaign ID from above ($campaign->id) later.

If you check the admin interface you’ll see the campaign draft:

image

With the campaign in “draft” status we can now test the campaign to any email address (if the email address is an existing contact, they’ll see personalizations as well):

$test_email = $ac->api("campaign/send?email=matt@test.us&campaignid=" . $campaign->id .
 "&messageid=0&type=mime&action=test");

Once you’re ready to schedule the campaign, update the scheduled date (“sdate”) to the appropriate date/time:

$schedule = $ac->api("campaign/status?id=" . $campaign->id . "&status=1&sdate=" . 
 urlencode("2013-07-25 12:00:00"));

Make sure the “sdate” is a date in the future otherwise it will send right away.

If you need to UN-schedule the campaign in order to send more email tests, just update the status back to “draft.”

$schedule = $ac->api("campaign/status?id=" . $campaign->id . "&status=0";

Happy coding! Let us know if we can help with anything.

Working with Webhook Data

ActiveCampaign webhooks allow you to capture real-time data from your account based on activity such as new or updated contacts, campaigns sending, and more.

Screenshot of webhooks page

A good way to get started with webhooks is to see how the data appears when it hits your custom webhook URL. With PHP it’s as simple as outputting the value of the $_POST variable, which will look something like this (for the “New Subscription” webhook):

Array
(
    [type] => subscribe
    [date_time] => 2013-07-18 08:46:33
    [initiated_from] => admin
    [initiated_by] => admin
    [list] => 1
    [contact] => Array
        (
            [id] => 50984
            [email] => test1@test.com
            [first_name] => test
            [last_name] => test
            [ip] => 127.0.0.1
        )

    [subscriber] => Array
        (
            [id] => 50984
            [email] => test1@test.com
            [first_name] => test
            [last_name] => test
            [ip] => 127.0.0.1
        )

)

You can set up any public PHP script to capture this data. For example, your webhook URL could be: http://mydomain.com/webhooks.php. Your PHP script could simply log every time a “post” request hits it:

<?php

  if ($_SERVER["REQUEST_METHOD"] == "POST") {
  
    $data = print_r($_POST, 1);
    
    $fd = @fopen("/path/to/webhooks.log", "a");
    fwrite($fd, $data);
    fclose($fd);
    
  }

?>

You can even receive the webhook data behind a firewall using a tool like UltraHook or Runscope Passageway.

image

For example, your webhook URL (in ActiveCampaign) could be http://test.activecampaign.ultrahook.com (which maps to http://localhost/webhooks.php behind the scenes). UltraHook is a Ruby gem and is simple to use:

image

image

If you are not a developer and prefer to have the data captured and output for you, try a service like RequestBin. You can create public or private bins where you can visualize data coming across.

image

Once you create a bin, copy the URL as a new webhook in ActiveCampaign:

image

When a webhook fires, the data will appear in RequestBin shortly after:

image

image

Finally, if you’d like to have another service automate ActiveCampaign data for you – our Zapier, CloudWork, and itDuzzit integrations provide a way to sync data in and out of ActiveCampaign with dozens of other services.