108 lines
2.8 KiB
Go
108 lines
2.8 KiB
Go
|
|
package commands
|
||
|
|
|
||
|
|
import (
|
||
|
|
"encoding/json"
|
||
|
|
"fmt"
|
||
|
|
"io/ioutil"
|
||
|
|
"math/rand"
|
||
|
|
"net/http"
|
||
|
|
"net/url"
|
||
|
|
"os"
|
||
|
|
"strings"
|
||
|
|
"time"
|
||
|
|
|
||
|
|
helpers "ion606_bot/Bot/Helpers"
|
||
|
|
|
||
|
|
"github.com/bwmarrin/discordgo"
|
||
|
|
)
|
||
|
|
|
||
|
|
var AnimalGifCommand = &discordgo.ApplicationCommand{
|
||
|
|
Name: "animalgif",
|
||
|
|
Description: "Shows a random cute gif of an animal (default: seal)",
|
||
|
|
Options: []*discordgo.ApplicationCommandOption{
|
||
|
|
{
|
||
|
|
Type: discordgo.ApplicationCommandOptionString,
|
||
|
|
Name: "animal",
|
||
|
|
Description: "Name of the animal (default: seal)",
|
||
|
|
Required: false,
|
||
|
|
},
|
||
|
|
},
|
||
|
|
}
|
||
|
|
|
||
|
|
type TenorResponse struct {
|
||
|
|
Results []struct {
|
||
|
|
MediaFormats map[string]struct {
|
||
|
|
URL string `json:"url"`
|
||
|
|
} `json:"media_formats"`
|
||
|
|
} `json:"results"`
|
||
|
|
Next string `json:"next"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func HandleAnimalGif(s *discordgo.Session, i *discordgo.InteractionCreate) {
|
||
|
|
// Get the animal option, default to "seal" if not provided.
|
||
|
|
animal := "seal"
|
||
|
|
if len(i.ApplicationCommandData().Options) > 0 && i.ApplicationCommandData().Options[0].Value != nil {
|
||
|
|
animal = i.ApplicationCommandData().Options[0].StringValue()
|
||
|
|
}
|
||
|
|
|
||
|
|
// Build the search query (e.g., "cute seal").
|
||
|
|
searchQuery := fmt.Sprintf("cute %s", animal)
|
||
|
|
encodedQuery := url.QueryEscape(searchQuery)
|
||
|
|
|
||
|
|
// Get the Tenor API key from environment.
|
||
|
|
tenorKey := os.Getenv("TENOR_KEY")
|
||
|
|
tenorKey = strings.TrimSpace(tenorKey)
|
||
|
|
if tenorKey == "" {
|
||
|
|
helpers.HandleError(s, i, fmt.Errorf("TENOR_KEY is not set in the environment"))
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
// Build the Tenor API URL.
|
||
|
|
limit := 1
|
||
|
|
apiURL := fmt.Sprintf("https://tenor.googleapis.com/v2/search?q=%s&key=%s&limit=%d&random=true", encodedQuery, tenorKey, limit)
|
||
|
|
|
||
|
|
client := http.Client{Timeout: 10 * time.Second}
|
||
|
|
resp, err := client.Get(apiURL)
|
||
|
|
if err != nil {
|
||
|
|
helpers.HandleError(s, i, fmt.Errorf("error fetching gif: %w", err))
|
||
|
|
return
|
||
|
|
}
|
||
|
|
defer resp.Body.Close()
|
||
|
|
|
||
|
|
body, err := ioutil.ReadAll(resp.Body)
|
||
|
|
if err != nil {
|
||
|
|
helpers.HandleError(s, i, fmt.Errorf("error reading response: %w", err))
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
var tResponse TenorResponse
|
||
|
|
err = json.Unmarshal(body, &tResponse)
|
||
|
|
if err != nil {
|
||
|
|
helpers.HandleError(s, i, fmt.Errorf("error unmarshalling response: %w. Response body: %s", err, string(body)))
|
||
|
|
return
|
||
|
|
}
|
||
|
|
if len(tResponse.Results) == 0 {
|
||
|
|
helpers.HandleError(s, i, fmt.Errorf("no gif results returned from Tenor"))
|
||
|
|
return
|
||
|
|
}
|
||
|
|
|
||
|
|
// Pick a random gif from the results.
|
||
|
|
rand.Seed(time.Now().UnixNano())
|
||
|
|
randomIndex := rand.Intn(len(tResponse.Results))
|
||
|
|
formats := tResponse.Results[randomIndex].MediaFormats
|
||
|
|
gifFormat, ok := formats["gif"]
|
||
|
|
if !ok {
|
||
|
|
helpers.HandleError(s, i, fmt.Errorf("gif format not available in Tenor response"))
|
||
|
|
return
|
||
|
|
}
|
||
|
|
gifURL := gifFormat.URL
|
||
|
|
|
||
|
|
// Respond with the gif.
|
||
|
|
s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{
|
||
|
|
Type: discordgo.InteractionResponseChannelMessageWithSource,
|
||
|
|
Data: &discordgo.InteractionResponseData{
|
||
|
|
Content: gifURL,
|
||
|
|
},
|
||
|
|
})
|
||
|
|
}
|