120 lines
3.2 KiB
Go
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
|
|
}
|
|
}
|