Ghost API Post Issue

Can anyone spot why this Ghost API Post config might not be working?

https://github.com/huginn/huginn/issues/2575

We’re trying to figure out how to create a post via the API using Huginn.

Thanks.

"headers": {
   "Authorization": "Ghost $token"
},

You will need to replace $token with your admin token

This doesn’t sound entirely correct. Ghost provides you with an Admin API Key, you need to use that to generate a JWT (JSON Web Token) that signs each request to the Admin API via the Authorization header. You can read about the JWT generation in our docs https://ghost.org/docs/api/v2/admin/#token-generation

Unfortunately, I don’t know anything about huginn. You’d need to find out if it’s possible to generate and use JWTs with it.

Thanks Kevin, I’ve tried generating the token manually using the bash script example you give in your docs and using the output of $TOKEN to replace $token but that doesn’t work either, response says the token is invalid.

1 Like

How quickly did you go through the whole process between generating the token and making the request in Huginn? The tokens are only valid for 5 minutes which is the maximum age our API will accept.

Within 60 - 90 seconds, but if the maximum is 5 minutes then I guess Huginn will need to handle that dynamically anyway, so I’m not sure how that will work or if it can.

Huginn is far more powerful than Zapier so I’d really like to get it to work, if someone thinks they can make it work I’ll happily pay for their time and contribute the code to open source for everyone to use with no limitations.

I’ve had a quick look, seems doable by creating a ghost-specific huginn_agent gem but there would be a reasonable degree of coding required. This approach would be similar to how the Zapier integration works.

There’s also a ruby example of token generations in our docs (which Kevin linked) which might help :relaxed:

Someone on GitHub pointed out we can use auth but that’s not working either, the config below returns a 200 but nothing gets posted.

Is the /ghost/admin/session/ endpoint correct?

{
  "post_url": "https://blog.domain.com/ghost/admin/session/",
  "expected_receive_period_in_days": "1",
  "content_type": "json",
  "method": "post",
  "payload": {
    "posts": [
      {
        "username": "user@domain.com",
        "password": "password",
        "title": "My test post",
        "html": "<p>My post content. Work in progress...</p>",
        "status": "published"
      }
    ]
  },
  "headers": {
    "Origin": "https://blog.domain.com"
  },
  "emit_events": "true",
  "no_merge": "false",
  "output_mode": "clean"
}

also tried

{
  "post_url": "https://blog.domain.com/ghost/admin/session/",
  "expected_receive_period_in_days": "1",
  "content_type": "json",
  "method": "post",
  "payload": {
        "username": "user@domain.com",
        "password": "password",
    "posts": [
      {
        "title": "My test post",
        "html": "<p>My post content. Work in progress...</p>",
        "status": "published"
      }
    ]
  },
  "headers": {
    "Origin": "https://blog.domain.com"
  },
  "emit_events": "true",
  "no_merge": "false",
  "output_mode": "clean"
}

@www user/session auth is documented here https://ghost.org/docs/api/v2/admin/#user-authentication

The configs you’ve posted do not look correct, you can’t mix auth data into the payload for the posts endpoint. There are multiple requests involved in using session auth to create a post…

  1. POST /ghost/api/v2/admin/session/
  2. store cookie from response
  3. POST /ghost/api/v2/admin/posts/ ensuring it has a valid Cookie header containing the cookie from step 2

Thanks Kevin.

Time to hire a coder or switch to WordPress, this is way above my pay grade. I was hoping to hack something together quickly but clearly it’s a lot more complex than I thought.

Out of interest, why are you unable to use Zapier? What is it that you are trying to achieve through Huginn?

From what I can see, Huginn is open source so it could be cheaper in the long run but it looks less powerful and more constrained than Zapier.

We have hundreds of sophisticated inputs that require a lot of manipulation that Zapier just can’t handle.

We also output to multiple channels, including email, discourse, discord and public and private blogs. The inputs are updated every 60 seconds which Zapier can’t do (their best update frequency is 5 minutes) and they charge too much for it.

Initially I was going to use WordPress because it’s very simple, but I prefer Ghost - it’s so fast and the user experience is just way better out of the box than WP is.

I’m a big Ghost fan, but I suck at code :frowning:

Sorry, I don’t mean this to come across as a sales pitch for Zapier, just wanted to correct a few things for anyone else who comes across this post :)

We have hundreds of sophisticated inputs that require a lot of manipulation that Zapier just can’t handle.

Zapier has a “code” action where you have full programmatic control over the inputs and you can manipulate the data before passing it onto later steps of your zap (we use this in a number of places, one example is cleaning up URLs in a Google doc before creating a post in Ghost so that the links aren’t passing through Google). There’s also the paths feature that gives you conditional logic within a zap.

The inputs are updated every 60 seconds which Zapier can’t do (their best update frequency is 5 minutes) and they charge too much for it.

True in some cases but it’s dependent on how the integration is coded. The Ghost integration is based on webhooks in the background so it’s all instant, even on the free tier.


I understand completely that it’s not in your interest to move away from Huginn if you’re already using it, especially if your usage would put you into the higher Zapier plans, prices can ramp up quickly at scale!

I’m still interested in the specifics for where Ghost fits into your workflow, it may help someone put together a minimal agent gem :slight_smile: I’d be interested in building something (I built our Zapier integration so I have something to work from) but don’t have much spare time at the moment

Also, we’re not bashing Zapier - it’s great for most people but we’re already committed to Huginn because it’s cheaper, more scalable (in a way we’re comfortable with) and more flexible and we’re not affected by any policy or feature changes Zapier might make in the future, which could really hurt us down the road - it’s important we own and control everything so open source works best for us.

Here’s the flow we’re trying to make work:

Every 60 seconds we’re collecting and processing (heavily in Huginn) information from multiple sources and dumping it as well formatted as possible (thanks to liquid templating in Huginn) programmatically into Private Ghost 1, and when that happens a human editor performing task A gets immediately alerted automatically and does their thing then hits publish when they’re done.

Automation picks up new Private Ghost 1 posts (checking every 60 seconds) and dumps them into Private Ghost 2 where a different human editor performing task B gets alerted and does their thing, then they hit publish when done.

The task separation between Ghost 1 and Ghost 2 human editing is important and additionally serves as a backup in case we need to redo task A.

Automation picks up new Private Ghost 2 posts (checking every 60 seconds) and sends them to Ghost Public in draft form where a final human editor (quality control) checks the post, edits and finally publishes it for public dissemination through private channels.

Automation picks up newly published Ghost Public posts (checking every 60 seconds) and sends out an email campaign with a link to the new Public Ghost Post to a list of subscribers and posts the same with a summary in discourse forums, discord text channels and other private channels, like slack.

There are many reasons why Ghost is better than WP for us, but most importantly is speed of editing, custom routes and overall user experience.

Well… that’s the idea anyway and so far it’s all been possible without any coding - but now we’ve hit this Huginn Ghost roadblock, which is a bit unfortunate but we still love Ghost and want to try to make it work.

Not sure which is the shortest path to making Huginn work with Ghost, there seem to be several options. There’s the gem route which you mentioned and apparently Huginn also has some command processing capability in its agents that allow it to run scripts and use their output.

Phew…