toast

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 4, 2026 License: MIT Imports: 2 Imported by: 0

README

Toast

English | 简体中文

Toast is a small Go library for sending desktop notifications from native applications and lightweight tools. It supports macOS, Windows, and JavaScript WASM, with helper utilities for Windows toast click-to-focus workflows.

Features

  • Simple toast.Push API with functional options
  • macOS notifications through osascript or Objective-C
  • Windows toast notifications through Windows Runtime APIs
  • Windows protocol activation for clickable toast actions
  • Optional Windows focus helper for bringing the originating terminal or app to front
  • JavaScript/WASM notification support for browser environments

Install

go get github.com/hellolib/toast

Quick Start

package main

import "github.com/hellolib/toast"

func main() {
    _ = toast.Push("Build finished", toast.WithTitle("Agent Notify"))
}

Platform Examples

macOS
package main

import "github.com/hellolib/toast"

func main() {
    _ = toast.Push("Permission required",
        toast.WithTitle("Agent Notify"),
        toast.WithSubtitle("15:04:05"),
        toast.WithAudio(toast.Submarine),
    )
}

For Objective-C delivery:

_ = toast.Push("Task completed",
    toast.WithTitle("Agent Notify"),
    toast.WithObjectiveC(),
)
Windows
package main

import "github.com/hellolib/toast"

func main() {
    _ = toast.Push("Task completed",
        toast.WithAppID("agent-notify"),
        toast.WithTitle("Agent Notify"),
        toast.WithAudio(toast.Default),
        toast.WithLongDuration(),
    )
}

To add an image:

_ = toast.Push("Task completed",
    toast.WithTitle("Agent Notify"),
    toast.WithIcon(`C:\path\to\icon.png`),
)
JavaScript / WASM
package main

import (
    "fmt"

    "github.com/hellolib/toast"
)

func main() {
    _ = toast.Push("Saved",
        toast.WithTitle("WASM App"),
        toast.WithOnClick(func(event interface{}) {
            fmt.Println("clicked")
        }),
        toast.WithOnClose(func() {
            fmt.Println("closed")
        }),
    )
}

Windows Click-To-Focus

Windows toast clicks are delivered through activation. For ordinary Go command line tools, the practical approach is:

  1. Ship a small GUI-subsystem helper executable.
  2. Register a custom URL protocol that launches the helper.
  3. Send the toast with WithActivationType("protocol").
  4. Pass the protocol URI through WithActivationArguments.

This repository provides both the library API and a helper command for that flow. The helper is a separate executable so toast clicks do not flash a console window.

Library Usage
package main

import (
    "fmt"
    "os"

    "github.com/hellolib/toast"
)

func main() {
    focus, err := toast.PrepareFocusActivation(
        os.Getppid(),
        `C:\path\to\toast-focus-helper.exe`,
    )
    if err != nil {
        panic(err)
    }

    _ = toast.Push("Click to focus the current terminal",
        toast.WithAppID("agent-notify"),
        toast.WithTitle("Agent Notify"),
        toast.WithMessage(fmt.Sprintf("helper: %s", focus.Helper)),
        toast.WithActivationType("protocol"),
        toast.WithActivationArguments(focus.Arguments),
    )
}

PrepareFocusActivation checks explicit helper candidates first. If none are provided or found, it looks next to the current executable for conventional names:

  • toast-focus-helper.exe
  • toast-focus-helper-arm64.exe
  • <app>-focus-helper.exe
  • <app>-helper.exe
Demo Commands

cmd/toast-focus is a runnable demo that sends a clickable toast. It expects the helper binary to be in the same directory.

make build

Artifacts are written to dist/:

  • toast-focus.exe
  • toast-focus-helper.exe
  • toast-focus-arm64.exe
  • toast-focus-helper-arm64.exe

For applications that only need the helper binaries:

make build-helpers

Make Targets

make test                 # Run Go tests
make build                # Build all Windows demo/helper binaries
make build-helpers        # Build only Windows focus helpers
make build-windows-amd64  # Build Windows amd64 demo/helper
make build-windows-arm64  # Build Windows arm64 demo/helper
make clean                # Remove dist/

