This commit is contained in:
93
cmd/releasewatcher/main.go
Normal file
93
cmd/releasewatcher/main.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"releasewatcher/internal/auth"
|
||||
"releasewatcher/internal/discordbot"
|
||||
"releasewatcher/internal/notify"
|
||||
"releasewatcher/internal/store"
|
||||
"releasewatcher/internal/web"
|
||||
)
|
||||
|
||||
func main() {
|
||||
addr := flag.String("addr", env("RW_ADDR", ":8080"), "HTTP listen address")
|
||||
dataFile := flag.String("data", env("RW_DATA", "/data/releasewatcher.json"), "JSON data file")
|
||||
adminEmail := flag.String("admin-email", env("RW_ADMIN_EMAIL", "admin@example.local"), "initial admin email")
|
||||
adminPass := flag.String("admin-pass", env("RW_ADMIN_PASSWORD", "admin12345"), "initial admin password")
|
||||
secret := flag.String("secret", env("RW_SECRET", "change-me-in-production"), "session secret")
|
||||
discordToken := flag.String("discord-token", env("RW_DISCORD_TOKEN", ""), "Discord bot token; empty disables Discord")
|
||||
discordAppID := flag.String("discord-app-id", env("RW_DISCORD_APP_ID", ""), "Discord application ID for command registration")
|
||||
discordGuildID := flag.String("discord-guild-id", env("RW_DISCORD_GUILD_ID", ""), "Discord guild/server ID for release channels")
|
||||
discordCategoryID := flag.String("discord-category-id", env("RW_DISCORD_CATEGORY_ID", ""), "Discord category ID for software release channels; empty creates/uses category name")
|
||||
discordCategoryName := flag.String("discord-category-name", env("RW_DISCORD_CATEGORY_NAME", "ReleaseWatcher"), "Discord category name for software release channels")
|
||||
discordReleaseMention := flag.String("discord-release-mention", env("RW_DISCORD_RELEASE_MENTION", "@here"), "Mention text for release channel pings, e.g. @here or <@&ROLE_ID>; empty disables pings")
|
||||
discordSendDMs := flag.Bool("discord-send-dms", envBool("RW_DISCORD_SEND_DMS", true), "also send release notifications as DMs to subscribers")
|
||||
flag.Parse()
|
||||
|
||||
logger := slog.New(slog.NewTextHandler(os.Stdout, nil))
|
||||
st, err := store.Open(*dataFile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
if err := st.EnsureUser(store.User{Email: *adminEmail, DisplayName: "Administrator", Role: store.RoleAdmin, PasswordHash: auth.HashPassword(*adminPass)}); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
am := auth.New(*secret, st)
|
||||
var notifier notify.ReleaseNotifier = notify.LoggingNotifier{Log: logger}
|
||||
if *discordToken != "" {
|
||||
dg, err := discordbot.NewDiscordSession(*discordToken)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
discordServices := discordbot.NewServices(st, dg, logger, discordbot.Config{
|
||||
GuildID: *discordGuildID,
|
||||
CategoryID: *discordCategoryID,
|
||||
CategoryName: *discordCategoryName,
|
||||
ReleaseMention: *discordReleaseMention,
|
||||
SendDMs: *discordSendDMs,
|
||||
})
|
||||
discordbot.AttachDiscordHandlers(dg, discordServices)
|
||||
if err := dg.Open(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer dg.Close()
|
||||
if *discordAppID != "" {
|
||||
if err := discordbot.UpsertCommands(dg, *discordAppID); err != nil {
|
||||
logger.Warn("Discord commands konnten nicht registriert werden", "error", err)
|
||||
}
|
||||
} else {
|
||||
logger.Warn("RW_DISCORD_APP_ID fehlt; Slash-Commands werden nicht registriert")
|
||||
}
|
||||
notifier = discordServices
|
||||
logger.Info("Discord-Bot gestartet")
|
||||
}
|
||||
srv, err := web.New(st, am, notifier, logger)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
logger.Info("ReleaseWatcher gestartet", "addr", *addr, "admin", *adminEmail)
|
||||
log.Fatal(http.ListenAndServe(*addr, srv.Routes()))
|
||||
}
|
||||
|
||||
func env(key, fallback string) string {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
return v
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func envBool(key string, fallback bool) bool {
|
||||
switch os.Getenv(key) {
|
||||
case "1", "true", "TRUE", "yes", "YES", "on", "ON":
|
||||
return true
|
||||
case "0", "false", "FALSE", "no", "NO", "off", "OFF":
|
||||
return false
|
||||
default:
|
||||
return fallback
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user