view calsync/notificationrouter/notificationrouter.go @ 66:629d9ad289fe

doc & refactor
author drewp@bigasterisk.com
date Fri, 06 Sep 2024 17:26:11 -0700
parents 8aee4f5c4bdd
children
line wrap: on
line source

package notificationrouter

// Holds the map of (random) watchIds and the sync functions for the affected
// calendars. When google sends a notification, this object calls the right
// sync.

import (
	"log"
	"net/http"
	"time"

	"github.com/dchest/uniuri"
)

type SyncFunc func()

type NotificationRouter struct {
	handlers map[string]SyncFunc
}

func New() *NotificationRouter {
	return &NotificationRouter{
		handlers: make(map[string]SyncFunc),
	}
}

func (nr *NotificationRouter) AddHandler(watchId string, handler SyncFunc, lifetime time.Duration) {
	nr.handlers[watchId] = handler
	go func() {
		time.Sleep(lifetime)
		delete(nr.handlers, watchId)
	}()
}

func (nr *NotificationRouter) NotificationHandler(w http.ResponseWriter, r *http.Request) {
	watchId := r.Header.Get("X-Goog-Channel-ID")
	if nr.handlers[watchId] == nil {
		log.Println("incoming notification for unknown watch id", watchId, "(ignoring)")
		return
	}
	// todo: The first notification on a given watchId is the confirmation,
	// and the sync func is probably (surely?) not needed.
	log.Println("incoming notification for known watch id", watchId)
	nr.handlers[watchId]()
}

func NewWatchId() string {
	return uniuri.New() + "_" + time.Now().Format("15_04_05")
}