Files
autocal/jobs/jobs.go
2026-03-05 19:06:17 -05:00

120 lines
3.2 KiB
Go

package jobs
import (
"autocal/pkg/autocal"
"autocal/services"
"strings"
"time"
"github.com/charmbracelet/log"
"google.golang.org/api/calendar/v3"
)
// Start jobs
func Start(calSrv *calendar.Service, config *autocal.Autocal) {
// Setup time
t := time.Now().Format(time.RFC3339)
// Create events channel
events := make(chan *calendar.Event)
// Start event watcher
go func() {
checkForNewEvents(calSrv, config, t, events)
}()
// Wait for jobs
for event := range events {
// Loop through rules in config
for _, rule := range config.Events {
// Check if the event name matches the rule
// either by exact name or by keyword
isMatch := (rule.ExactName && event.Summary == rule.Name) || (!rule.ExactName && strings.Contains(event.Summary, rule.Name))
if isMatch {
if config.Notifications.Logging {
log.Info("Found matching event", "event", event.Summary, "rule", rule.Name)
}
// Add participants to the event
go func(e *calendar.Event) {
err := addParticipantsToEvent(calSrv, e, &config.Notifications, rule.Participants)
if err != nil {
log.Error("Failed to add participants", "err", err)
}
}(event)
// Once a rule matches, we can stop checking other rules for this event
break
}
}
}
}
func addParticipantsToEvent(calSrv *calendar.Service, event *calendar.Event, notifications *autocal.Notifications, participants []string) error {
// Create a map of existing attendees for quick lookup
existingAttendees := make(map[string]bool)
for _, attendee := range event.Attendees {
existingAttendees[attendee.Email] = true
}
// Flag to check if we need to update the event
shouldUpdate := false
// Add new participants if they are not already in the event
for _, participant := range participants {
if !existingAttendees[participant] {
event.Attendees = append(event.Attendees, &calendar.EventAttendee{ Email: participant })
shouldUpdate = true
if notifications.Logging {
log.Info("Adding new participant", "event", event.Summary, "participant", participant)
}
}
}
// If we've added new attendees, update the event in Google Calendar
if shouldUpdate {
_, err := calSrv.Events.Update("primary", event.Id, event).Do()
if err != nil {
return err
}
if notifications.Logging {
log.Info("Successfully updated event", "event", event.Summary)
}
}
return nil
}
// Checks periodically for new events
func checkForNewEvents(calSrv *calendar.Service, config *autocal.Autocal, t string, eventsCh chan *calendar.Event) {
// Create ticker
interval := time.Duration(config.Interval) * time.Minute
ticker := time.NewTicker(interval)
defer ticker.Stop()
// Start loop
for {
// Get events
log.Info("Checking for new events")
events, err := services.ListEvents(calSrv, "primary", false, true, t, 10, "startTime")
if err != nil {
log.Fatal("Failed to fetch events", "err", err)
}
// Send events
if len(events.Items) > 0 {
for _, event := range events.Items {
eventsCh <- event
}
// Update the time to the last event checked to avoid processing the same events again
t = events.Items[len(events.Items)-1].Created
}
// Wait for next tick
<-ticker.C
}
}