Is this craft? - A Link Shortener Website and Making Scrunchies
Every once in a while, I find an unexplainable desire to make/create something. Usually I don’t act on it but sometimes when a random idea or a video I see takes root then it just has to happen. I watched the below and I just had to try, watch it and see how crazy making a scrunchie is! I am pretty sure Grigori Perelman would have solved the Poincaré conjecture sooner if he had seen how a Scruchie is made :P
Many months before that I had seen that Oracle has a free tier cloud plan where they give 2 micro vms for free. Half a vcpu and 1gb of ram. Really wanted to take one and do something on it.
dns.toys was a good start because it was written in GO and therefore could run with low resources. Once I finished the IFSC bit, I started to wonder if a simple flask app would work. I basically wanted to build a bare bones version of bitly.
I went ahead and purchased 5ht.in, gave up oddsock.in (My plan to create and sell non-matching socks in odd quantities 😂 — I had to give up oddsock because for some reason individual people can only hold onto 2 .in domains at a time)
I knew docker would be overkill for a VM with 1gb so decided to try running a python script natively. And it worked, worked quite well actually. Initially I did not use Traefik and the VM was exposed directly on the web which turned out to be quite problematic. Why? For context you can read this blog post on fly.io which has a lot of information on companies owning blocks of IPs.
The issue now is that bad actors have a ready list of IPs that cloud providers own. So they have bots in the hundreds, continuously pining these IP address blocks. If they find any that are active then the bot goes into overdrive trying all the most common vulnerabilities - random php & wordpress files/ directories, various traversal and shell activation attempts. I was frankly overwhelmed looking at long access logs for a website I had not even advertised yet. Thankfully none of those exploits worked but now I had to make changes, did what most people do
- Put cloudflare in front
- Put Traefik in front of Flask for TLS and basic filtering
- Added code in Flask to rate limit, flag and block problematic IPs
- This is funny - Change all 403 responses to 500 (LOL! This actually helped, the bots tend to ignore these because they cant really take over an app that doesn’t work to begin with)
I still see IPs being added to the blocklist but I can rest assured knowing its much safer than before. Cloudflare free has some basic analytics and most of these bots originate in Singapore, Russia and France.
Actually I think the Elixir-Phoenix rabbit hole (Before I found out about the Oracle free tier) lead me to fly.io where I learnt that fast booting micro vms can be used to run services, you don’t always need large VMs or Kubernetes to run stuff. Anyway before I diverge again…
So I created the flask app using Claude and added basic APIs to create short links. In hind sight I should have just used SQLite, but at that time I thought no need for fancy databases, I will just run it off of jsons, and it is still running on jsons!
After that was Coldplay time here and I thought, why not now try to make a Linktree like feature, the base link will still be the same short link but when python recognizes this is a custom page, it will render a html template instead of forwarding to an external page. Here is the scrunchie page for example. This was fun to build too, Claude helped a lot and I was able to make it fully customizable. There is a config json that you can edit to add sections, links, link icons, styling themes and more!
Now comes the scrunchies, I saw the above video, ordered some elastic (the wrong elastic… more in a bit) and got out my sewing machine, a nice purple cloth and started sewing. The first few were tricky, the thread kept getting cut etc. Basically all the problems someone who does’nt know how to properly use a sewing machine faces…
Once I got a hang of it, it was very calming to do. Almost meditative so I just continued and used up the full cloth, must have made about 15. After I was done, obviously not having a use for so many, I decided to give them away at the office. This is when I got the idea to make a feedback form. Quickly made a simple feedback endpoint with a feedback_id query param. Added a json to configure the feedback list and put the scrunchies in the office with a QR for the feedback.
All the scrunchies were claimed and I was surprised! So later in the evening opened my feedback_received json and realized I messed up spectacularly. Remember the elastic, it was too tight and rigid. Me a person without long hair and having never used a scrunchie had no idea on how t was supposed to behave. Turned out that it was close to unusable, it only looked good :')
Anyway now that it was an easy fix, I really wanted to spend more time trying to perfect it. My mind anyway liked it when I was occupied with it so ordered a few more cloth pieces and made a few more versions.
The feedback for the second one was much better but working with Satin is quite hard. Hard to cut, hard to stitch and seemed fragile. So my recent experiments with soft cotton and cotton blends seem promising but I’m ye to give it away at the office. Will write about it once I receive feedback.
Finally a few people told me that these are costly, why am I just giving it away. I said it just feels nice to make and I am doing it as a hobby and not really to make some income. Yes it can get expensive online but the bill of materials for a single scrunchie is only about 14~18₹
But that gave me my next Idea, make a payment collection page. Whoever interested could pay. Then I whipped up a simple payment page and in the template, added differentiation between a desktop and mobile page.
The intention was that mobile users would first see a pay now button that leveraged UPI Intent to pay via any UPI app on the phone and desktop users would just see a UPI QR to pay.
Only after building the intent mechanism did I realize that it no longer works. Something to do with preventing payment fraud. It needed a sign parameter which was just a hash created from the full uri. Problem is we individual citizens cannot sign it because NPCI / the banks must have the private key to verify the hash with and there is no way for us to submit one to them. So only payment aggregators can now do intent payments. The funny part is the EXACT same intent URI if made into a QR Code works flawlessly.
Anyway eventually I caved and removed the intent option. Added UPI QR to both the Mobile and Web versions, even though a mobile user can’t really use the QR in a straight forward way. On iPhones I think one can long press a QR and if its UPI can automatically be opened in a UPI app? I am not sure. On Android if an supports it, you can just long press and share and in the share menu choose the app. None are user friendly or nice. So as a final resort I signed up for Razorpay and added their payment button. They take a small cut but that’s by far the cleanest way to do this for now.