Skip to content

Getting correct field values with ActiveCampaign webhooks

active campaignfirebase

If you work at ActiveCampaign or know someone who works at ActiveCampaign please hook me up with them. I'd love to work on making their webhooks and documentation around it better. I think it would unlock a huge chunk of productivity.

This article goes over the hack needed to use a contact's field values on a updateContact webhook.

The scenario is pretty basic:
You use ActiveCampaign (AC) to send out a call to your backend server whenever a contact is being updated (i.e. using the updateContact webhook). On your backend you have some business logic as a function of the contact's fields and tags.

the problem with updateContact

The body of updateContact has the following structure:

{
    "type": "update",
    "date_time": "2023-07-12T06:49:04-05:00",
    "initiated_from": "admin",
    "initiated_by": "admin",
    "list": "0",
    "contact": {
        "id": "1234",
        "email": "[email protected]",
        "first_name": "Test",
        "last_name": "User",
        "phone": "+15555555555",
        "ip": "10.0.6.48",
        "tags": "month, free_forever, not_active_0912, TIER1, app_notif_reminder_sent, free-day-fix-1",
        "fields": ["", "", "", "", "", "", "none", "Free Forever", "none", "", "none", "4", "", "", "2023-07-01", "2023-07-08", "2022-04-14", "+15555555555", "TIER1", "0", "Paid", "none"],
        "customer_acct_name": "",
        "orgname": ""
    },
    "customer_acct_name": "",
    "customer_acct_id": "0",
    "orgname": ""
}

There are two things that stand out as having been implemented in the wee hours of a hackathon: tags and fields.

tags is a string of all the tags separated by a comma (,). fields is an array of strings, no matter the field's original data type. And more importantly, and what causes the headaches that probably brought you here, they are in a random order.

Now I'm not the sharpest tool in the... tool drawer, but that doesn't look like an optimal way to go about it.

If I was paid a Silicon Valley salary, I would've implemented tags as an array of strings and fields as a dictionary. But alas, I wasn't consulted and here we are.

the quick fix

The quick solution is to make a call to ActiveCampaign API to get the fields.

The call from the API returns an array of objects which you can parse to identify exactly which value belongs to which field.

So if before the process would look something like this:

  1. a change is made to a contact in AC
  2. AC sends out a webhook call
  3. your server processes the call

Now you need one more step:

  1. a change is made to a contact in AC
  2. AC sends out a webhook call
  3. your server makes a call to AC API endpoint && (a)waits for the response
  4. your server processes the result of both calls

That's the simple solution, if you can call it that.

the safer, but more complex solution

The thing is that ActiveCampaign webhooks can send out 10-20 calls a second. And their API responds to 5 calls per second.

As the quote goes:

An API call for an API call makes both servers flood.
-- Abraham Lincoln

Ideally you would wait for all updateContact calls to finish then make just one call to AC API to get custom field values.

To do that, what I did was to add a few steps to the process described above and got to something like this.

  1. a change is made to a contact in AC
  2. AC sends out a webhook call
  3. your server processes the udpate call without the fields and marks the contact as needing to be updated
  4. run a function every X minutes (cron job) to make the AC API call for each user marked for update

Even though this means another write to the DB, another function/job running periodically, it's still cheaper than running an API call for every call from the AC webhook.

Get updates for FREE

Put in your best email and I'll send you new articles, like this one, the moment they come out. ✌️

    Won't send you spam. Unsubscribe at any time.