I've recently been playing around with Go and I created a very basic pomodoro timer that would run from the command line. I wanted to create an alert that would inform me when I could take a break, or get back to work. I settled for an unconventional approach, but in this article I'll highlight a few different options that you have at your disposal.
I'll take you through creating a simple pomodoro timer, explaining my decisions along the way.
This is the option I went for as it would work for me, and I could set the message to whatever I liked and it would speak to me. It's not the best solution as it has to be run on a Mac and it's not exactly professional. It's pretty easy though:
exec.Command("say", "This is the message to be spoken").Output()
Beeep is a cross-platform library for sending desktop notifications, alerts and beeps.
You can send a single beep and specify the frequency of the noise and the duration.
beeep.Beep(beeep.DefaultFreq, beeep.DefaultDuration)
Each platform will have a different DefaultFreq and DefaultDuration. Changing these values doesn't change anything on a mac however.
You can also send a silent notification like this:
beeep.Notify("Title of notification", "Body of notification", "path/to/icon/asset")
Or an alert like this:
beeep.Alert(“Title of alert”, “Body of alert”, “path/to/icon/asset”)
For my purposes, the Alert works best as it makes a noise as well as displaying the notification.
I still prefer the “say” api talking to me and telling me to “take a break”. There's something nice about having someone say that to you instead of a machine beeping at you. I'd like it to work on other platforms as well though, so I'm going to implement a check for which operating system the user is on.
Checking for the OS in Go is as easy as runtime.GOOS
.
os := runtime.GOOS
if os == "darwin" {
go exec.Command("say", message).Output()
}
beeep.Notify(message, message, "assets/information.png")
You'll notice that we've used the go
keyword before executing the say
command. This keyword tells go to start a goroutine. You can think of this as a separate lightweight thread. For the purposes of our example it's simpler to think about if we didn't have the go
keyword.
Without the go
keyword the program would wait until the entire message is read out before it would show the notification. The go
keyword tells the program not to wait, and the Notify
command is able to slip in and be executed while the message is being read out. I'll go into more depth about concurrency and parallelism in a future article since it's outside the scope of this article.
If you're following along with the pomodoro series, you can see the code at this point on GitHub
Previous item in series:
I'll take you through creating a simple pomodoro timer, explaining my decisions along the way.
Next item in series:
Learn some Time functions in Go while continuing to build our pomodoro timer
Self taught software developer with 12 years experience excelling at JavaScript/Typescript, React, Node and AWS.
I love learning and teaching and have mentored several junior developers over my career. I find teaching is one of the best ways to solidify your own learning, so in the past few years I've been maintaining a technical blog where I write about some things that I've been learning.
I'm passionate about building a teams culture and processes to make it efficient and satisfying to work in. In many roles I have improved the quality and reliability of the code base by introducing or improving the continuous integration pipeline to include quality gates.