Guild-Admin-Fix
All checks were successful
release-tag / release-image (push) Successful in 2m3s

This commit is contained in:
2025-08-15 10:11:34 +02:00
parent 18cd4ff9e3
commit 2ce30f02d2

74
main.go
View File

@@ -274,6 +274,24 @@ func sendDM(dg *discordgo.Session, userID, content string) error {
return err
}
func isGuildAdminOrManager(dg *discordgo.Session, i *discordgo.InteractionCreate) bool {
if i.GuildID == "" || i.Member == nil || i.Member.User == nil {
return false
}
perms, err := dg.State.UserChannelPermissions(i.Member.User.ID, i.ChannelID)
if err != nil {
// Fallback: keine Berechtigung annehmen
return false
}
if (perms & discordgo.PermissionAdministrator) != 0 {
return true
}
if (perms & discordgo.PermissionManageGuild) != 0 {
return true
}
return false
}
// onInteraction verarbeitet Slash-Commands (/subscribe, /unsubscribe)
// und den User-Kontext-Command („Zu Empfängern hinzufügen“).
func (s *Server) onInteraction(_ *discordgo.Session, i *discordgo.InteractionCreate) {
@@ -309,14 +327,17 @@ func (s *Server) onInteraction(_ *discordgo.Session, i *discordgo.InteractionCre
switch cmd.CommandType {
case discordgo.UserApplicationCommand:
// Rechtsklick auf User → Apps → Dein Command
if !isGuildAdminOrManager(s.dg, i) {
replyEphemeral(s.dg, i, "Nur Admins/Moderatoren dürfen Empfänger hinzufügen.")
return
}
targetID := cmd.TargetID
if targetID == "" {
replyEphemeral(s.dg, i, "Kein Zielbenutzer erhalten.")
return
}
// Optional: Username aus Resolved ziehen (falls mitgeliefert)
username := ""
if cmd.Resolved != nil {
if u, ok := cmd.Resolved.Users[targetID]; ok && u != nil {
@@ -343,7 +364,7 @@ func (s *Server) onInteraction(_ *discordgo.Session, i *discordgo.InteractionCre
replyEphemeral(s.dg, i, "Fehler beim Subscribe: "+err.Error())
return
}
replyEphemeral(s.dg, i, "✅ Du erhältst nun DMs. Mit `/unsubscribe` meldest du dich ab.")
replyEphemeral(s.dg, i, "✅ Du erhältst nun DMs. Mit `/unsubscribe` meldest du dich ab. Beachte bitte, das dieser Bot keine eingehenden Nachrichten verarbeitet!")
case "unsubscribe":
u := actor(i)
@@ -417,33 +438,42 @@ func userLabel(u *discordgo.User) string {
return u.Username
}
// …
func upsertCommands(s *discordgo.Session, appID string) error {
// Slash-Commands
if _, err := s.ApplicationCommandCreate(appID, "", &discordgo.ApplicationCommand{
Name: "subscribe",
Description: "Opt-in: Nachrichten per DM erhalten",
Type: discordgo.ChatApplicationCommand, // Slash
}); err != nil {
return err
}
if _, err := s.ApplicationCommandCreate(appID, "", &discordgo.ApplicationCommand{
Name: "unsubscribe",
Description: "Opt-out: Keine DMs mehr erhalten",
Type: discordgo.ChatApplicationCommand, // Slash
}); err != nil {
// Manage Guild-Recht verlangen (oder PermissionAdministrator)
perms := int64(discordgo.PermissionManageGuild)
// User-Kontext-Command nur für Admins/Mods
_, err := s.ApplicationCommandCreate(appID, "", &discordgo.ApplicationCommand{
Name: "Zu Empfängern hinzufügen",
Type: discordgo.UserApplicationCommand,
DefaultMemberPermissions: &perms,
DMPermission: ptrBool(false), // nicht in DMs
})
if err != nil {
return err
}
// User-Kontext-Command (Rechtsklick auf User)
if _, err := s.ApplicationCommandCreate(appID, "", &discordgo.ApplicationCommand{
Name: "Zu Empfängern hinzufügen",
Type: discordgo.UserApplicationCommand, // User-Context
}); err != nil {
// Beispiel: Slash-Commands ohne besondere Einschränkung
_, err = s.ApplicationCommandCreate(appID, "", &discordgo.ApplicationCommand{
Name: "subscribe",
Description: "Opt-in: Nachrichten per DM erhalten",
Type: discordgo.ChatApplicationCommand,
})
if err != nil {
return err
}
return nil
_, err = s.ApplicationCommandCreate(appID, "", &discordgo.ApplicationCommand{
Name: "unsubscribe",
Description: "Opt-out: Keine DMs mehr erhalten",
Type: discordgo.ChatApplicationCommand,
})
return err
}
func ptrBool(b bool) *bool { return &b }
func (s *Server) handleIndex(w http.ResponseWriter, r *http.Request) {
subs, _ := s.listSubs(1000)
data := map[string]any{