Nice Tips Bot

Tips from a nice robot

Features

  • Tiny web scraper
  • Cloud database
  • Tip validation

Tech Stack

  • SvelteKit
  • Fauna
  • Vercel

Overview

Nice Tips Bot was once a Twitter bot back in the time I ran Twitter bots. The conceit is simple: grab a random tip from the community how-to website wikiHow, put a little friendly phrasing around it, and serve it as advice. The bot ceased posting in 2016, but I missed it, so I made it into a website.

Generating tips

On the server side, I use the special wikiHow Randomizer link to pull a random how-to article from wikiHow. After making sure that the article contains either tips or warnings, I select a random tip or warning from the article and slot it into a template. I return the templated tip text, the URL for the wikiHow article, and a hash generated from the templated tip and URL.

Saving tips

Sometimes it’s fun to generate ephemeral tips; other times, it’s nice to be able to share a tip that is especially silly or significant! I didn’t want to save every tip by default, but I did want to provide the option to save tips if they felt worth sharing or coming back to — a kind of content curation by the site’s visitors.

However, if I’m going to allow anybody at all to save a tip, then I need to ensure the tip is genuinely from the robot. Otherwise, a mischievous actor could submit any old text and URL, and transform Nice Tips into Bad Spam! This is where hashing the wikiHow URL and tip text comes in. I created a POST route that receives the tip text, URL, and hash. Every request is verified by ensuring the server’s hash of the submitted text and URL matches the submitted hash as a safety check to ensure the tip was indeed generated on the server.

Caching

Once a tip is created and stored in the database, it’s immutable — it’s not going to be edited or changed. What this means is that rather than querying the database every time a tip is accessed (slow, expensive), individual tips can be stored in a shared public cache and served from a CDN (fast, cheap!). By setting the s-maxage cache control directive in our server response, I am able to direct my hosting provider Vercel to cache these responses in their Edge Network for several days. This not only cuts down on redundant cloud database queries, but enables the cached response to be served to the client from the closest location for even faster performance.

Although speed and scaling are not major concerns for this particular application, I was happy to learn more about best practices when it comes to caching. I’m a lot more aware of why caching to a CDN can be valuable, and more confident in my ability to spot those scenarios and set the Cache-Control directives appropriately.

Takeaways

This project was an experiment in taking something I had made in one medium (Twitter bot) and translating it over to another medium (website). When Nice Tips Bot lived on Twitter, it was as simple as generating the text and shooting it off to the API on mentions and timed intervals. As a website, though, I had to consider storage and presentation of these tips — that is, both backend and frontend concerns. The backend gave me an opportunity to try out one of the many database-as-a-service products I’d heard about, and the simplicity of the content afforded a holistic focus on the design aspect of the frontend.

During this project, I made decisions which were ultimately in some way arbitrary, and I am still not sure if they were the “best” decisions. At the same time, though, I took deliberate care with the details of realizing these decisions, and I would like to think that this attention to craft shows on Nice Tips. There is still something mysterious to me about how it came together; I still visit it and feel comforted by the harmony of the layout and design. If nothing else, this project was a meaningful exercise for my intuition in the context of building beautiful websites. After many years of being out of touch with that sense, I am grateful to feel it again.