Home
DevWriting

Building A Blog (BAB'ing) Part: 1


I have held in my head for many years that BAB'ing is hard. You not only have to set up the site using WordPress, or another tool... but you have to write the posts, and I have struggled with that the most. I start writing, then I ask myself why would I use this choice of words, or what am I telling people this. Usually it ends up being a very bad guide on how to live your life, or a bad story about how stupid I am.

But not today! Today I have a real story, real advice, and even more importantly a good reason... I built a blog. It does everything, from the basics of rendering the text that I wrote in a country, sending it out from a server in Germany, through Cloudflare infrastructure, and after a lot of "hubub" and in less than 100 milliseconds, it starts lighting up the pixels on your screen, giving your face a dose of light, and ya... well that got long. All in all, you're here, I'm here, and if you stay I will tell you more!

The Idea

The first thing I do in the morning is wake up. That's obvious, and in no particular order after that I use the toilet, look at my phone, and think what do I have to do today... it's a bit of a hassle and being the nincompoop that I am, I look at the news and feel sad. Where is the world headed? IDK, but I felt I must make something. So one of these days I said, let's make a blog site! Why not! How hard could it be? And you're not wrong thinking the AI could do it quick, but I wanted it to do a lot: newsletters, privacy-focused tracker, nice layout, easy format to write in, no proprietary tools designed to fit all sizes. I wanted a clean, cool, and good blog site, and so here it is!

I started building it the 31st of May, originally under the name "Peskymice" (my old failed home IT business), but over the coming hours it grew clear that that was not an option. Not only was the name too good for a blog like this, but the colours did not match, and I forgot where the source code for the Peskymice site was, so it was not like I could change the colours there (not to mention I would have to update the images, or live knowing that it was wrong). I played around with the name a little and decided that "TheITJournal" was a good enough name.

I started building this site in Python, as Python is good for anything. After the first test server that tried grabbing posts from Directus and then making it render to an HTML page, I had the realisation that Python was too slow — it could only handle like 1,000 people on the site at once, and Directus was just a bit overkill for what I needed (not to mention the database upkeep that Directus uses). So I "ported" the server code to Go, and then promptly deleted all the code and rebuilt from scratch... luckily with AI this was not a large feat, and in a couple of hours I had got to the point where the front end UI was looking good, the server was rendering the Markdown files from a folder and making HTML pages from them, and then they were being sent out. At this point I had a few Bash scripts (put simply, a Bash script is just a plain text file ending in .sh that runs commands automatically. It's like saving a bunch of code you would normally paste into your terminal so you can run it all at once.) and these scripts were running the basics like building the binary and then running it, to doing odd stuff that is only just okay — for example the draft preview system. This was needing the Bash script to pull keys from the config, find file names, generate keys, and run Python inside the Bash script to format outputs, then finally output the draft preview URL.

The Draft Preview URL

This was one of the first larger things I implemented. I wanted a system where I could share a URL with someone and that person could look at the draft preview, but it would not show up on the main site. The way I did it was using "query parameters" — basically the thing that you might see at the end of a URL that looks kinda like this: "apple.com/macbooks?ref=<not-microsoft>". You use the "?" to denote a parameter, and then the name of the parameter — in this case "ref" — and finally the "=" and "<not-microsoft>", the last being for who the ref is (ref = referrer). It doesn't really matter what the name of the parameter is, so I used "spfp" — please don't ask what it stands for, as at the moment I have no idea. Anyway, using this parameter at the end of a URL allows me to show the server that I know a secret, and in this case it allows me to tell the server "hey, I know this draft exists, here's a code to prove it", and then the server sees the query parameter and says "ok, ya, here is the page". To make it secure, I did not make it be the same "spfp token" all the time. On the server end there is a DB that holds all the tokens that get generated — these tokens have what draft posts they are linked to. When the server gets a request with a "spfp token" it looks through this DB to try and find a match. If one is found, all good. If there is no match found, it waits around 500ms before sending the 404 error back to the client. The wait time is introduced because if there really was no file it can be really quick, and if there is a file, due to it doing a hash, that can take longer — so it just helps people who are not meant to know this file exists from finding out if it does.

I can set the amount of time a "spfp token" is good for, and after that time the token is deleted and never seen again, allowing me to not have to keep the drafts in a different folder, as well as being able to use the same renderer so I can see what the page looks like on the main site.

Privacy-First Tracker

...may be a false statement. I can see what country you're from as well as the closest city. I can also see stuff like if you're on mobile or desktop, and what browser you're using (Chrome, Firefox, Safari, etc...). This info though is not personally identifiable. When the tracker fires I get the raw IP, browser agent, and the time of the fire. Then I put your IP through a local database called GeoLite2 — it's a database that updates about every 2 weeks and maps IP ranges to places. After running it through the database I take the browser agent and find the browser type (Chrome, Firefox, Safari, etc...), and store the country, city, and then I hash the browser agent, IP, and a secret salt that changes every year or so. This allows me to have a decent idea of returning vs new users. Using a VPN, changing browsers, or even updating your browser to the next version (or the previous version) would make the hash different and I would not know who you are the next time you loaded the site. But I think this is okay — the metrics are just there because it's cool to have an idea of what countries visit, as well as knowing whether most people read on mobile vs desktop. The mobile vs desktop is probably the most useful metric for site development, seeing what I should optimise and what not... but I digress.

Seeing all this info, and in the first 2 days having over 43 unique visits from over 12 countries, is cool! Really cool. And since they all visited when I had a bunch of test articles that AI made up, that was rather sad — I think most would have said "heck no!" and may never return. But who knows! Maybe you will come back and see this very article and decide to follow my newsletter!

And on that note!

Newsletter!

The newsletter idea came just before I was about to ship it to my Hetzner server. The idea was great: be able to send my posts directly to people's inboxes — easy, right? Well, depends on how you look at it. If you want to use an email provider whose main selling point is newsletters and blogs, then it is easy. But if you want to spend as little as possible, then it becomes harder... not much harder though, as with AI one can bang out anything in a few hours for much less money than they would have spent at a company like Substack, Mailchimp, and others.

I first tried using Zoho Mail. I wanted to be able to use my existing email provider to send emails out to a bunch of people. The problem is that Zoho does not like you sending a bunch of emails out to a bunch of people for newsletters or ads, as this ruins their IPs and makes Google trust emails that come from Zoho mail servers less. So, after trying to send myself a bunch of emails I was made aware of this by a warning email saying that newsletters and ads were not allowed and that I should use "Zoho Campaigns". I looked at it, but it was a very complicated UI, and while I can read code, if a document says go here but the button is no longer there, then I tend to be confused and just try and find another way. This new way was to use Amazon SES. It's pretty easy once you have made an account, but making an account... well, you have to pick a region, then a type of account, and then you have to sign in — or try to sign in and try and remember what you used. It's more than just an email; there are services for signing in, and which one do you pick? They all seem to accept the email, but one asks for an OTP (that you never set up), and the other asks for a root email and then more! Now this is all probably my fault — I was not great at knowing what was what on AWS when I first made my account like 4 years ago, and it's definitely not their fault that I lost the email that I signed up with. But it still feels like AWS could be simpler? I don't know.

Once I had finished setting up the IAM user, I found out that I can't add credits to my account — well, at least I don't think I can. Right now I'm just waiting for the bill, but the good thing is that the bill will probably not be seen for a few months at least, as Amazon SES is very cheap — I think like 0.05 cents per 1,000 emails, and I have hardly sent 50 total. So ya, Amazon SES is what I use. The side of my site program that deals with that uses 2 parts: the main site part, which calls a simple program that just deals with the communication with Amazon SES — it does not hold emails or text, it just fires emails out with whatever the main program tells it to. I made sure to store the emails in my DB encrypted, only decrypted on the fly by the main program and passed on to the other program. It's a cool system — it verifies a subscription by sending a verification email with a URL and a subscribe token that lasts for 30 minutes. When the verify URL is reached it will set the verified field to true. If the email is not verified within 30 minutes then the email and all its fields are deleted from the database — this is not only "why do I keep your email when I don't use it", but also so that if you want to try subscribing again, I don't need to implement code to do that.

It already kinda does via just dropping any emails that are already on the list and verified, and if they're not verified and on the list then you either have an email in your inbox where the sub link is no longer working, or it's still valid.

What's Next?

Well, part 2 of BAB, will be about the writing and post editing system, which as I got into the project is becoming the hardest part of the whole thing. From project systems, integrating the draft preview and email sub overview into it, I also have stuff like how should I display the tracking info, what does the projects workspace need — I think I want to have resources, but since my Hetzner server is limited on storage I would want a shared resource pool, so that some projects that have a few of the same files just use the stuff from each other instead of making multiple copies for each project. I also want to add a versioning system and an auto backup, meaning that I will need to find out the best balance of when to save or force save, using ideas like debouncing where you wait for 2 seconds to see if a person is still typing before saving the file. And this is a larger problem than even the tech savvy may think, because the post manager program runs on a different machine and uses SSH and rsync only to get the files from the server and send them back — so I can't save on every keystroke or the data would be something awful. And then I wanted to integrate AI — I would love to be able to have the post manager thing read all my past posts and then, when I need a rewrite of a phrase or block of text, it knows the style I write in and can give me something better and more useful for the content.

This blog will never be written with AI. It may be edited slightly, but that's only because I can't remember all the proper punctuation or Markdown formatting, and we all know that even if it's just for Markdown formatting, AI has a hard time keeping its attention on just the formatting bits and must touch the text as well.

Anyway, this is me, and me is out!