Clay Tech

"clay-works make things real"

translated from clazytech.com

I Set Out to Hit Like and Ended Up Moving 186 Posts to Note

An acquaintance of mine had started a note, so I went to read it. When I tried to hit the like button, it told me I needed to log in.

That reminded me I had a note account of my own. Remembering it was one thing, but I had no idea which email address I’d used to register, or what the password was. After trying a few combinations I finally got in, and found my own articles lined up, with updates stopped in 2021. I’d switched my blog over to my own domain, clazytech.com, in 2021, and had completely left note untouched ever since (the neglect is almost impressive, even to me).

A thought occurred to me.

If the effort were close to zero, keeping note going too might be worth it. note has its own readers, people who would never come to my company blog otherwise. But “close to zero” is the condition — if I had to paste each article into two places by hand every time I wrote one, I’d probably give up around the third try.

So I asked Claude to automate it. The first thing I asked was whether note even accepts posting via script in the first place. It turns out note has no official posting API. On the other hand, the terms of service don’t explicitly prohibit automation — spam-like posting or excessive server load are what get an account suspended. Operating a browser automatically and posting at a human-like frequency didn’t seem like it would be a problem.

I thought this could work.

How to line up the old articles

I set the scope as the 186 articles from June 10, 2021 onward. Articles before that were excluded, since I might have posted the same ones to note back then too.

The first snag was the dates. On a normal note post, you can’t set the publish date in the past. If I posted all 186 as new, articles I’d written five years ago would flow into note’s “new arrivals” feed as if they were “today’s articles.” From a reader’s perspective, someone they don’t know would suddenly start posting old stuff every day — which is just strange.

My first idea was to space them out rather than dump them all at once. I had a spec written up with options like compressing the original clazytech publication intervals down to one per day, or following a few weeks behind. Since scheduled posting on note is a premium-only feature, I planned to keep it free and have a script run periodically to post one article at its scheduled time. But however you space them, getting through 186 articles would take months, and the dates still wouldn’t match the real ones.

Eventually I noticed note has an import feature. Feed it a WordPress export file (WXR format) and the articles come in as drafts. According to the help docs, the publish date becomes whatever date is written in the file, and articles with past dates don’t appear in “new arrivals” when published — they just sit at the corresponding date on the creator’s page.

That was exactly what I needed.

So I decided: articles written up through April 1, 2026 would be imported and lined up with their original dates intact, while the more recent ones after that would be posted fresh, one every one to two days, so they could also be read as new arrivals.

There’s an exception, though. Posting an article written right after a World Cup match as a “new arrival” months later is, frankly, too stale. For articles that lose most of their appeal once their moment has passed, I decided to import them with their original dates even if they’re recent.

Deciding whether something counts as “topical” turns out to be surprisingly hard

I had the Claude API make this call. For the 58 articles from April 2026 onward, I passed the title, publish date, and body text, and asked it to judge — with a confidence score and reasoning — whether it would feel natural to read as a new arrival months later. Anything below 0.8 confidence, I decided myself.

The first pass flagged 9 articles for review. Looking at them, I saw that Claude was reading analyses that used a topical event as an entry point as considerably less topical than I would. I get the point. Even an article prompted by IPO numbers is really arguing about the underlying structure.

That’s true. But to my sense, that counts as topical. Articles prompted by IPO numbers, by something that just happened after a transfer, or written on the assumption that the reader is watching matches during a tournament — even when they’re discussing structure, they’re relying on the reader having seen or heard about that event around the same time. Read months later, that assumption is the one thing missing.

So I reframed the criterion as “was this written prompted by a recent event, on the assumption that the reader encountered it around the same time,” and fed the prompt examples of articles I’d judged myself. After running this about three times, almost nothing was left on the boundary. In the end, of the recent articles, 19 went to the import side and 39 to the new-arrivals side (while I was at it, I also had Claude come up with 5 hashtags per article, since I’d barely tagged anything on the WordPress side).

Publishing just one article first

An imported draft isn’t done just by publishing it as-is. The header image and hashtags don’t come through in the import, so I had to open each draft one by one and add them. This too I did through browser automation. The header image button has no label, so I’m locating the unlabeled button above the title field by position (if note’s UI changes, this is probably the first thing to break).

When I published the first article and looked at it, there were 24 empty paragraphs scattered between the real ones.

This is bad.

The cause was simple: line breaks I’d placed between HTML tags in the WXR body text had been imported as-is as empty paragraphs. I fixed it by compressing the line breaks, and for the first article I deleted the empty paragraphs by hand in the editor. The thought of having published all 127 like that is chilling.

