Adding comments to your Ghost blog with Mastodon
Making an Ivory Bridge
I’ve wanted to add comments to my various blogs for a few years now. I had this idea for awhile kicking around in my head of linking a Twitter thread, or a matrix.org channel to an article so that folks could comment and then it would display in the article. With all the drama of Twitter that has happened over the last week, I really started to pick up and enjoy using Mastodon for microblogging. I’ve had Fediverse accounts in the past, but never really stuck with it as most of the network effect was not there, it just took a #SpaceKaren to kick us all out in the right direction ;)
In this post I will go over how I built comments into this blog and provide code so that you can also integrate Mastodon with your Ghost blog.
The workflow idea
The workflow requires a middle layer to do the heavy lifting of posting the article to Mastodon, and then updating the article with the thread ID of the Toot.
Working with the Ghost API
In order to accomplish what we need to do with the bridge, we need to setup an integration in Ghost and access the blog’s admin API. The Ghost docs explain it really well, so I’d suggest reading up on it [They have code examples as well].
Admin API docs:
Working with Mastodon.py
In order to post a Toot and then get the ID back we need to work with the Mastodon API. Luckily there is a nice Python module called Mastodon.py we can work with to get sorted.
You can setup an integration with the module, or manually do it in your user preferences on the instance you belong to. I had already created an integration, so I used that [screenshot]. You will need read and write scopes for this to work.
One thing of note, we will need to lockdown somethings in order to make this a bit more secure. I will highlight them here.
For the text coming back from Mastodon comments, we push it through DOMPurify to “clean” up the text.
Nginx deny access rules
We will setup Nginx to only accept requests from our local server and not the entire web. This locks it down so that only our Ghost blog can “talk” to the web hook.
If you are into computer security and have any other suggestions, please reach out to me on Mastodon as I am always keen to learn more.
The Ivory Bridge
Here is the main component of all this. The bridge accepts posts from Ghost via the integration webhook. It is a Python Flask app that takes the data from the post, formats some text, creates hashtags, and sends a Toot from that info. Once the Toot is sent, it takes the ID, and updates the article with the ID via the Ghost API.
Setting up Ghost
I am using the Solo theme for my blog. I copied the
custom-mastodon.hbs and added the code below. The folks at Ghost have a good tutorial on how to do that properly if you need more instructions:
Link to my current theme:
Once we have the theme in place, activate it and update the Mastodon Host and Mastodon Username in Settings > Design > Site-wide
Now that you have the custom theme loaded, when you create a new article, you will need to select the mastodon template in order to see the comments after publishing.
Code to replace the default post's comments section
Deploying the bridge to a VPS
I have been using this Ansible playbook for years now to deploy Flask web sites. I highly recommend reading the article that accompanies the code repo.
I used it to deploy the ivory bridge to my VPS.
Article to read:
So now with all that written and deployed, comments are available in future posts on this blog.
If you have any questions or comments, please feel free to reach out to me on Mastodon.
Using Mastodon for comments on a static blog
Adding comments to your static blog with Mastodon
Add comments to static website build with Jekyll
Art prompt [Midjourney]:
Surreal, bridge made of ivory with three cute elephants walking across it, bridge between the worlds, fairy magnificent, elegant, ebony black and shining like glass, sweeping arches, cinematic lighting, awe inspiring, octane render, high definition, trending artstation, digital art, by studio ghibli, brom, jordan grimmer, greg rutkowski --v 4