sox/cmd_timer.go
Waldo 38635243f7 Add timer command with .env support
Adds a `timer` command that immediately confirms the timer and posts a
notification back to Campfire when it fires, using CAMPFIRE_URL and
CAMPFIRE_TOKEN. Adds godotenv so the bot loads a .env file automatically
on startup. Includes a .env.example documenting all env vars.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-07 07:10:36 -07:00

62 lines
1.6 KiB
Go

package main
import (
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
"time"
)
type TimerPlugin struct{}
func (p TimerPlugin) Name() string { return "timer" }
func (p TimerPlugin) ShortHelp() string { return "set a timer" }
func (p TimerPlugin) DetailedHelp() string {
return "Usage: timer <duration>\nSets a timer. When it goes off, posts a message to the room.\nExamples: timer 5m, timer 1h30m, timer 90s"
}
func (p TimerPlugin) Execute(msg BotMessage, args string) string {
d, err := time.ParseDuration(strings.TrimSpace(args))
if err != nil || d <= 0 {
return "Usage: timer &lt;duration&gt; (e.g. timer 5m, timer 1h30m)"
}
if os.Getenv("CAMPFIRE_URL") == "" || os.Getenv("CAMPFIRE_TOKEN") == "" {
return "Cannot set timer: CAMPFIRE_URL and CAMPFIRE_TOKEN must be configured."
}
firesAt := time.Now().Add(d)
go func() {
time.Sleep(d)
sendTimerNotification(msg, d)
}()
return fmt.Sprintf("Timer set for %s. Will go off at %s.", d, firesAt.Format("15:04:05"))
}
func sendTimerNotification(msg BotMessage, d time.Duration) {
baseURL := os.Getenv("CAMPFIRE_URL")
token := os.Getenv("CAMPFIRE_TOKEN")
if baseURL == "" || token == "" {
log.Println("timer: CAMPFIRE_URL or CAMPFIRE_TOKEN not set, cannot send notification")
return
}
url := fmt.Sprintf("%s/rooms/%d/%s/messages", baseURL, msg.Room.ID, token)
body := fmt.Sprintf("%s your %s timer is done!", msg.User.Name, d)
resp, err := http.Post(url, "text/plain", strings.NewReader(body))
if err != nil {
log.Printf("timer: failed to send notification: %v", err)
return
}
defer resp.Body.Close()
io.Copy(io.Discard, resp.Body)
}