API Overview

Common options:

  • toast.Push(message, opts...)
  • toast.WithTitle(title)
  • toast.WithMessage(message)
  • toast.WithAudio(audio)

macOS options:

  • toast.WithSubtitle(subtitle)
  • toast.WithObjectiveC()

Windows options:

  • toast.WithAppID(appID)
  • toast.WithIcon(path)
  • toast.WithIconRaw(bytes)
  • toast.WithActivationType(kind)
  • toast.WithActivationArguments(uri)
  • toast.WithProtocolAction(label, uri)
  • toast.WithLongDuration()
  • toast.WithShortDuration()

Windows focus helpers:

  • toast.FindFocusHelper(candidates...)
  • toast.RegisterFocusProtocol(helperPath, protocol...)
  • toast.PrepareFocusActivation(pid, helperCandidates...)
  • toast.FocusActivationArguments(pid, protocol...)

JavaScript/WASM options:

  • toast.WithIcon(url)
  • toast.WithImage(url)
  • toast.WithRequireInteraction(true)
  • toast.WithOnClick(fn)
  • toast.WithOnShow(fn)
  • toast.WithOnClose(fn)
  • toast.WithOnError(fn)

License

MIT

Documentation

Index

Constants

View Source
const (
	// DefaultFocusProtocol is the protocol used by the bundled focus helper.
	DefaultFocusProtocol = "anfocus"
)

Variables

This section is empty.

Functions

func FindFocusHelper

func FindFocusHelper(candidates ...string) (string, error)

FindFocusHelper locates the helper executable used for toast click-to-focus. Explicit candidates are checked first, followed by conventional helper names next to the current executable.

func FocusActivationArguments

func FocusActivationArguments(pid int, protocols ...string) string

FocusActivationArguments formats the URI passed to WithActivationArguments.

func Push

func Push(message string, opts ...NotificationOption) error

func RegisterFocusProtocol

func RegisterFocusProtocol(helperPath string, protocols ...string) error

RegisterFocusProtocol registers protocol as a user-local URL protocol that launches helperPath with the clicked toast URI.

Types

type Action

type Action struct {
	Type      string
	Label     string
	Arguments string
}

Action

Defines an actionable button. See https://msdn.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-adaptive-interactive-toasts for more info.

Only protocol type action buttons are actually useful, as there's no way of receiving feedback from the user's choice. Examples of protocol type action buttons include: "bingmaps:?q=sushi" to open up Windows 10's maps app with a pre-populated search field set to "sushi".

Action{"protocol", "Open Maps", "bingmaps:?q=sushi"}

type Audio

type Audio string
const (
	Silent         Audio = "silent"
	Default        Audio = "ms-winsoundevent:Notification.Default"
	IM             Audio = "ms-winsoundevent:Notification.IM"
	Mail           Audio = "ms-winsoundevent:Notification.Mail"
	Reminder       Audio = "ms-winsoundevent:Notification.Reminder"
	SMS            Audio = "ms-winsoundevent:Notification.SMS"
	LoopingAlarm   Audio = "ms-winsoundevent:Notification.Looping.Alarm"
	LoopingAlarm2  Audio = "ms-winsoundevent:Notification.Looping.Alarm2"
	LoopingAlarm3  Audio = "ms-winsoundevent:Notification.Looping.Alarm3"
	LoopingAlarm4  Audio = "ms-winsoundevent:Notification.Looping.Alarm4"
	LoopingAlarm5  Audio = "ms-winsoundevent:Notification.Looping.Alarm5"
	LoopingAlarm6  Audio = "ms-winsoundevent:Notification.Looping.Alarm6"
	LoopingAlarm7  Audio = "ms-winsoundevent:Notification.Looping.Alarm7"
	LoopingAlarm8  Audio = "ms-winsoundevent:Notification.Looping.Alarm8"
	LoopingAlarm9  Audio = "ms-winsoundevent:Notification.Looping.Alarm9"
	LoopingAlarm10 Audio = "ms-winsoundevent:Notification.Looping.Alarm10"
	LoopingCall    Audio = "ms-winsoundevent:Notification.Looping.Call"
	LoopingCall2   Audio = "ms-winsoundevent:Notification.Looping.Call2"
	LoopingCall3   Audio = "ms-winsoundevent:Notification.Looping.Call3"
	LoopingCall4   Audio = "ms-winsoundevent:Notification.Looping.Call4"
	LoopingCall5   Audio = "ms-winsoundevent:Notification.Looping.Call5"
	LoopingCall6   Audio = "ms-winsoundevent:Notification.Looping.Call6"
	LoopingCall7   Audio = "ms-winsoundevent:Notification.Looping.Call7"
	LoopingCall8   Audio = "ms-winsoundevent:Notification.Looping.Call8"
	LoopingCall9   Audio = "ms-winsoundevent:Notification.Looping.Call9"
	LoopingCall10  Audio = "ms-winsoundevent:Notification.Looping.Call10"
)

