Cross-posting blog posts to Mastodon, Twitter and LinkedIn using Azure Logic Apps

Published on
Reading time
Authors

Welcome! If you're reading this, then I have successfully implemented my plan to build a content cross-posting service using Azure Logic Apps!

In the 10 years that I've been blogging I've learnt that the easiest way to get people across your latest content is to proactively publish alerts to various social platforms. Traditionally I've only ever used Twitter, LinkedIn and dev.to but am increasing my publication to Mastodon.

I blog using the SaaS-version of Wordpress from Wordpress.com which at the subscription level I have provides only limited social endpoints to publish alerts to.

A developer loves nothing if not a good challenge, so let's take a look at how I can build a cross-posting solution using Azure Logic Apps!

Mastodon custom connector for Logic Apps

The first thing I'd usually look to do to make my life easier would be to build a custom Logic Apps connector for the Mastodon API, similar to what I did previously with the Meetup API.

At time of writing this post, the Mastodon team are still working on an autogenerated OpenAPI spec for app developers, so I've decided not to use one of the existing static specifications to avoid having to rework a connector in future.

Regardless, we can easily use Logic Apps with Mastodon to post content (also known as a 'toot'!). Let's take a look at how!

Setup a Mastodon application identity

In order to post the content I have I will need to use the API published by Mastodon, specifically the Post new status endpoint.

This API requires authentication and authorisation in order to be used, so I have to setup a client registration for my Logic App which provides it with privleges to post on my behalf.

To set this up you need to visit the Mastodon server your account is homed on and then use the Development option (1) to create a new application (2).

Screenshot of the Mastodon Development menu screen.

Give the application a meaningful name and set the permission scope accordingly. In my case I will only post new items, so I select the write:statuses scope (shown by arrow in image) for this application.

Important note: put a real web address in the application website field as this value is used along with the application name in any posts made on Mastodon (see below).

Mastodon application registration page with write:statuses scope selected.

Here's a sample post with the application name highlighted. You can click on this and be taken to the web address supplied.

Sample Mastodon post with client application name highlighted.

Once I save the Application the Mastodon server returns the registration details for the application, which will seem familiar if you've used OAuth previously. These are super sensitive, so don't share with anyone (just like it says in the screenshot!)

Application registration displaying client details and keys.

Now I have a token (highlighted in red) that I need to call the Mastodon API so let's progress on to building our Logic App solution.

Logic App Message Distributor

Ideally I'd like to drive my final solution off of a webhook tied to the Post publication event on Wordpress, but this feature isn't available for my Wordpress subscription, so instead I use a simple HTTP trigger in my Logic App.

The benefit of this approach is I allow any upstream service to post to it, which means if I ever move off Wordpress I could fairly easily do something like wire a call to the Logic App into, say, a GitHub Action if I were looking to publish a static website.

The first step I need to take is define what data I want to send out to all the services I publish to. For the purpose of this blog post I am going to use the following simple JSON format when calling my Logic App.

{
  "Title": "A sample blog post title",
  "Summary": "This is a test blog post summary.",
  "ImageRef": "https://link.to/image/for/share",
  "Link": "https://blog.siliconvalve.com/"
}

The great thing in using JSON is that the HTTP trigger in the Logic App will automatically parse the JSON and turn each property into a variable in my Logic App that I can easily reference in Actions.

So the solution is reusable I am going to create a Parameter for the Logic App - MastodonHost - which will hold the hostname on the Mastodon server we want to post to ('mastodon.online' in my case).

Additionally, as the Mastodon token is sensitive, even with a restricted scope, I am still going to place it into an Azure Key Vault secret that can be read by the Logic App at runtime using a managed service identity.

Posting to Mastodon

Now we have all the bits in place we can go ahead and use the standard HTTP action to invoke the Mastodon API.

Logic App HTTP Action configured to post a message on Mastodon.

The key vault secret value is passed in as part of the HTTP Authorization header as an OAuth Bearer token and we set the content type appropriately. The body of the message contains the status we wish to post. There are lots of other types we can publish (media and polls), but for my use case I simply want to publish some text and a link.

If I want to post to Mastodon I can use a simple REST client such as Thunderclient to test it out. You can see the resulting post above.

Simple REST request to pust a post into Mastodon.

Extending the idea

Developers love the concept of Don't Repeat Yourself (DRY), so let's extend our posting Logic App to help us in other places. For my example I've added Twitter and LinkedIn cross-posting which is done in parallel to my Mastodon post.

I'm not going to go into depth how to add these steps as they are well documented elsewhere (Twitter and LinkedIn).

The full solution is visualised below - click to enlarge.

Azure Logic App that cross posts content on Mastodon, Twitter and LinkedIn.

Wrapping it up

So, there we are - a quick no-code way to take a single piece of text, hyperlink (and an optional image) and post it to Mastodon, Twitter and LinkedIn. You can grab the bicep deployment template for this solution from the GitHub repository it is stored in.

The beauty of spinning this solution up in a Consumption Plan for Logic Apps is that I will only pay when I invoke the API which means there is minimal cost for the value it adds.

Now I just need to disable the social auto-posting from Wordpress!

Happy Days! 😎