Hello,
I’ve been working on automating a process for a Ghost blog where I need to remove all the links from the posts. The workflow I’ve been following is:
- Fetch all articles using the Ghost Content API.
- Process the articles to remove all the links.
- Update the articles using the Ghost Admin API.
However, I’ve run into a series of issues during this process:
Errors and Issues:
Initially, there was an issue with generating the JWT token for the Admin API. Seems I’ve resolved this, but it led to another problem.
Despite generating the JWT token according to Ghost’s documentation, the Admin API consistently returns an “Invalid token: invalid signature” error.
While updating my code, I found that certain methods, like decode(), behaved differently between Python versions. For instance, in Python 3.11.5, the method decode was flagged as an error because the generated JWT was already a string. But working around that did not help me.
Here’s the Python code I’ve been using:
import requests
import re
import jwt
import time
# Ghost API details
api_url = "###"
content_api_key = "###"
admin_api_key = "###"
# Fetching the first post using the Content API
response = requests.get(f"{api_url}/ghost/api/v4/content/posts/?key={content_api_key}&limit=1")
data = response.json()
post = data['posts'][0]
# Removing all links from the HTML content
clean_content = re.sub(r'<a [^>]*>([^<]+)</a>', r'\1', post['html'])
# Converting the HTML to Mobiledoc format
mobiledoc_structure = {
"version": "0.3.1",
"markups": [],
"atoms": [],
"cards": [["html", {"cardName": "html", "html": clean_content}]],
"sections": [[10, 0]]
}
# Encoding the JWT token for the Admin API
header = {
"alg": "HS256",
"typ": "JWT",
"kid": admin_api_key.split(':')[0]
}
payload = {
"iat": int(time.time()), # current time
"exp": int(time.time()) + 86400, # current time + 24 hours
"aud": "/v4/admin/"
}
token = jwt.encode(payload, admin_api_key.split(':')[1], algorithm="HS256", headers=header)
# Updating the post using the Admin API
update_url = f"{api_url}/ghost/api/v4/admin/posts/{post['id']}/"
headers = {
"Authorization": f"Ghost {token}" # Removed the .decode('utf-8') here
}
data = {
"posts": [{
"mobiledoc": str(mobiledoc_structure),
"html": clean_content # setting the HTML directly just for redundancy, mobiledoc should be enough
}]
}
response = requests.put(update_url, json=data, headers=headers)
if response.status_code == 200:
print("Post updated successfully!")
else:
print(f"Failed to update the post. Response: {response.text}")
I’m particularly perplexed by the “Invalid token: invalid signature” error, as I’ve followed the Ghost documentation closely when generating the JWT token. If anyone has encountered similar issues, especially with updating content on ghost with API, the Ghost Admin API and JWT token generation, I’d greatly appreciate your insights.
Thanks in advance!