Some tiny personal programs I've written
Tags: programming, javascript, go, automation
Published: 2022-03-22 09:14:12

---
canonical_url: https://david.coffee/some-tiny-programs-i-ve-written
---

_Mirrored from my blog - https://david.coffee/some-tiny-programs-i-ve-written_

There was this post on HN the other day titled [Some tiny personal programs I've written](https://jvns.ca/blog/2022/03/08/tiny-programs/) that I enjoyed a lot. It resonated with me so much because I've been pumping out smaller programs left and right for a while as well, but never thought of sharing those with the public, so let's change that. 

I love hacking on mini projects. Fixing a problem with programming feels like a superpower - I can do something that other people that can't program can't do, and every time I find a situation where I can apply my skills to an issue, I feel happy. 

Here are some programs I've written in the past few months, in no specific order:

## a covid bot

Every day when there were new cases published, people posted Twitter links, links to news and other sources. Turns out Tokyo has an [official dashboard](https://stopcovid19.metro.tokyo.lg.jp/) that pulls data out of a GitHub repository and is updated daily. 

About an hour after discovering those json files, we had a slackbot that posts updates once daily - nice!

<img src="https://david.coffee/_Files/assets/Some tiny programs I've written/coronachan.png" alt="The COVID bot in action" style="zoom:50%;" />

## apartment finder LINE bot

This one I'm especially proud of because I was able to get my current place thanks to it. 

In Tokyo there are 2 'companies' that are owned by the government, and rent out pretty decent places for an ok price, without hidden costs, minimun contract runtime, cancellation fee, and so on. Only problem - these place are gone *fast*. Like in minutes after something is posted, it's gone. 

People don't even bother visiting these places, they just put in an application right away, then visit them and cancel accordingly. 

At first I was checking the page every couple hours once, but that was too inefficient, so I hacked together a bot that's using [puppeteer](https://github.com/puppeteer/puppeteer) to check for new place, and send me a message on LINE whenever something new is available. A couple weeks later and my dream place free'd up!

<img src="https://david.coffee/_Files/assets/Some tiny programs I've written/apatochan.jpeg" alt="Apartment bot in action" style="zoom: 33%;" />

## Fastmail masked aliases through the cli

I wrote a [separate blogpost](https://david.coffee/creating-fastmail-masked-emails-without-1password-anytime-and-everywhere) about this one so I'll skip the details, but when Fastmail + 1Password released their 'masked email' (domain specific email addresses) implementation I was stoked because I was doing something like this for a long long time. I wanted to migrate to this new feature, but it wasn't available to the public yet, and only usable through 1Password. 

A put a couple hours in to reverse-engineer the fastmail JMAP API with proxyman and hacked together a Golang client that was able to create identical requests. Now I have masked emails everywhere I want by just hammering '@@@' into a dialogue. 

![Fastmail masked emails through Keyboard Maestro](https://blotcdn.com/blog_f1c3613082cc4491b8eddec3b73ef2fe/_image_cache/3f698dde-7569-4a97-af6a-95825955d3e8.gif)

## work-hour tracking through the cli 

At work we use this tool called [King of Time](https://www.kingoftime.jp/) to track working hours. It's usable through the web app but doing bulk edits was very tedious. I wanted to be able to hook checkins/checkouts to different events and actions, and the lack of an official API made this difficult. 

[puppeteer](https://github.com/puppeteer/puppeteer) to the rescue (it involved way too much javascript to be usable without headless browser), and tadaa - a npm-installable company internal tool to interact with King of Time was born.

<img src="https://david.coffee/_Files/assets/Some tiny programs I've written/kot-cli.png" alt="The time-tracking CLI" style="zoom:50%;" />

## auto-importing Japanese words into my study app

When I was learning Japanese more actively I often encountered words I didn't know, as you usually do. I looked those up in a dictionary, and then usually added them to my flashcard app (Anki). 

This became repetitive fast, so I did what engineers do and hacked together a [chrome extension](https://github.com/dvcrn/ankimo) that does it for me. Bonus points for writing it in ClojureScript which I wanted to get better with at that time. 

![ankimo](https://github.com/dvcrn/ankimo/raw/master/screenshots/tangorin.gif)

## auto-compound crypto

This one is the definition of a micro-program. FTX is able to lend away unused crypto and gives interest back. I wanted this interest to be auto-compounded every hour without me having to open the site all the time and click some buttons. 

Luckily FTX has an API to do just that, so hooking it up to a script that runs in cron, and we have automatic compounding :) 

## HomeKit-ifying my TV and aircon

[homebridge](https://homebridge.io/) is an amazing piece of software. It allows to integrate basically anything that has an API into Apples HomeKit, which is what I use at home. 

Problem: Neither my Air-Conditioner, nor my TV are HomeKit-compatible. The TV is from a time way before HomeKit was even a thing (running 'netcast'), and my Air-Conditioner is only using through Sharps proprietory 'Cocoro Cloud'.

2 homebridge plugins got created during longer caffeinated sessions, and now I can automate both purely in HomeKit: 

- https://github.com/dvcrn/homebridge-netcast-tv

- https://github.com/dvcrn/homebridge-sharp-cocoro

## netatmo temperature getter

I use a netatmo weather station at home and wanted to get it's temperature to integrate into HomeKit, so I can always see what the current temperature is, but also automate things like my AirCon or fans. This is another micro-script that just pulls the stations from my account and stores it in a text file (`/tmp/temperature`), running in a CRON

```go
for _, station := range dc.Stations() {
        for _, module := range station.Modules() {
            if module.ID == homeModuleID {
                fmt.Println("Found home module")
                homeModule = module
                break
            }
        }
    }

    temperature := fmt.Sprintf("%.1f", *homeModule.DashboardData.Temperature)
    fmt.Printf("Current temperature at home: %v \n", temperature)
    ioutil.WriteFile("/tmp/temperature", []byte(temperature), 0644)
```

## ... and lots more!

It's nice to just hack on things in between professional tasks and work. Low commitment, easy to explore new technology and usually makes something in my day-to-day life a bit easier.