package events import ( "context" "log" "strconv" "strings" "velox-bot/internal/db/services" "github.com/bwmarrin/discordgo" ) // HandleGuildMemberAdd sends a configurable welcome message in a guild channel // and an optional configurable DM to the joining user. func HandleGuildMemberAdd(s *discordgo.Session, m *discordgo.GuildMemberAdd, svc *services.Services) { if s == nil || m == nil || svc == nil || svc.Welcome == nil { return } if m.User == nil { return } ctx := context.Background() guildID := mustParseInt64(m.GuildID) settings, err := svc.Welcome.GetSettings(ctx, guildID) if err != nil { log.Printf("welcome: failed to load settings for guild %s: %v", m.GuildID, err) return } if settings == nil || settings.ChannelID == 0 { // No welcome channel configured; nothing to do. return } memberMention := m.User.Mention() // Resolve guild/server name and user avatar for placeholders / visuals. guildName := "" userAvatarURL := "" if g, err := s.State.Guild(m.GuildID); err == nil && g != nil { guildName = g.Name } else if g, err := s.Guild(m.GuildID); err == nil && g != nil { guildName = g.Name } if m.User.Avatar != "" { userAvatarURL = discordgo.EndpointUserAvatar(m.User.ID, m.User.Avatar) } // Build guild welcome message. channelID := strconv.FormatInt(settings.ChannelID, 10) welcomeMsg := strings.TrimSpace(settings.WelcomeMessage) if welcomeMsg == "" { // Default message when none configured. // "! Welcome to ! Have fun!" welcomeMsg = "! Welcome to ! Have fun!" } welcomeMsg = strings.ReplaceAll(welcomeMsg, "{user}", memberMention) if guildName != "" { welcomeMsg = strings.ReplaceAll(welcomeMsg, "{server}", guildName) welcomeMsg = strings.ReplaceAll(welcomeMsg, "", guildName) } welcomeMsg = strings.ReplaceAll(welcomeMsg, "", memberMention) embed := &discordgo.MessageEmbed{ Title: "👋 Welcome!", Description: welcomeMsg, Color: 0xFFA500, Footer: &discordgo.MessageEmbedFooter{ Text: "ID: " + m.User.ID, }, } if userAvatarURL != "" { embed.Author = &discordgo.MessageEmbedAuthor{ Name: m.User.Username, IconURL: userAvatarURL, } embed.Thumbnail = &discordgo.MessageEmbedThumbnail{ URL: userAvatarURL, } } gif := strings.TrimSpace(settings.WelcomeGIFURL) if gif == "" { // Default GIF when none configured. gif = "https://images-ext-1.discordapp.net/external/uJ6XfdK2WwDnei3RmNWUqSiOVboC4mK9r78TtgVE_9g/https/media.giphy.com/media/XD9o33QG9BoMis7iM4/giphy.gif" } embed.Image = &discordgo.MessageEmbedImage{URL: gif} if _, err := s.ChannelMessageSendComplex(channelID, &discordgo.MessageSend{ Content: memberMention, Embed: embed, }); err != nil { log.Printf("welcome: failed to send channel welcome in guild %s: %v", m.GuildID, err) } // Optional DM. dmText := strings.TrimSpace(settings.WelcomeDM) if dmText == "" { // Default DM when none configured. // "Welcome to ! Have fun!" dmText = "Welcome to ! Have fun!" } dmText = strings.ReplaceAll(dmText, "{user}", memberMention) if guildName != "" { dmText = strings.ReplaceAll(dmText, "{server}", guildName) dmText = strings.ReplaceAll(dmText, "", guildName) } dmCh, err := s.UserChannelCreate(m.User.ID) if err != nil { log.Printf("welcome: failed to create DM channel for user %s: %v", m.User.ID, err) return } if _, err := s.ChannelMessageSend(dmCh.ID, dmText); err != nil { log.Printf("welcome: failed to send DM welcome to user %s: %v", m.User.ID, err) } }