Help: fall back to a private message in the channel when DMs fail #33

Merged
FernandoJVideira merged 3 commits from fix/help-dms-off into dev 2026-10-23 11:05:20 +00:00
Showing only changes of commit 5bc2da4ad8 - Show all commits
+21 -2
View File
@@ -1,6 +1,7 @@
package help package help
import ( import (
"fmt"
"log" "log"
"unicode/utf8" "unicode/utf8"
@@ -139,8 +140,8 @@ func HelpHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
// when "no mutual guilds" appears for someone who is in a server with // when "no mutual guilds" appears for someone who is in a server with
// the bot: a command run through a user install, or in a server the bot // the bot: a command run through a user install, or in a server the bot
// isn't actually a member of, has no shared server for Discord to see. // isn't actually a member of, has no shared server for Discord to see.
log.Printf("help: DM not possible, showing it here (guild %q, context %d, installs %v): %v", log.Printf("help: DM not possible, showing it here (guild %q, context %d, installs %v, %s): %v",
i.GuildID, i.Context, i.AuthorizingIntegrationOwners, err) i.GuildID, i.Context, i.AuthorizingIntegrationOwners, botMembership(s, i.GuildID), err)
note := "I couldn't DM you (your DMs may be off), so here it is." note := "I couldn't DM you (your DMs may be off), so here it is."
_, _ = s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{Content: &note, Embeds: &list}) _, _ = s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{Content: &note, Embeds: &list})
return return
@@ -161,3 +162,21 @@ func sendByDM(s *discordgo.Session, userID string, list []*discordgo.MessageEmbe
} }
return nil return nil
} }
// botMembership says whether the bot is really a member of the server, which
// is what Discord means by "mutual guilds". A server where the app was added
// with only the applications.commands scope runs slash commands fine but has
// no bot user in it.
func botMembership(s *discordgo.Session, guildID string) string {
if s == nil || s.State == nil || s.State.User == nil {
return "bot user unknown"
}
inCache := false
if g, err := s.State.Guild(guildID); err == nil && g != nil {
inCache = true
}
if _, err := s.GuildMember(guildID, s.State.User.ID); err != nil {
return fmt.Sprintf("bot is NOT a member of that server (in gateway cache: %v): %v", inCache, err)
}
return fmt.Sprintf("bot is a member of that server (in gateway cache: %v)", inCache)
}