Leon Stigter

@retgits

Building extensions for TIBCO Cloud Integration Web Integrator

Last month TIBCO added the ability to add custom activities to TIBCO Cloud Integration — Web Integrator (I’ll use Web Integrator going forward). The Web Integrator experience is “Powered by Project Flogo”, so when you create your own extensions for Web Integrator, and use them in every flow that you want, those activities will work with Project Flogo as well. In this blog post I’ll walk through creating a new extension that connects to IFTTT using the WebHooks service.

Why IFTTT?

IFTTT is a free web-based service that people use to create chains of simple conditional statements, called applets. An applet is triggered by changes that occur within other web services1.

IFTTT also has a great feature to extend that connectivity using, what was previously known as the Maker Channel, the WebHooks service. With easy to understand input and output and still delivering great value, this is an great way to show how you can create your own extensions for Web Integrator.

Setting up IFTTT

Within IFTTT you need to activate the WebHooks service. You can do that by going to this url and clicking the big white button Connect.

Now go to the settings screen and check the generated URL. The last past of the URL (after the last /) is what IFTTT calls the WebHook key and that is used to authenticate the calls coming in. We'll need that key later! Be sure to never tell anyone your key (and yes, I did change my key already).

Build a notification flow

The connector and the activity that are the end result of this blog post need to be tested with something nice. As pretty much everyone carries a mobile phone nowadays, the IFTTT flow will start with a WebHook (the this) and send a notification (the that)

Event name

One of the parameters that our connector will need, and one of the parameters that IFTTT needs to route the event to the correct applet, is the event name. In this case I’ve set it to HelloWorld.

The structure of your folder

The end result of this extension will have an activity and a connector and a bunch of files that make up the two. The code is available on GitHub, so you could just skip all this and check that out. The folder structure, including the files we’ll create is:

wi-ifttt-extension  
├───activity
│ └───ifttt
│ ├───activity.go
│ ├───activity.json
│ ├───activity.module.ts
│ ├───activity.ts
│ ├───activity_test.go
│ └───ifttt.png

└───connector
└───ifttt
├───connector.json
├───connector.module.ts
├───connector.ts
└───ifttt.png

The root folder of the extension is called wi-ifttt-extension, which will also be the name of the repository on GitHub (this is important for when we add Travis CI into the mix). Bellow that is a folder to store the activities called activity and a folder to store connectors called connector. From there on each activity and each connector will have its own subfolder. In the case above there is one activity in the folder ifttt and one connector in the folder ifttt (different folders, same name)

The Web Integrator connector

Let’s look a bit more detailed at the connector

└───connector
└───ifttt
├───connector.json
├───connector.module.ts
├───connector.ts
└───ifttt.png

A good extension obviously needs a killer icon, and as luck would have IFTTT has a brilliant icon available. The file ifttt.png in this folder is shown on the connector screen. The only requirement here is that it is a png file (I'd recommend looking for 128x128 pixels).

connector.json

The connector.json file describes what the connector is, what the inputs are it needs and a bunch of other metadata. It is important that the namefield doesn't have any special characters and no spaces (in my case it is wi-ext-ifttt). The category in the display section is the name of the category that will be shown for this connector. In this case the connector will be shown in the ifttt category. The ref field is a reference to a GitHub repository and this field has to be a correct URL (the repository doesn't have to exist though). The settings describe the fields that the user will need to provide:

  • name: the name of the connection so you can find it easily in your activities
  • description: a useful description is always good, especially when you have multiple connections
  • webhookKey: this is the key that comes from IFTTT, note that the type is password so it will be shown on the user interface as a bunch of balls
  • eventName: the event to trigger

connector.ts

The connector also has a TypeScript file that covers the validation of the fields and takes care of alerting Web Integrator when to save the data.

As you browse through the code you’ll see a validate object which, as the name would imply, validates whether the connection can be saved. In our case there are two mandatory fields that need to be there, webhookKey and eventName. If both the webhookKey and the eventName have a value enable the connect button otherwise keep it disabled.

