In my previous post, I showed how to cross-post to Dev.to using its API. In this post, I will show how to cross-post to Hashnode using its API.
Getting Started
Dev.to's API is a REST API. It is pretty straightforward to use. Hashnode's API is a GraphQL API. If you are not familiar with GraphQL, you can think of it as a query language running over HTTP that can traverse and manipulate the data graph.
Hashnode API is well-documented. Also, it comes with a GraphiQL playground. You can use the playground to explore the API and test your queries.
Most of the queries to the Hashnode API should work without authentication. However, since we are going to create a (draft) article, we need to authenticate the API requests. To do so, we need to obtain an API key from the Hashnode settings page.
Also, Hashnode needs to know which "publication" we are targeting. You can find it in the URL of your publication's (or your blog's) dashboard. It looks something like this:
https://hashnode.com/0123456789abcdef01234567/dashboard
So, the publication ID
is then 0123456789abcdef01234567
.
I have put the API key and the publication ID in my .envrc
file:
export THENEGATION_HASHNODE_APIKEY="MyVerySecretApiKey"
export THENEGATION_HASHNODE_PUBLICATION_ID="0123456789abcdef01234567"
Create a New Article
We will use the following GraphQL mutation operation to create a new article:
mutation CreateDraft($input: CreateDraftInput!) {
createDraft(input: $input) {
draft {
id
slug
title
}
}
}
What does this mean?
-
CreateDraft
is the name of the operation. -
$input
is a variable that will be passed to the operation. -
createDraft
is the mutation operation. -
draft
is the object that will be returned by the operation with theid
,slug
, andtitle
fields.
The test $input
looks like this:
{
"input": {
"publicationId": "0123456789abcdef01234567",
"title": "string",
"contentMarkdown": "string"
}
}
Then, we can use the following curl
command to create a draft article:
curl \
-X POST \
-H "content-type: application/json" \
-H "authorization: ${THENEGATION_HASHNODE_APIKEY}" \
-d '{
"query": "mutation CreateDraft($input: CreateDraftInput!) { createDraft(input: $input) { draft { id slug title } } }",
"variables": {
"input": {
"publicationId": "${THENEGATION_HASHNODE_PUBLICATION_ID}",
"title": "My New Article",
"contentMarkdown": "This is the content of my new article.",
}
}
}' \
"https://gql.hashnode.com/"
It worked on my computer!
Scripting?
A little bit self-plagiarism is not bad, right? I have taken the script from my previous post and modified it to work with Hashnode:
#!/usr/bin/env bash
## Get the path to the Markdown file:
_path="${1}"
## Extract the title from the front-matter of the Markdown file:
_title="$(yq --front-matter=extract .title "${_path}")"
## Convert the Markdown file to target format (commonmark):
_body="$(dev-md-format "${_path}")"
## Get the filename of the Markdown file:
_filename=$(basename -- "${_path}")
## Extract the slug from the filename:
_slug="$(echo "${_filename%.*}" | cut -f 2- -d "_")"
## Build the URL for the post:
_url="https://thenegation.com/posts/${_slug}/"
## Build the payload for the API request:
_payload="$(jq \
--null-input \
--arg title "${_title}" \
--arg slug "${_slug}" \
--arg body "${_body}" \
--arg url "${_url}" \
--arg publication "${THENEGATION_HASHNODE_PUBLICATION_ID}" \
'{
"query": "mutation CreateDraft($input: CreateDraftInput!) { createDraft(input: $input) { draft { id slug title } } }",
"variables": {
"input": {
"title": $title,
"publicationId": $publication,
"contentMarkdown": $body,
"slug": $slug,
"originalArticleURL": $url,
"metaTags": {
"title": $title
}
}
}
}'
)"
## Make the API request:
curl \
-sX POST \
-H "authorization: ${THENEGATION_HASHNODE_APIKEY}" \
-H "content-type: application/json" \
-d "${_payload}" \
"https://gql.hashnode.com/" |
jq .
I added this script to my Nix shell with name dev-cross-post-hashnode
:
dev-cross-post-hashnode content/posts/2024-08-21_crosspost-api-hashnode.md
Done! Going forward, I can cross-post to Hashnode with a single command, almost, as I still need to make a few adjustment to the draft and then publish on Hashnode Website, but it is a good start.