ref: GitHub webhook guide, Medium API doc, Medium node SDK, Webhook server
For the past month, I have been using GitHub issue tracker to take note on what I learn every day. But what if I want to post these notes on Medium?
Use GitHub webhook + Medium SDK
Of course we don’t need to copy-and-paste every post. We can use Github webhook and Medium SDK to achieve this goal.
There are a few steps:
- Deploy a server to receive the webhook
- On the Github repo, setup GitHub repo’s web-hook
- On the server, extract the data from the webhook and post via Medium SDK
Let’s do it step by step.
1. Deploy a server to receive the webhook
First, we need to make a very tiny server and open an endpoint github_api_callback:
var express = require('express')
var bodyParser = require('body-parser')
var app = express()
app.use(bodyParser.json());
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.post('/github_api_callback', function (req, res) {
// do something
res.send('callback!')
})
app.listen(3000, function () {
console.log('Webhook server is listening on port 3000!');
})
2. Set up GitHub repo’s webhook
For example: we have a GitHub repo til. Navigate to Settings tab, select Webhooks on the sidebar, and click Add webhook:
Here Payload URL is where we need to put the the webhook url, which is the endpoint /github_callback_api we created in step 1. Next, select event issues since we need to gather issue tracker’s event.
3–1. Extract data from the webhook
Every action we do on an issue will trigger the webhook. Eventually we will receive a lot of events and data. In what condition should we post to Medium? I use 2 conditions.
- When the action is labeled, which occurs when I label any tag on an issue.
- When the issue has the label published.
This means: it should be posted on Medium if an issue is labeled with tag “published.” Let’s take a look on the implementation:
// GitHub_receiver
module.exports = {
inspect: function(payload) {
var labeled = (payload.action == 'labeled')
var published = (payload.issue.labels.findIndex(function(label) {
return label.name == 'Published'
}) != -1)
return (labeled && published) ?
{
shouldPublish: true,
payload: {
title: payload.issue.title,
body: payload.issue.body
}
} : { shouldPublish: false }
}
}
3–2. Post via Medium SDK
Finally, we need to post on Medium. To achieve this, we need to get the access token first. Just navigate to the setting page to get the token.
Next, install medium SDK. Then we can post to Medium without pain! Let’s see what is going on:
// medium_publisher
var medium = require('medium-sdk')
module.exports = {
publish: function(payload) {
var client = new medium.MediumClient({
clientId: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET
})
client.setAccessToken(process.env.ACCESS_TOKEN)
client.getUser(function (err, user) {
client.createPost({
userId: user.id,
title: payload.title,
contentFormat: medium.PostContentFormat.MARKDOWN,
content: payload.body,
publishStatus: medium.PostPublishStatus.DRAFT
}, function (err, post) {
if (err) {
console.log(err)
}
})
})
}
}
Here is the final webhook server:
// index.js
// ...
app.post('/github_api_callback', function (req, res) {
var result = receiver.inspect(req.body)
if (result.shouldPublish) {
publisher.publish(result.payload)
}
res.send('callback!')
})
// ...
That’s it! Happy posting!