type FocusActivation

type FocusActivation struct {
	Protocol  string
	Helper    string
	Arguments string
}

FocusActivation describes the protocol activation data used to focus the source window when a Windows toast is clicked.

func PrepareFocusActivation

func PrepareFocusActivation(pid int, helperCandidates ...string) (FocusActivation, error)

PrepareFocusActivation finds the helper, registers the default focus protocol, and returns the URI that should be passed to WithActivationArguments.

type NotificationDuration

type NotificationDuration string
const (
	Short NotificationDuration = "short"
	Long  NotificationDuration = "long"
)

type NotificationOption

type NotificationOption func(*notification)

func WithActivationArguments

func WithActivationArguments(activationArguments string) NotificationOption

WithActivationArguments

// The activation/action arguments (invoked when the user clicks the notification)

func WithActivationType

func WithActivationType(activationType string) NotificationOption

WithActivationType

The type of notification level action (like Action)

func WithAppID

func WithAppID(appID string) NotificationOption

WithAppID

The name of your app. This value shows up in Windows 10's Action Centre, so make it something readable for your users. It can contain spaces, however special characters (eg. é) are not supported.

func WithAudio

func WithAudio(audio Audio) NotificationOption

WithAudio

The audio to play when displaying the notification

func WithAudioLoop

func WithAudioLoop(b bool) NotificationOption

WithAudioLoop

Whether to loop the audio (default false)

func WithDuration

WithDuration

How long the notification should show up for (short/long)

func WithIcon

func WithIcon(pathIcon string) NotificationOption

WithIcon

An optional path to an image on the OS to display to the left of the title & message.

func WithIconRaw

func WithIconRaw(raw []byte) NotificationOption

func WithLongDuration

func WithLongDuration() NotificationOption

func WithMessage

func WithMessage(msg string) NotificationOption

WithMessage

The single/multi line message to display for the notification.

func WithProtocolAction

func WithProtocolAction(label string, arguments ...string) NotificationOption

WithProtocolAction

Defines an actionable button. See https://msdn.microsoft.com/en-us/windows/uwp/controls-and-patterns/tiles-and-notifications-adaptive-interactive-toasts for more info.

Only protocol type action buttons are actually useful, as there's no way of receiving feedback from the user's choice. Examples of protocol type action buttons include: "bingmaps:?q=sushi" to open up Windows 10's maps app with a pre-populated search field set to "sushi".

Action{"protocol", "Open Maps", "bingmaps:?q=sushi"}

func WithShortDuration

func WithShortDuration() NotificationOption

func WithTitle

func WithTitle(title string) NotificationOption

WithTitle

The main title/heading for the notification.

Directories

Path Synopsis
cmd
toast-focus command
toast-focus sends a Windows toast notification whose click action focuses the terminal window that launched this process.
toast-focus sends a Windows toast notification whose click action focuses the terminal window that launched this process.
toast-focus-helper command
toast-focus-helper is launched by the anfocus: protocol.
toast-focus-helper is launched by the anfocus: protocol.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL