package main import ( "context" "flag" "fmt" "log" "os" "maunium.net/go/mautrix/appservice" "maunium.net/go/mautrix/event" ) func main() { configPath := flag.String("config", "config.yaml", "Path to configuration file") dbPath := flag.String("database", "ntfy-bridge.db", "Path to SQLite database file") flag.Parse() cfg, err := LoadConfig(*configPath) if err != nil { log.Fatalf("Failed to load config: %v", err) } db, err := NewDatabase(*dbPath) if err != nil { log.Fatalf("Failed to open database: %v", err) } defer db.Close() reg := &appservice.Registration{ ID: cfg.Appservice.ID, AppToken: cfg.Appservice.ASToken, ServerToken: cfg.Appservice.HSToken, SenderLocalpart: cfg.Appservice.BotLocalpart, } as, err := appservice.CreateFull(appservice.CreateOpts{ Registration: reg, HomeserverDomain: cfg.Homeserver.Domain, HomeserverURL: cfg.Homeserver.URL, HostConfig: appservice.HostConfig{Hostname: cfg.Appservice.Address, Port: cfg.Appservice.Port}, }) if err != nil { log.Fatalf("Failed to create appservice: %v", err) } ghostPrefix := fmt.Sprintf("@%s_", cfg.Appservice.BotLocalpart) handler := &MatrixHandler{ AS: as, DB: db, Ntfy: NewNtfyClient(cfg.Bridge.NtfyURL), Config: &cfg.Bridge, HSDomain: cfg.Homeserver.Domain, GhostPrefix: ghostPrefix, } ep := appservice.NewEventProcessor(as) ep.On(event.EventMessage, handler.HandleEvent) ep.On(event.StateMember, handler.HandleEvent) bridges, err := db.GetAllBridges() if err != nil { log.Fatalf("Failed to load bridges: %v", err) } botIntent := as.BotIntent() for topic, roomID := range bridges { log.Printf("[startup] Re-establishing ntfy listener for topic %q -> room %s", topic, roomID) handler.Ntfy.StartNtfyListener(topic, roomID, botIntent, as.BotMXID()) } ctx, cancel := context.WithCancel(context.Background()) defer cancel() ep.Start(ctx) log.Printf("[main] Starting appservice on %s:%d", cfg.Appservice.Address, cfg.Appservice.Port) log.Printf("[main] ntfy base URL: %s", cfg.Bridge.NtfyURL) log.Printf("[main] Loaded %d existing bridge(s)", len(bridges)) as.Start() _ = os.Stdout }