chore: I have no fucking idea
Build and Publish Package (amd64) / docker (push) Successful in 4m54s

This is vibecoded shit but i can't be bothered to do it myself.
Nobody else besides me is gonna be using this, and this wont ever be
extended or anything, so I just don't care.
This commit is contained in:
2026-07-25 23:07:16 +02:00
parent dee1d94ae4
commit 6756b9f179
7 changed files with 534 additions and 313 deletions
+82 -29
View File
@@ -6,24 +6,95 @@ import (
"fmt"
"log"
"os"
"regexp"
"maunium.net/go/mautrix/appservice"
"maunium.net/go/mautrix/event"
)
var (
Version = "dev"
BuildTime = "unknown"
)
func main() {
configPath := flag.String("config", "config.yaml", "Path to configuration file")
dbPath := flag.String("database", "ntfy-bridge.db", "Path to SQLite database file")
genReg := flag.Bool("g", false, "Generate registration file and exit")
regPath := flag.String("r", "registration.yaml", "Path for the registration file")
showVersion := flag.Bool("v", false, "Print version and exit")
flag.Parse()
if *showVersion {
fmt.Printf("mautrix-ntfy %s (built %s)\n", Version, BuildTime)
return
}
cfg, err := LoadConfig(*configPath)
if err != nil {
log.Fatalf("Failed to load config: %v", err)
log.Fatalf("Load config: %v", err)
}
db, err := NewDatabase(*dbPath)
if *genReg {
if err := generateRegistration(cfg, *configPath, *regPath); err != nil {
log.Fatalf("Generate registration: %v", err)
}
return
}
if err := run(cfg, *configPath, *dbPath); err != nil {
log.Fatalf("Fatal: %v", err)
}
}
func generateRegistration(cfg *Config, configPath, regPath string) error {
if cfg.Homeserver.Domain == "" || cfg.Homeserver.Domain == "example.com" {
return fmt.Errorf("set homeserver.domain in %s first", configPath)
}
if cfg.Appservice.BotLocalpart == "" {
return fmt.Errorf("set appservice.bot_localpart in %s first", configPath)
}
if cfg.Appservice.Address == "" {
return fmt.Errorf("set appservice.address in %s first", configPath)
}
reg := appservice.CreateRegistration()
reg.ID = cfg.Appservice.ID
reg.URL = cfg.Appservice.Address
reg.SenderLocalpart = cfg.Appservice.BotLocalpart
rateLimited := false
reg.RateLimited = &rateLimited
botRegex := regexp.MustCompile(fmt.Sprintf("^@%s:%s$",
regexp.QuoteMeta(cfg.Appservice.BotLocalpart),
regexp.QuoteMeta(cfg.Homeserver.Domain)))
reg.Namespaces.UserIDs.Register(botRegex, true)
ghostRegex := regexp.MustCompile(fmt.Sprintf("^@%s_[^:]*:%s$",
regexp.QuoteMeta(cfg.Appservice.BotLocalpart),
regexp.QuoteMeta(cfg.Homeserver.Domain)))
reg.Namespaces.UserIDs.Register(ghostRegex, true)
if err := reg.Save(regPath); err != nil {
return fmt.Errorf("save registration: %w", err)
}
cfg.Appservice.ASToken = reg.AppToken
cfg.Appservice.HSToken = reg.ServerToken
if err := cfg.Save(configPath); err != nil {
return fmt.Errorf("save config with tokens: %w", err)
}
fmt.Printf("Registration saved to %s\n", regPath)
fmt.Printf("Config updated at %s (tokens filled in)\n", configPath)
fmt.Println("Copy the registration file to your homeserver and restart it.")
return nil
}
func run(cfg *Config, configPath, dbPath string) error {
db, err := NewDatabase(dbPath)
if err != nil {
log.Fatalf("Failed to open database: %v", err)
return fmt.Errorf("open database: %w", err)
}
defer db.Close()
@@ -38,47 +109,29 @@ func main() {
Registration: reg,
HomeserverDomain: cfg.Homeserver.Domain,
HomeserverURL: cfg.Homeserver.URL,
HostConfig: appservice.HostConfig{Hostname: cfg.Appservice.Address, Port: cfg.Appservice.Port},
HostConfig: appservice.HostConfig{Hostname: cfg.Appservice.Address, Port: 8080},
})
if err != nil {
log.Fatalf("Failed to create appservice: %v", err)
return fmt.Errorf("create appservice: %w", 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,
}
ntfy := NewNtfyClient(cfg.Bridge.NtfyURL)
bridge := NewBridge(as, db, ntfy, cfg)
handler := NewMatrixHandler(bridge, fmt.Sprintf("@%s_", cfg.Appservice.BotLocalpart))
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)
bridge.StartExistingBridges(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))
log.Printf("mautrix-ntfy %s starting on %s:8080", Version, cfg.Appservice.Address)
as.Start()
_ = os.Stdout
return nil
}