src/globals/utils.go (view raw)
1package globals
2
3import (
4 "errors"
5 "fmt"
6 "io"
7 "net/http"
8 "net/url"
9 "regexp"
10 "strings"
11 "time"
12
13 "github.com/birabittoh/myks"
14 "github.com/bwmarrin/discordgo"
15 "github.com/kkdai/youtube/v2"
16)
17
18var (
19 searchPattern = regexp.MustCompile(`watch\?v\x3d([a-zA-Z0-9_-]{11})`)
20 searchKS = myks.New[string](12 * time.Hour)
21)
22
23func GetVoiceChannelID(s *discordgo.Session, m *discordgo.MessageCreate) (response string, g *discordgo.Guild, voiceChannelID string) {
24 if m.Member == nil {
25 response = "Please, use this inside a server."
26 return
27 }
28
29 g, err := s.State.Guild(m.GuildID)
30 if err != nil {
31 logger.Errorf("could not get guild: %s", err)
32 response = MsgError
33 return
34 }
35
36 for _, vs := range g.VoiceStates {
37 if vs.UserID == m.Author.ID {
38 voiceChannelID = vs.ChannelID
39 break
40 }
41 }
42
43 if voiceChannelID == "" {
44 response = "You need to be in a voice channel to use this command."
45 }
46 return
47}
48
49func (bc BotCommand) FormatHelp(command, guildID string) string {
50 var shortCodeStr string
51 if bc.ShortCode != "" {
52 shortCodeStr = fmt.Sprintf(" (%s)", FormatCommand(bc.ShortCode, guildID))
53 }
54 return fmt.Sprintf(MsgHelpFmt, FormatCommand(command, guildID)+shortCodeStr, bc.Help)
55}
56
57func FormatCommand(command, guildID string) string {
58 return fmt.Sprintf("`%s%s`", GetPrefix(guildID), command)
59}
60
61func FormatVideo(v *youtube.Video) string {
62 return fmt.Sprintf("**%s** (`%s`)", v.Title, v.Duration.String())
63}
64
65func ParseUserMessage(messageContent, guildID string) (command string, args []string, ok bool) {
66 after, found := strings.CutPrefix(messageContent, GetPrefix(guildID))
67 if !found {
68 return
69 }
70
71 userInput := strings.Split(after, " ")
72 command = strings.ToLower(userInput[0])
73 return command, userInput[1:], len(command) > 0
74}
75
76func GetPrefix(guildID string) string {
77 for _, prefix := range Config.Values.Prefixes {
78 if prefix.Name == guildID {
79 return prefix.Value
80 }
81 }
82
83 Config.Values.Prefixes = append(Config.Values.Prefixes, KeyValuePair{Name: guildID, Value: defaultPrefix})
84 err := Config.Save()
85 if err != nil {
86 logger.Errorf("could not save config: %s", err)
87 }
88 return defaultPrefix
89}
90
91func SetPrefix(guildID, prefixValue string) string {
92 var found bool
93 for i, prefix := range Config.Values.Prefixes {
94 if prefix.Name == guildID {
95 Config.Values.Prefixes[i].Value = prefixValue
96 found = true
97 break
98 }
99 }
100
101 if !found {
102 Config.Values.Prefixes = append(Config.Values.Prefixes, KeyValuePair{Name: guildID, Value: prefixValue})
103 }
104
105 err := Config.Save()
106 if err != nil {
107 logger.Errorf("could not save config: %s", err)
108 }
109 return defaultPrefix
110}
111
112func Search(query string) (videoID string, err error) {
113 escaped := url.QueryEscape(strings.ToLower(strings.TrimSpace(query)))
114
115 cached, err := searchKS.Get(escaped)
116 if err == nil && cached != nil {
117 return *cached, nil
118 }
119
120 resp, err := http.Get("https://www.youtube.com/results?search_query=" + escaped)
121 if err != nil {
122 return
123 }
124 defer resp.Body.Close()
125
126 pageContent, err := io.ReadAll(resp.Body)
127 if err != nil {
128 return
129 }
130
131 matches := searchPattern.FindAllStringSubmatch(string(pageContent), -1)
132 if len(matches) == 0 {
133 err = errors.New("no video found")
134 return
135 }
136
137 videoID = matches[0][1]
138 searchKS.Set(escaped, videoID, 11*time.Hour)
139
140 return matches[0][1], nil
141}