Daily sms with github actions
Introduction
I had a daemon a while back on my raspberry pi that would send me and my girlfriend a sms in the morning. The text of the sms usually was a quote or a joke or some positive inspiration.
It was fine but recently I have been really enjoying setting up workflows using Github actions and wanted to move this to actions.
Github actions runner
This is the process that listens for and processes jobs from github.
Github actions billable minutes are favourably priced in general but what is even better is that jobs running on self hosted hardware are free.
I can run the GitHub actions runner, which is open source, and run it on my raspberry pi and all jobs on it will not count against billable minutes.
Configure a self hosted runner using the amazingly simple documentation for your repo: https://github.com/:user/:repo/settings/actions/runners/new
Each runner process can only take jobs for a single repo but you can have multiple of these processes running on the same machine.
Codebase lol: https://github.com/actions/runner/blob/be9632302ceef50bfb36ea998cea9c94c75e5d4d/src/Sdk/WebApi/WebApi/WrappedException.cs#L153
Workflow yaml
This the file that defines what the job is to do.
I want to build and run my code every morning at 8am or when I push to main and the job should run on my pi. To do that my workflow file looks something like this
1 | name: Send reminder |
Project pom
This is the file that defines how to build the app and what dependencies should be brought in.
The relevant sections of the pom are the ones that allows building the fat jar and the dependencies that were used for the project.
1 | <plugin> |
The only dependencies we will be bringing in are Unirest for Http requests and Json and Twilio SDK for sending messages.
1 | <dependency> |
Data sources
Where do the quotes and jokes come from? This is the snippet that grabs the data that will be texted.
There are 7 data sources. 4 make network calls to get the data and 3 read a local json file [part of the repo] and pick a random one.
1 | // list of function references List<()->String> |
Picking a service
Pick at random works for a lot of use cases. Pick a random number up to 7 and use that as the index - call invoke()
to actually trigger the function.
Run catching to capture exceptions and retry. It also returns a Result<T>
which has a convenient api
1 | fun getMessage(retry: Int = 0): String { |
Twilio send sms
1 | Message.creator(PhoneNumber("phone-num"), "msg-service-id", "text msg body").create() |
Performance on pi
It takes roughly 3 minutes to do the maven compile step and 12 seconds to do the run jar step. The pi spins up to 70-80% Cpu and uses 1.1GB of the 4GB of memory available.
Parting thoughts
GH actions allows for all kinds of automation. It can be used for many other workflows other than pure CI/CD pipelines. Keep it in mind when trying to deploy code. It fills a really nice niche.