This answer for a similar question points to few options depending on which platform you need to implement this in.
I've personally used https://github.com/MarinX/keylogger.
It's well written and easy to understand. At the time, I had to write my own version of this library to listen to multiple keyboards, It was easy to adapt this code for that.
Note that this library is written for Linux only.
Example code:
import (
    "github.com/MarinX/keylogger"
    "github.com/sirupsen/logrus"
)
func main() {
    // find keyboard device, does not require a root permission
    keyboard := keylogger.FindKeyboardDevice()
    logrus.Println("Found a keyboard at", keyboard)
    // init keylogger with keyboard
    k, err := keylogger.New(keyboard)
    if err != nil {
        logrus.Error(err)
        return
    }
    defer k.Close()
    events := k.Read()
    // range of events
    for e := range events {
        switch e.Type {
        // EvKey is used to describe state changes of keyboards, buttons, or other key-like devices.
        // check the input_event.go for more events
        case keylogger.EvKey:
            // if the state of key is pressed
            if e.KeyPress() {
                logrus.Println("[event] press key ", e.KeyString())
            }
            // if the state of key is released
            if e.KeyRelease() {
                logrus.Println("[event] release key ", e.KeyString())
            }
            break
        }
    }
}