Posting with Admin API and webhooks with axios creates a loop

...
// Admin API key goes here
const key = 'ADMIN_KEY';

// Split the key into ID and SECRET
const [id, secret] = key.split(':');

const token = jwt.sign({}, Buffer.from(secret, 'hex'), {
    keyid: id,
    algorithm: 'HS256',
    expiresIn: '5m',
    audience: `/v3/admin/`
});

const headers = { Authorization: `Ghost ${token}` };

app.post('/webhook', (req, res) => {

        #...
        #ghost action trigger
        #data processing
        #...

        payload = {
            posts: [{
                ...
            }]
        };
       
            try {
                #insert new post
                axios.post(urlInsert, payload, { headers })
                    .then(function (response) {
                        console.log("test")
                    })
                    .catch(error => console.log(error));
    
            } catch (err) {
                console.error(err);
            }

})

this simplified code creates an unwanted loop
the result is the following

"test"
"test"
"test"
"test"
...

something i am doing wrong, how can i avoid the loop?

app.post('/webhook', (req, res) => {
    getData(req)
})

const getData = async (req) => {
    try {
        await axios.post(urlInsert, payload, { headers })
            .then(function (response) {
                console.log("TEST")
            })
            .catch(error => console.log(error));
    } catch (err) {
        console.log(err)
    }

}

i also tried this way, i have the same problem … an infinite loop

What’s urlInsert? It isn’t /webhook, by any chance?

/webhook is the trigger from Ghost, urlinsert is the link to insert a new post

http://localhost:2368/ghost/api/v3/admin/posts?source=html

when I perform a specific action from Ghost, I use the webhook to insert a new post

What calls app.post(/webhook)? What’s the non-error response from the function call? Is it creating four posts with the same content but different slugs?

when I create an article I trigger the “Post published” event, it calls the url http://localhost:9000/webhook

then in app.post('/webhook') I take all the information of the post, modify some things of my interest and insert a new article with axios.post(urlInsert), but the result of this is the insertion of an infinite number of articles with different slugs

Is this from the same Ghost site?

The circular behavior would then be expected:

  1. Publish
  2. Published webhook
  3. Edit post
  4. Publish

Because you’re publishing again, the webhook will trigger, the post will be edited, published, and the cycle continues.

Does that sound like what could be the case?

Maybe I did not say it clear enough.

The site is the same.

Publish
Published webhook
Edit data
Publish new post

The original article is not changed
So at the end of the cycle I have two articles published.
The first article published from the Ghost backend, and the second posted with the API using the modified data of the first.

At least that’s what I try to do, it actually creates an infinite loop.

Yeah. Because when you publish the second post via the API, it triggers another webhook, which kicks off the whole process again and again.

What I think you could do would be to tag your original post, then check for that tag in your JS. If it’s there, remove it for the new post with edited data. That way, you can stop execution for any post that doesn’t have that tag and stop the loop.

It was really obvious, I don’t know how I didn’t think about it, thanks

1 Like