Introduction§

Yesplan offers customers and third parties the possibility to integrate with the system using webhooks. The integration allows a user to take an action in another system from within Yesplan. Yesplan sends the action to the other system. The other system can then retrieve, and write, data through the Yesplan HTTP API. A wide range of workflows that use Yesplan and other systems can be implemented using webhooks and the HTTP API, such as announcing a Yesplan event on a public website, making tickets for it available in a ticketing system, invoicing the event in financial software and so on. Webhooks allow all of these workflows to be initiated from within Yesplan while being handled by the other system.

Users take actions in the other system from within Yesplan through a custom data field. The field shows a current state and buttons for the various actions the user can take. Both the current state and the possible actions are defined by the other system. On the above screenshot, the current state is “Published”, which might, for example, be a state as given by a system that publishes Yesplan events on a public website. The actions the user can take are to “Update” the event on the website, or to “Revoke” it from the website.

Webhooks are implemented using the HTTP protocol. The other system needs to be able to handle two kinds of HTTP requests sent by Yesplan:

Additionally, the other system needs to send at least one kind of HTTP request to Yesplan in turn. After sending a “Take Action” request, Yesplan expects to receive an “Update State” request to tell it which new state to show in the custom data field.

This document assumes you are familiar with the HTTP protocol as documented in RFC 2616, and with the Yesplan HTTP API. Knowledge of Node.js and Express.js is needed to be able to run the example external system that is given, but this document can be understood without running the example.

Example External System§

To illustrate the webhook mechanism, we provide an example of an external system implemented using Node.js and the Express.js framework. While the example implements a trivial, non-meaningful service, the code is fully functional and serves as a succinct illustration of how to use Yesplan’s webhooks.

The code for this example can be downloaded as a ZIP archive. The example consists of two files:

If you want to execute the webhook in combination with a Yesplan installation, you need to configure the file server.js in the following way:

Example States and Actions§

The example system is only meant to demonstrate the interaction with Yesplan. As such, it doesn’t do anything other than respond to “Take Action” requests by sending a corresponding “Update State” request where the new state is simply determined by the button the user pressed in Yesplan. The following states are defined with the corresponding buttons:

State Buttons Description
OFF Publish Default state
Published Update, Revoke Event was registered with the webhook
Updated Update, Error, Revoke The event was updated by the webhook
Errored Update The webhook marked the event as being in an error state

By clicking the Publish, Update or Error button, the user instructs the system to set the event to the state with the corresponding name. Clicking Revoke will inform the system that the user wishes to put the event in the OFF state.

Configuration in Yesplan§

The webhook needs to be set up in Yesplan by an administrator. As a Yesplan administrator, you can open the System Settings via the Dock. On the tab Integrations you can add a new integration (in our example, we called this integration “Webhook”). As the kind of integration in the dropdown select “Web Hook”. For the field “Configuration URL”, fill out the URL which Yesplan can use to send the “Configuration” request, as defined by the external system. For the example, the URL is “http://external.system.com/configuration”.

When the “Click to Configure” button is pressed, Yesplan will send the “Configuration” request using the URL given as the “Configuration URL”. The retrieved states and buttons, as well as the other configuration details, are shown. In case the response to the “Configuration” request is not as expected, an error message will be shown.

One other thing to set up is the integration custom data field. Setting up custom data fields is discussed in more detail in the chapter on “System Settings”. The custom data field needs to be of type “Publication trigger”. For this example, as shown on the screenshot below, the custom data field has label “webhook” and is made visible on the “Info” tab in event inspectors. In the settings for the integration, it is the field selected in the dropdown for the setting “Webhook Trigger”.

Using the Custom Data Field§

Actions can now be taken in the external system from within Yesplan. When an event is created in the Yesplan calendar, and opened, the custom data field labeled “webhook” is shown on the “Info” tab of the event inspector. For an event that has just been created, the field alwyas has the initial state as defined by external system in response to the “Configuration” request. In the example, this initial state is “OFF”, which offers “Publish” as the only button.

When the “Publish” button is clicked, Yesplan sends a “Take Action” request. Until a corresponding “Update State” request is received, the field is shown as being in a state “Waiting”. In our example, the external system in turn sends an “Update State” request that puts the field in the state “Published”.

If the external service takes too long to send a corresponding “Update State” request, the field will be put in an error state “Waiting too long”. At this point, the user can try again by pressing the field’s refresh button. Yesplan will repeat the “Take Action” request that it sent before.

