diff --git a/main.go b/main.go index 6dcc2d0..188afdb 100644 --- a/main.go +++ b/main.go @@ -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{