Trouble updating a post using micropub API endpoint

Hello again :smile:

Continuing onward with my journey, I’ve hit a bit of a roadblock with updating a post. I feel like I might be missing something obvious but I haven’t made any headway in a couple of days so I figure I would ask.

I’m trying to update a blog post using the micropub endpoint and I’m following the micropub specification linked in the documentation. Using JavaScript I’m creating a POST like this…

let contentMethod = {
    method: "POST",
    headers: {
        "Authorization": "Bearer " + access_token,
        "Content-Type": "application/json"
    },
    data: {
        "action": "update",
        "url": data.fields.url,
        "replace": {
            "name": [data.fields.title],
            "content": [data.fields.content],
            "post-status": [data.fields.status],
            "category": categories
        }
    }
};

let postingContent = await fetch("https://micro.blog/micropub", contentMethod);
let results = await postingContent.json();

The data itself looks okay to me. The url is the post url, categories is an array of strings and all the data.fields have data in them.

The response I get is

{
  error: "invalid_request",
  error_description: "No content or photo or summary."
}

Which makes me think it’s interpreting my request as a create. Any pointers? Am I using the wrong endpoint or content-type or method?

Thanks!
Loura

Hey Loura,

I’m really impressed with what you’re doing with your project!

The fetch function expects body as an option instead of data. I haven’t had a chance to test the following code, but it should be on the right track. Fingers crossed! :sweat_smile:

fetch("https://micro.blog/micropub", {
  method: "POST",
  headers: {
    "Authorization": "Bearer " + access_token,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    action: "update",
    url: data.fields.url,
    replace: {
      name: [data.fields.title],
      content: [data.fields.content],
      post-status: [data.fields.status],
      category: categories
    }
  })
});

You’re right :smile:.

I should have checked more closely when pasting my code in. I was trying out all sorts of configurations to see if I could get it to work. Unfortunately, I still get the same error above (invalid_request) when using the body if I send it as an object.

Using JSON.stringify on the object and sending it throws an Unexpected end of JSON input which is throwing me for a loop since if I console.log the output everything looks in order (jsonlint.com says its valid JSON, and I can do a JSON.parse without error):

{"action":"update","url":"https://heyloura-test.micro.blog/2023/09/21/here-we-go.html","replace":{"name":[""],"content":["Here we go. Sending along categories. With updates."],"post-status":["publish"],"category":["Private","Public"]}}

It also happens if I hard code in the JSON string above. Maybe this is something Deno specific that I’ll need to resolve that first. Hmmmm :thinking:

I slimmed the example down a bit and ran the following successfully on deno 1.36.4.

fetch("https://micro.blog/micropub", {
  method: "POST",
  headers: {
    "Authorization": "Bearer MY_TOKEN",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    action: "update",
    url: "https://my-test-blog.micro.blog/2023/09/22/test-post.html",
    replace: {
      content: ["hello, world!"]
    }
  })
});

Doh!!! I figured it out. As I expected. It was something simple I was overlooking.

Thank you so much for your help @sod. I grabbed a cup of tea, relooked at your sample, and eventually what I was doing wrong came to me. The error I was running into didn’t have anything to do with how I was sending the response… It was when I was getting the response and assuming it was JSON and trying to do let results = await postingContent.json(). Hence the Unexpected end of JSON input error. I removed the .json() and everything started working.

Just in case anyone else comes across this and is trying to get an update working. This is what finally worked:

    let postingContent = await fetch("https://micro.blog/micropub", {
        method: "POST",
        headers: {
            "Authorization": "Bearer " + access_token,
            "Content-Type": "application/json"
        },
        body: JSON.stringify({
            action: "update",
            "mp-destination": data.fields.destination,
            url: data.fields.url,
            replace: {
                content: [data.fields.content],
                name: [data.fields.title],
                category: categories
            }
        })
    });
    let results = await postingContent;
    console.log(results);

Now I can edit and delete posts in my micro.blog client :partying_face::tada::dancer:

2 Likes

Yay! :tada: