Implement scripts running in Alfred Workflows with deanishe/awgo

golangalfredproductivity

deanishe/awgo is a library to implement scripts running in Alfred Workflows. It enables to output Script Filter JSON to pass values to the next object with NewItem(), access keychain, and check logs with MagicAction by calling wf.Args() and passing workflow:log as arguments.

The code is executed every time a character is typed by default, so it would be better to cache results of API calls, etc. as follows. There are full codes in GitHub.

package main

import (
	"flag"
	"fmt"
	aw "github.com/deanishe/awgo"
	"github.com/deanishe/awgo/keychain"
	"logging"
	"time"
)

var (
	wf     *aw.Workflow
	action string
)

const (
	cacheDir            = "./cache"
	cacheKey            = "time"
	actionSetCredential = "set-credential"
	actionLogCredential = "log-credential"
)

func init() {
	wf = aw.New()
	flag.StringVar(&action, "action", "", "action to be executed")
}

func fetchTime() (time.Time, error) {
	cache := aw.NewCache(cacheDir)
	if !cache.Expired(cacheKey, time.Second*20) {
		bytes, err := cache.Load(cacheKey)
		if err != nil {
			return time.Time{}, err
		}
		return time.Parse(time.RFC3339, string(bytes))
	}
	now := time.Now()
	cache.Store(cacheKey, []byte(now.Format(time.RFC3339)))
	return now, nil
}

func run() {
	wf.Args()
	flag.Parse()

	kc := keychain.New("test-alfred-workflow")

	if action == "" {
		wf.NewItem("Set credential").Arg(actionSetCredential, flag.Arg(0)).Valid(len(flag.Arg(0)) > 0)
		wf.NewItem("Log credential").Arg(actionLogCredential).Valid(true)

		t, err := fetchTime()
		if err != nil {
			wf.FatalError(err)
		}
		wf.NewItem(fmt.Sprintf("now: %s, cache: %s", time.Now().Format("15:04:05"), t.Format("15:04:05")))
		wf.SendFeedback()
		return
	}

	switch action {
	case actionSetCredential:
		kc.Set("test", flag.Arg(0))
	case actionLogCredential:
		cred, err := kc.Get("test")
		if err != nil {
			wf.FatalError(err)
		}
		log.Println(fmt.Sprintf("credenital: %s", cred))
	}
	wf.SendFeedback()
}

func main() {
	wf.Run(run)
}

Constructing Workflows on GUI and opening it with Finder, there is info.plist containing the settings, so a .alfredworkflow file can be created by zipping this together with the script.

build:
	go build -o test-alfred-workflow .

package: build
	zip -r test.alfredworkflow info.plist test-alfred-workflow

install: package
	open test.alfredworkflow

The keyword and the command can be set on Script Filter, and arguments passed by the previous element can be referred to like ./test-alfred-workflow -action “$1” “$2”.

References

deanishe/awgoを使って簡単にAlfred Workflowを作る - ぽよメモ