diff --git a/.gitignore b/.gitignore index a2cebc0..cb303dd 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ go.work /email_password /birdweather_daily_email /waisbrot_config.yaml +/.vscode diff --git a/README.md b/README.md index 38cf30a..ee5bf08 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,75 @@ # birdweather_daily_email -A personal project for sending a daily summary of the birds whose calls were identified by my stations on [BirdWeather](https://app.birdweather.com). And also learning some basic Go. +I got a brace of [BirdWeather](https://app.birdweather.com) PUCs for myself and family members. Rather than checking stations regularly, I thought it'd be nice to get a daily digest email of what birds appeared: + +![example email](/img/birds-email-1.png "Example email sent by the program") + +The email goes out to all the family bird-listeners summarizing what birds were active yesterday at the different stations. I can see my parents home in the mountains trail behind my sea-level place in winter bird activity, due to colder temperatures. + +This project also serves as a vehicle for teaching myself programming in Go. That's the reason for the language selection. ## Usage +### Configuration file + +You must use a configuration file, to tell the program which stations to check, while emails to send, and how to connect to an email server. Here's an example configuration: + +```yaml +--- +email: + recipients: + - nathaniel@github.co.uk + - nate@gmail.org + sender: My BirdWeather PUC + smtp: + host: smtp.fastmail.com + port: 465 + user: me@vanity.name + pass: setecastronomy + template: "/etc/birdweather/countEmail.tmpl" +stations: + - 1985 + - 2122 +influx: + url: https://influxdb.local + token: 0KPCajYMUIg5k6RpkfW5qvJalN8xWNJYPMdIphS29JauuWgjO6tvKmTAsT-aWsC5NR5IGcDoEGJAzW6J1GuG5w== + org: 18292773589b0208 + bucket: ebc4fb5a458af26e +``` + +If you're not running an InfluxDB server (or don't want to collect metrics) just leave that section out. All other configuration elements are required. + +Consult your email provider for what you need to send email by SMTP. I thought that Fastmail's instructions were easy but others might be more difficult. + +### Running + +By default, the configuration file is expected to be at `/etc/birdweather/config.yaml`. You can override this by setting the `BIRDWEATHER_CONFIG_FILE` environment variable: + +```sh +BIRDWEATHER_CONFIG_FILE=$PWD/test.config ./birdweather_daily_email send +``` + +Note the `send` argument at the end. There's some other testing-related sub-commands, but `send` is the one to fetch data and email it. + +### Email template + +You need to provide an HTML email template file in the `email.template` configuration key. Only HTML emails are currently supported. + +I used [Stripo](https://my.stripo.email) to design the provided email template (`countEmail.tmpl`), but I'm not very good at HTML design. + +You can create your own, if you like. The template can use the following components, nested: + +* `{{ .Day }}`: The weekday-number of the day being fetched (_e.g._ Monday will replace this with "1") +* `{{ range .Stations }} ... {{ end }}`: this will iterate over each station defined in the config file + * `{{ .Name }}`: The name of the station currently being iterated over. This is whatever the station-owner named it. + * `{{ .Id }}`: The ID number of the current station + * `{{ range .Counts }} ... {{ end }}`: this goes inside the `.Stations` loop and iterates over each bird-count for a station + * `{{ .Name }}`: The common name of the bird + * `{{ .SciName }}`: The scientific name of the bird + * `{{ .ImageURL }}`: The BirdWeather-hosted URL for an image of the bird + * `{{ .ImageCredit }}`: The credit for the bird image. It's scraped data and IME is often garbled. + * `{{ .Count }}`: The number of times this bird was heard on this day + Fetch data for 3 stations and send a daily digest to two email addresses: ``` @@ -12,7 +78,17 @@ birdweather_daily_email send --email=me@example.com,friend@example.com --station Currently expects that `countEmail.tmpl` (the email template) and `email_password` -## How to update the Birdweather API +## Hacking + +### Code structure + +Cobra is used for subcommands. I could remove that since I'm not using any command-line flags. `cmd/send.go` is where the main logic lives. I tried to split functionality out by module: +* `birdweather` - talking to BirdWeather via GraphQL +* `email` - talking to mail-provider over SMTP (the file says "fastmail" but it's actually agnostic) +* `metrics` - InfluxDB stuff +* `structs` - Go `struct`s that I moved here to break dependency-cycles + +### How to update the BirdWeather API 1. In the `birdweather` directory 2. Fetch the schema: `npx gql-sdl https://app.birdweather.com/graphql --sdl -o schema.graphql` @@ -21,7 +97,3 @@ Currently expects that `countEmail.tmpl` (the email template) and `email_passwor I got some errors reported in the schema, but making the obvious-seeming fixes by hand appeared to resolve things. Genqlient depends on `schema.graphql` being the schema, `genqlient.graphql` containing the query-functions we want to be able to run, and `genqlient.yaml` being its config. - -## Updating email template - -I used [Stripo](https://my.stripo.email) to design the email template. Might be useful for redesign. diff --git a/img/birds-email-1.png b/img/birds-email-1.png new file mode 100644 index 0000000..8f5fed1 Binary files /dev/null and b/img/birds-email-1.png differ