tvl-depot/monzo_ynab
William Carroll d35eb5c8f9 Debug os.Signal handling
Problem:

When SIGINT signals we're sent to the token server, it would shut down without
completing the shutdown procedure. The shutdown procedure would persist the
application state (i.e. access and refresh tokens).

This is problematic for the following sequence of events:
t0. Access and refresh tokens retrieved from kv.json and used as app state.
t1. Tokens are refreshed but not persisted. (I'm still unsure how this
    happens). Remember that this means the previous access and refresh tokens
    from t0 are now invalid.
t2. User sends a SIGINT.
t3. Token server shuts down.
t4. Token server is restarted, kv.json is used as the app state even though its
    tokens are now invalid.
t5. Tokens are attempted to refresh, Monzo API rejects the tokens because
    they're invalid.

Now we need to provide the token server with valid access and refresh tokens
otherwise we will repeat the loop described above. This means going through the
client authorization flow again or copying and pasting the tokens logged from
the token server into kv.json. Either scenario is more manual than I'd prefer.

Solution:

Use a buffered channel to receive the os.Signal. I got this idea after reading
these docs: https://golang.org/pkg/os/signal/#Notify and I debugged this issue
shortly thereafter.

I also rearranged the order of operations in main/0 to ensure that
handleInterrupts/0, which registers the event listeners, occurs before
scheduleTokenRefresh/2 is called. This allows the token server to gracefully
shutdown even if it's in the middle of the scheduleTokenRefresh/2 call.
2020-02-10 10:06:40 +00:00
..
monzo Sketch Monzo client 2020-02-10 10:06:40 +00:00
ynab Support serde for Monzo and YNAB transaction structs 2020-02-07 21:33:08 +00:00
.envrc Support YNAB personal-access-token 2020-02-07 21:30:24 +00:00
auth.go Move authorization logic into separate package 2020-02-10 10:06:40 +00:00
job.nix Create gopkgs directory for golang libs 2020-02-10 10:06:40 +00:00
main.go Move authorization logic into separate package 2020-02-10 10:06:40 +00:00
README.md Support OAuth 2.0 login flow for Monzo API 2020-02-05 23:33:23 +00:00
requests.txt Create server for managing Monzo credentials 2020-02-10 10:06:40 +00:00
shell.nix Nixify tokens.go 2020-02-10 10:06:40 +00:00
tokens.go Debug os.Signal handling 2020-02-10 10:06:40 +00:00
tokens.nix Move authorization logic into separate package 2020-02-10 10:06:40 +00:00

monzo_ynab

Exporting Monzo transactions to my YouNeedABudget.com (i.e. YNAB) account. YNAB unfortunately doesn't currently offer an Monzo integration. As a workaround and a practical excuse to learn Go, I decided to write one myself.

This job is going to run N times per 24 hours. Monzo offers webhooks for reacting to certain types of events. I don't expect I'll need realtime data for my YNAB integration. That may change, however, so it's worth noting.

Installation

Like many other packages in this repository, monzo_ynab is packaged using Nix. To install and use, you have two options:

You can install using nix-build and then run the resulting ./result/bin/monzo_ynab.

> nix-build . && ./result/bin/monzo_ynab

Or you can install using nix-env if you'd like to create the monzo_ynab symlink.

> nix-env -f ~/briefcase/monzo_ynab -i

Deployment

While this project is currently not deployed, my plan is to host it on Google Cloud and run it as a Cloud Run application. What I don't yet know is whether or not this is feasible or a good idea. One complication that I foresee is that the OAuth 2.0 login flow requires a web browser until the access token and refresh tokens are acquired. I'm unsure how to workaround this at the moment.

For more information about the general packaging and deployment strategies I'm currently using, refer to the deployments writeup.