External System Requirements§

This section discusses the details of the “Configuration” and “Take Action” requests from Yesplan that an external system should be able to respond to, as well as the “Update State” requests it is expected to send. The details are illustrated using the same example that is used in the previous section to illustrate how the integration is set up and used.

Handling “Configuration” Requests§

The external system needs to be able to handle a “Configuration” request, and is expected to respond data about the possible states and actions. Technically, a “Configuration” request is a HTTP GET request on the “configuration” URL. The configuration URL is defined by the external system, and is set up in Yesplan by an administrator as discussed in the previous section. The response is expected to have status 200, with a JSON object with the following name/value pairs:

A few important points:

In the example code, the handling of “Configuration” requests from Yesplan is implemented as follows:

app.get('/configuration', function (req, res) {
  res.send( {
    url: "http://external.system.com/action",
    timeout: 15,
    initialstate: "OFF",
    states: [
        {
            name: "OFF",
            buttons: [ "Publish" ]
        },
        {
            name: "Published",
            type: "success",
            buttons: [ "Update", "Revoke" ]
        },
        {
            name: "Updated",
            buttons: [ "Update", "Error", "Revoke" ]
        },
        {
            name: "Errored",
            type: "error",
            buttons: [ "Update" ]
        },
    ]
  })
});

Handling “Take Action” Requests§

The external system needs to be able to handle a “Take Action” request. Yesplan sends a “Take Action” request when the user clicks one of the action buttons of the custom data field. Technically, a “Take Action” request is a HTTP POST request with a JSON object with data on the action the user is taking. The response is only expected to have status 200, as an indication that the request has been correctly received. The JSON object that is sent with a “Take Action” request has the following name/value pairs:

A few important points:

The following is an example of a “Take Action” request. The user pressed the “Update” button on an event named “Concert” where the custom data field is in the state “Published”:

POST http://external.system.com/action HTTP/1.1
Content-type: application/json
Content-Length: 301

{ "subject":
   { "url": "http://theater.yesplan.be/api/event/1179-1506667413",
     "id": "1179-1506667413",
     "name": "Concert",
     "_type": "event" },
  "state": "Published",
  "button": "Update",
  "customdata": "webhook_webhook",
  "user":
   { "url": "http://theater.yesplan.be/api/user/16-1506667364",
     "id": "16-1506667364",
     "name": "Administrator" } }

In the example code, the handling of “Take Action” requests from Yesplan is implemented as follows; being only an example, this implementation doesn’t do anything other than responding to the request with status 200 (“OK”) and sending the expected “Update State” request:

app.post('/action', function (req, res) {
    console.log(req.body);
    const button = req.body.button;
    const url = req.body.subject.url;
    const customdata = req.body.customdata;
    const targetState = buttonToStateMap[button];
    request
        .put(url + '/customdata')
        .query( { 'api_key': apiKey })
        .send( [ {
         "keyword": customdata,
         "value": targetState
        } ]).end( (err, success) => {
            if (err) {
                console.log("ERROR " + err);
            }
        });
    res.send("ok");
});

Sending “Update State” Requests§

After sending a “Take Action” request, Yesplan expects to receive a corresponding “Update State” request through the Yesplan HTTP API. An “Update State” request is a request from the external system for Yesplan to change the state of the integration custom data field. It is made in the same way as other requests to update Yesplan custom data fields, which is covered in more detail in the chapter on the Yesplan HTTP API. Technically, an “Update State” request is a HTTP PUT request with a JSON object that gives the new state of the integration custom data field.

The “Update State” request should correspond to the “Take Action” request by being about the same subject and the same custom data field. In the example “Take Action” request given in the previous section, the URL of the subject is “http://theater.yesplan.be/api/event/1179-1506667413” and the keyword of the custom data field is “webhook_webhook”. The URL to be used for the corresponding “Update State” request is the same URL, but with “/customdata” appended as well as an API key. A complete example request that sets the state of the custom data field to “Updated” is as follows; example code that sends such a request is included in the previous section:

PUT /api/event/1179-1506667413/customdata?api_key=6F5A671121FB7123ECD3B3E3E8DBE7EE HTTP/1.1
Host: theater.yesplan.be
Accept: */*
Content-type: application/json
Content-Length: 50

[
    {
        "keyword": "webhook_webhook",
        "value": "Updated"
    }
]