Integrating with WordPress and Elementor API webhooks

Overview

Consider this scenario:

  • You have a WordPress instance, possibly installed in your own internal network
  • With WordPress, you use Elementor, a popular website builder
  • A user fills out a form that you prepared using Elementor, e.g. the user provides his or her email and username to create an account in your CRM
  • Now, after WordPress processes this information accordingly, you also need to send it all to a remote backend system that only accepts JSON messages

The concern here is that WordPress alone will not send it to the backend system.

Hence, we are going to use an Elementor-based webhook that will invoke Zato which will be acting as an integration layer. In Zato, we will use Python to transform the results of what was submitted in the form - in order to deliver it to the backend API system using a REST call.

Creating a channel

A Zato channel is a way to describe the configuration of a particular API endpoint. In this case, to accept data from WordPress, we are going to use REST channels:

In the screenshot below, note particularly the highlighted data format field. Typically, REST channels will use JSON, but here, we need to use "Form data" because this is what we are getting from Elementor.

Now, we can add the actual code to accept the data and to communicate with the remote, backend system.

Python code

Here is the Python code and what follows is an explanation of how it works:

# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

# Field configuration
field_email = 'fields[email][value]'
field_username = 'fields[username][value]'

class CreateAccount(Service):

    # The input that we expect from WordPress, i.e. what fields it needs to send
    input = field_email, field_username

    def handle(self):

        # This is a dictionary object with data from WordPress ..
        input = self.request.input

        # .. so we can use dictionary access to extract values received ..
        email = input[field_email]
        username = input[field_username]

        # .. now, we can create a JSON request for the backend system ..
        # .. again, using a regular Python dictionary ..
        api_request = {
            'Email': email
            'Username': username
        }

        # Obtain a connection to the backend system ..
        conn = self.out.rest['CRM'].conn

        # .. invoke that system ..
        # Invoke the resource providing all the information on input
        response = conn.post(self.cid, api_request)

        # .. and log the response received ..
        self.logger.info('Backend response -> %s', response.data)

The format of data that Elementor will use is of a specific nature. It is not JSON and the field names are not sent directly either.

That is, if your form has fields such as "email" and "username", what the webhook sends is named differently. The names will be, respectively:

  • fields[email][value]
  • fields[username][value]

If it were JSON, we could say that instead of this ..

{
  "email": "hello@example.com",
  "username": "hello"
}

.. the webhook was sending to you that:

{
  "fields[email][value]": "hello@example.com",
  "fields[username][value]": "hello"
}

The above format explains why in the Python code below we are extracting all the input fields from WordPress using the "self.request.input" object using its dictionary access syntax method.

Normally, if the field was plain "username", we would be doing "self.request.input.username" but this is not available in this case because of the naming conventions of the fields from Elementor.

Now, the only remaining part is the definition of the outgoing REST connection that service should use.

Outgoing REST connections

Create an outgoing REST connection as below - this time around, note that the data format is JSON.

Using the REST channel

In your WordPress dashboard, create a webhook using Elementor and point it to the channel created earlier, e.g. make Elementor invoke an address such as http://10.157.11.39:11223/api/wordpress/create-account

Each time a form is submitted, its contents will go to Zato, your service will transform it to JSON and the backend CRM system will be invoked.

And this is everything - you have just integrated WordPress, Elementor webhooks and an external API backend system in Python.