package core import ( "bytes" "fmt" "os/exec" "regexp" "strings" "time" "github.com/bwmarrin/discordgo" ) // source on www.socketloop.com func removeCharacters(input string, characters string) string { filter := func(r rune) rune { if strings.IndexRune(characters, r) < 0 { return r } return -1 } return strings.Map(filter, input) } // https://stackoverflow.com/questions/34839659/how-can-i-easily-get-a-substring-in-go-while-guarding-against-slice-bounds-out func maxString(s string, max int) string { if len(s) > max { r := 0 for i := range s { r++ if r > max { return s[:i] } } } return s } // this only strip custom emoji, not default unicode ones func stripEmoji(msg string) string { re := regexp.MustCompile(`:\w+:`) match := re.FindAll([]byte(msg), -1) if len(match) > 0 { s := msg for i := range match { s = strings.Replace(s, string(match[i]), "", -1) } return s } else { return msg } } func prepareTTSMessage(msg string) string { t1 := maxString(msg, 300) t2 := stripEmoji(t1) t3 := removeCharacters(t2, "-\"'`$();:.\\") return strings.Trim(t3, " ") } func createAudio(msg string) (filename string, file *bytes.Reader) { curr_time := time.Now().Unix() filename = fmt.Sprintf("/tmp/%d.mp3", curr_time) var cmd_args string = fmt.Sprintf("espeak-ng -s 120 -v mb-fr2 -p 30 '%s' --stdout", maxString(msg, 300)) cmd := exec.Command("sh", "-c", cmd_args) out, err := cmd.CombinedOutput() if err != nil { fmt.Println(fmt.Sprint(err)) } file = bytes.NewReader(out) return } func MessagePing(s *discordgo.Session, m *discordgo.MessageCreate) { // Ignore all messages created by the bot itself // This isn't required in this specific example but it's a good practice. if m.Author.ID == s.State.User.ID { return } if m.Content == "ping" { s.ChannelMessageSend(m.ChannelID, "Pong!") } if m.Content == "pong" { s.ChannelMessageSend(m.ChannelID, "Ping!") } } func MessageAudio(s *discordgo.Session, m *discordgo.MessageCreate) { if m.Author.ID == s.State.User.ID { return } var prefix string = "/gogodisco audio" if strings.HasPrefix(m.Content, prefix) { var message string = strings.TrimPrefix(m.Content, prefix) var cleanMessage string = prepareTTSMessage(message) filename, file := createAudio(cleanMessage) s.ChannelFileSend(m.ChannelID, filename, file) } }