Help: show it in the channel when the DM can't be sent, and log where the command came from

Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
This commit is contained in:
FernandoJVideiraandClaude Sonnet 5.5 committed 2026-10-23 11:50:44 +01:00
1 parent 85bd89a3f6
commit 63f17365fc
4 files changed
+132 -29

No files matched your search

+55 -27
View File
@@ -185,39 +185,67 @@ func embeds(author *discordgo.MessageEmbedAuthor) []*discordgo.MessageEmbed {
return append(out, cur)
}
// HelpHandler sends the help by direct message. If that isn't possible (the
// member has DMs off, or shares no server with the bot), it shows the help to
// them in the channel instead, as a message only they can see.
func HelpHandler(s *discordgo.Session, i *discordgo.InteractionCreate) {
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{
Content: "Check your DMs for help.",
Flags: discordgo.MessageFlagsEphemeral,
},
})
userID := ""
// check if command is run in a guild
if i.Member != nil {
userID = i.Member.User.ID
} else {
userID = i.Interaction.User.ID
}
dmChannel, err := s.UserChannelCreate(userID)
if err != nil {
log.Printf("Error creating DM channel: %v", err)
return
}
author := discordgo.MessageEmbedAuthor{
Name: "Velox Bot",
URL: "https://gitea.fernandovideira.com/FernandoJVideira/velox-bot",
}
list := embeds(&author)
for _, e := range embeds(&author) {
if _, err := s.ChannelMessageSendEmbed(dmChannel.ID, e); err != nil {
log.Printf("Error sending help: %v", err)
return
// Used in a DM with the bot, there is nowhere else to send it.
if i.GuildID == "" {
_ = s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{Embeds: list},
})
return
}
// Answer first (sending the DM can take a moment), and edit the answer
// once we know where the help went.
if err := s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
Type: discordgo.InteractionResponseDeferredChannelMessageWithSource,
Data: &discordgo.InteractionResponseData{Flags: discordgo.MessageFlagsEphemeral},
}); err != nil {
log.Printf("help: cannot answer: %v", err)
return
}
userID := ""
if i.Member != nil && i.Member.User != nil {
userID = i.Member.User.ID
} else if i.User != nil {
userID = i.User.ID
}
if err := sendByDM(s, userID, list); err != nil {
// Typically "Cannot send messages to this user": DMs are off.
// The context says where the command came from, which is what to look at
// 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
// 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",
i.GuildID, i.Context, i.AuthorizingIntegrationOwners, err)
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})
return
}
done := "Check your DMs for help."
_, _ = s.InteractionResponseEdit(i.Interaction, &discordgo.WebhookEdit{Content: &done})
}
func sendByDM(s *discordgo.Session, userID string, list []*discordgo.MessageEmbed) error {
dm, err := s.UserChannelCreate(userID)
if err != nil {
return err
}
for _, e := range list {
if _, err := s.ChannelMessageSendEmbed(dm.ID, e); err != nil {
return err
}
}
return nil
}