After publishing, I added a mechanism to check whether the date shown on the article page matched the original date down to the minute, and to stop if it didn’t. After publishing a few and confirming they were fine, I ran the remaining 121 overnight, five at a time. It took 5 hours, but every date matched.

The stumbling didn’t end there.

My more recent articles include SVG diagrams I drew myself, but SVGs don’t come through in the import. I decided to place a marker paragraph reading “[SVG Figure 1]” where the diagram goes, convert the SVG to PNG before publishing, and replace the marker with the image in the editor. Converting to PNG was easy — just render it in a headless browser and take a screenshot. The replacement inside the editor was the tedious part: in long articles the cursor would, for some reason, jump to the title field when I pressed End; the editor would redraw the body right after loading, making an element I’d grabbed earlier stale; autosave wouldn’t catch up if I navigated away; and if something stopped midway, it would autosave a state where the marker was gone but the image hadn’t been inserted. One problem after another.

A pain.

In the end, I settled on re-reading the saved body text, checking the number of images and any remaining markers, before publishing.

Link cards in the articles (the framed thumbnail-and-title boxes for external pages) also fell apart into separate images and text on conversion, with other sites’ photos and favicons getting re-saved as note’s own body images. I didn’t notice until after the import, and for 2 articles I deleted the draft and reimported it. Now I render link cards as a single line of title plus link.

Then, when I tried to import the last article, I was told I’d “reached the limit.” The help docs only mention limits on size and count, but apparently there’s also a limit on how many imports you can do per day. For topical, recent articles, I decided to let a few accumulate before importing them together.

Running it every 5 minutes on my home Ubuntu machine

For the 39 on the new-arrivals side, I kept the original publish order and compressed the original intervals to a quarter of their length. At most one per day, with intervals ranging from 24 hours to 7 days, and times anchored to the original publish time but nudged into the 7am–11pm window, shifted by a few minutes. This spreads articles written between April and October out across October 17 to December 22, appearing every one to two days.

The execution logic is just: check if the scheduled time has passed, and if so, post one article — run every 5 minutes. I decided to run this continuously on my home Ubuntu machine, and since that machine runs plenty of other things too, I confined it to a Docker container.

I hit a snag here too. With a headless browser, the new-article editor screen would hang on loading. The cause was the browser identifying itself as “HeadlessChrome”; once I had it identify as regular Chrome, it opened fine. There was also an issue where it worked from the terminal but a systemd timer couldn’t reach Docker. The user’s systemd had been running continuously since before I was added to the docker group, so the permission change hadn’t taken effect (obvious once you know, of course). I fixed it by having it launch through sg docker.

For login, I log in once on my Mac, which has a screen, and send the resulting login state (cookies) as a file to the Ubuntu machine. Since the cookies get re-saved every run, they’re unlikely to expire as long as it keeps running regularly.

What I was most careful about was double-posting. If the same article went out to new arrivals twice, that would be indistinguishable from spam. Right before hitting publish, I set the status to “publishing,” then confirm the publish via note’s API before setting it to “published.” If an article is left stuck at “publishing,” the system does nothing further and just notifies me — it never retries automatically. Unglamorous, but I didn’t cut corners here.

So, did the effort actually get down to close to zero?

A day and a half after I started building this, 146 articles were lined up on note with their original dates, and 39 were sitting in the queue (the remaining 1 was waiting on the import limit). My note, which had been frozen since 2021, now looks like this.

[

Yuichiro ‘kuz’ Kuzuryu|note

note.com/claytech](https://note.com/claytech)

I handed the spec to Claude Code and had it write the actual code. What I did was: decide on the policy, decide on the articles where topicality was ambiguous, upload the import files, and judge whether something was okay to publish. That’s about it.

From now on, when I write a new article, its topicality gets judged, and it either joins the back of the new-arrivals queue or waits for import if it’s topical. What’s left for me to do with note is little more than occasionally uploading an import file. I’ve basically hit the “close to zero” condition I set out with.

I’ll probably forget my note password again. But since the cookies get re-saved every run, the articles will keep piling up on their own regardless.

Though I might still run into trouble the next time I try to like an acquaintance’s article.

This piece was drafted and directed by Yuichiro Kuzuryu, with the writing by AI.


Originally published in Japanese at https://clazytech.com/2026/10/1878/. Translated with LLM assistance and reviewed before publication.