The action object is triggered when an action occurs (e.g. a button is clicked). This part of the code handles the click of the Connect button. As all the details are already in the form, the only thing that needs to happen is to save the data. The action result is needed to save the configuration data.

If you would upload all the code for the connector and create a new connection, the screen would look something like this

The Web Integrator activity

Now that the connector is covered, let’s take a look at the activity

├───activity
│ └───ifttt
│ ├───activity.go
│ ├───activity.json
│ ├───activity.module.ts
│ ├───activity.ts
│ ├───activity_test.go
│ └───ifttt.png

Just like above, a good extension still needs that killer icon. The file ifttt.png in this folder is shown on the activity.

activity.json

The activity.json describes the metadata of your activity and looks quite similar to the connector.json file. The important differences here are that is describes the input and output of the activity and that it has a special input type object for a field called iftttConnection. With help of the TypeScript files we'll go over next, this object makes sure we can pick a connection and use that in the code.

activity.ts

The activity.ts file handles a bit of the UI code for the activity. As you're browsing the code you'll see the value object which allows you to specify what types of values you can pick for a certain field. For the field iftttConnection the only allowed types are connections that are created as an iftttConnector (the connector category as specified in the connector.json must match what we specify here).

As with the connector, the activity.ts has a validate object as well and it can be used to validate the input of certain fields. For the field iftttConnection we need to check that the connection has been set and otherwise display an error message (the value already makes sure that you can only pick connections, so there is no need to validate that again).

activity.go

The package ifttt provides connectivity to IFTTT for TIBCO Cloud Integration — Web Integrator using the WebHooks service from IFTTT (https://ifttt.com/maker_webhooks). In the code there are five constants that I’ve used to make my code easier (and more reusable). For example

ivConnection = "iftttConnection"

means I can use a field called ivConnection and at runtime that object will point to the thingy I named iftttConnection in the metadata of my activity. A lot of words to say that ivConnection is the connection object I'll use in the code. The same applies to the other input variables (all starting with iv) and output variables (all starting with ov). The payload struct is used to describe the payload to IFTTT with a maximum of three values (this limit is set by IFTTT). The eval method executes the activity and sends a message to IFTTT. I've documented the steps it takes in the code as well:

  • Step 1 is to validate that the connection has been set. The connection is mandatory whereas the three values are optional so we don’t need to check that.
  • Step 2 is to get the connection details object
  • Step 3 is to build the IFTTT WebHook URL. To trigger the event it will make a POST request to the URL. The URL will have the event name we specified in IFTTT and the webhook key we got from there too (both are extracted from the connection details object)
  • Step 4 is to create JSON payload. The data is completely optional. This content will be passed on to the Action in your Recipe in IFTTT.
  • Step 5 is to send the POST message and handle any errors that might come from there
  • Step 6 is to set the return value so the rest of the Web Integrator flow can use that too

Testing your activity

As good developers you want to make sure that the code you’re writing works perfectly. To make sure you can unit test the code you can create a activity_test.go file. The layout of the file is pretty straight forward and the TestEval method is the unit test for the Eval function and sends a message to IFTTT (make sure that you have updated the values when unit testing the code).

As you updated the variables simply run go test from the ifttt subfolder of activity and it will tell you whether your code will work or not.

Adding Travis CI to the mix

The article I wrote earlier on Continuously Testing Flogo activities is also valid for Web Integrator. In fact, you should see some striking similarities between the folder layout I had there and the one I have in this post. Check out the section on Travis CI to get add CI/CD into the mix of your new activities for Web Integrator.

Using it in a Web Integrator app

To use your extension in a Web Integrator app, you need to upload it to TIBCO Cloud Integration. Simply create a zip file of the root folder (for example wi-ifttt-extension), click on Extensions in the header and upload the zip.

Now you can create a connection to IFTTT from the Connections menu and use the activity in your new app

Conclusion

It isn’t too hard to build your own activities and connector for Web Integrator. As this is my first article here, I’d love to get your feedback!

References

  1. https://en.wikipedia.org/wiki/IFTTT

This article was originally published on my own blog https://retgits.github.io/building-extensions-for-web-integrator/

More by Leon Stigter

Topics of interest

More Related Stories