In the previous blog, how to connect the Micro Integrator to the Mastodon API – Part 1, I looked into the API that Mastodon exposes in order to, for instance, automate the posting of new toots (the name of a message on Mastodon). Why is this important? Well, this kind of service, like Twitter before, is becoming a communication channel for companies as well, and where a browser-based interface is ok for regular users, integration in the IT landscape is quite attractive for organizations.
The capability to automate messages (both reading and sending) can streamline processes and in this second part I am going to show the approach to create such an integration using the Connector feature of WSO2 Micro Integrator.
Creating the connector
A connector is a set of services bundled to be integrated with the Micro Integrator. It is a zip file that will be parsed and the individual services are added to the server, enabling you to use it’s functionality like automated sending messages.
From the development side, the same connector can be used in Integration Studio to develop new artifacts that utilize the new functionality, as you will see a bit later on in this article.
Creating a full-blown connector is a lot of work and what I am going to show you now is how you set up the structure and do a simple implementation. One of the reasons being that otherwise the blog would be very big.
So, what I’m going to take as parameters is the access token that we got from the last API call in the previous blog. This will be defined as a parameter and subsequently sent to the back end API as a Header.
Setting up a structure for a connector for the micro integrator is quite simple what you need to do is to use a maven archetype and configure it in such a way that it will hold the API that you would like to expose.
The maven command is as follows:
mvn org.apache.maven.plugins:maven-archetype-plugin:2.4:generate -DarchetypeGroupId=org.wso2.carbon.extension.archetype -DarchetypeArtifactId=org.wso2.carbon.extension.esb.connector-archetype -DarchetypeVersion=2.0.4 -DgroupId=org.wso2.carbon.esb.connector -DartifactId=org.wso2.carbon.esb.connector.mastodon -Dversion=1.0.0 -DarchetypeRepository=http://maven.wso2.org/nexus/content/repositories/wso2-public/
Here you can see part of the structure:
A connector can consist of synapse configurations but also Java and Soap services depending on what’s required.
The src/main/resources is the folder where we are going to make the necessary changes in a very simple and lightweight way. when I open the directory source main resources you will see that there are two subdirectories, sample and config. in the connector file these two are referenced.
We will create a new subdirectory called statuses in which we will define the status template that will allow us to post a status to our user account on Mastodon.
Delete the samples directory and create the statuses directory also make sure that you update the connector file as well. I’ve created an icon subdirectory in which I put two mastodon icons (25×25 and 72×80 png). The documentation is quite vague in the sense that in some examples the icons are referenced in the connector file in the root and in some they are not, simply the directory is there.
I did not reference them but rather simply put them in the right place with the right names.
The API call is easy to capture. This is the source synapse code. As you can see, we expose this as an API. For the connector I am not going to use an API but I’m going to use a sequence template that will take a parameter, in this case the status that we are getting from the API invocation and sending it to the HTTP endpoint.
<?xml version="1.0" encoding="UTF-8"?>
<api context="/mastodon" name="Status" xmlns="http://ws.apache.org/ns/synapse">
<resource methods="POST" url-mapping="/status">
<inSequence>
<property expression="json-eval($.status)" name="uri.var.status"/>
<header name="Authorization" scope="transport" value="Bearer IfC08KP8LtDT9I1bofk-yhoZ9zgswn6CRK23okW42Gk"/>
<call>
<endpoint>
<http method="post" uri-template="https://mastodon.nl/api/v1/statuses?status={uri.var.status}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</resource>
</api>
Here you can also see that the API call is successful and that the status update is available in Mastodon.
What we are now going to do is change the API to reflect the changes. So rather than during the call from the API we are going to call the template with the parameter.
Now instead of the API call we are calling a template that will submit the status update to Mastodon.
<?xml version="1.0" encoding="UTF-8"?>
<template name="write-status" xmlns="http://ws.apache.org/ns/synapse">
<parameter isMandatory="false" name="status"/>
<sequence>
<property expression="$func:status" name="uri.var.status" scope="default" type="STRING"/>
<header name="Authorization" scope="transport" value="Bearer IfC08KP8LtDT9I1bofk-yhoZ9zgswn6CRK23okW42Gk"/>
<call>
<endpoint>
<http method="post" uri-template="https://mastodon.nl/api/v1/statuses?status={uri.var.status}">
<suspendOnFailure>
<initialDuration>-1</initialDuration>
<progressionFactor>-1</progressionFactor>
<maximumDuration>0</maximumDuration>
</suspendOnFailure>
<markForSuspension>
<retriesBeforeSuspension>0</retriesBeforeSuspension>
</markForSuspension>
</http>
</endpoint>
</call>
</sequence>
</template>
And
<?xml version="1.0" encoding="UTF-8"?>
<component name="statuses" type="synapse/template" >
<subComponents>
<component name="write-status" >
<file>write-status.xml</file>
<description>mastodon simple connection</description>
</component>
</subComponents>
</component>
I do a mvn build (mvn clean install) and it results in a connector.
Add it to the Integration Studio in my project.
And there it is, a Mastodon connector with our implemented operations.
I can now start developing artifacts using the Mastodon connector. I will create a proxy that will simply push a message that comes in the payload to our Mastodon account.
The setup is a simple soap message that takes an XML as a payload and takes the message from the payload (//incoming) and sends it to the template to be put to Mastodon.
In graphical overview it looks like this:
In source view like this:
<?xml version="1.0" encoding="UTF-8"?>
<proxy name="MProxy" startOnLoad="true" transports="http https" xmlns="http://ws.apache.org/ns/synapse">
<target>
<inSequence>
<mastodon.write-status>
<status>{//incoming}</status>
</mastodon.write-status>
<respond/>
</inSequence>
<outSequence/>
<faultSequence/>
</target>
</proxy>
I have created a Soap Project in SoapUI where I constructed a very simple body. The <incoming> tag contains the message that is retrieved by the //incoming Xpath command in the code above.
You can see the message coming to Mastodon. Because I take the response from Mastodon and I send it back to the client, in this case so SoapUI you can see the original response from the API.
HTTP/1.1 200 OK
[ … ]{“id”:”109823997802502951″,”created_at”:”2023-02-07T14:46:56.499Z”,”in_reply_to_id”:null,”in_reply_to_account_id”:null,”sensitive”:false,”spoiler_text”:””,”visibility”:”public”,”language”:”en”,”uri”:”https://mastodon.nl/users/yenlo/statuses/109823997802502951″,”url”:”https://mastodon.nl/@yenlo/109823997802502951″,”replies_count”:0,”reblogs_count”:0,”favourites_count”:0,”edited_at”:null,”favourited”:false,”reblogged”:false,”muted”:false,”bookmarked”:false,”pinned”:false,”content”:”\u003cp\u003ethis is mymessage\u003c/p\u003e”,”filtered”:[],”reblog”:null,”application”:{“name”:”yenlo-app”,”website”:null},”account”:{“id”:”109703822406851413″,”username”:”yenlo”,”acct”:”yenlo”,”display_name”:”yenlo”,”locked”:false,”bot”:false,”discoverable”:false,”group”:false
[ … ]}
In Mastodon you only see the message of course.
Result
In a reasonably short time, I’ve created a very simple connector that makes a connection to a service. I said before if you want to do this in a way that it is usable beyond a simple blog like this it will take a lot of time to figure out your API and to implement all of the APIs and services that are available. The setup with a hardcoded access token to the mastodon API is something that of course is never done in a real-world situation. If I were to develop this in a real scenario, I would encrypt the client key client secret tokens and codes and store them in some sort of vault retrieving them whenever I need them.
The big benefit of working with connectors is that a lot of the work has already been done and that’s what you need to do these are only a small part making the connection to the service storing your credentials somewhere and or retrieving them and then you can start by building integrations in a very simple way dragging and dropping them in a graphical view while filling in the details in source view.