package discord import ( "encoding/json" "errors" "io/ioutil" "net/http" "github.com/rs/zerolog/log" ) const ( dadJokeAPI = "https://icanhazdadjoke.com/" dadJokeErr = "Could not get a Dad joke. :slight_frown:" ) type dadJoke struct { ID string `json:"id"` Joke string `json:"joke"` Status int `json:"status"` } func init() { commands = append(commands, &command{ name: "dad", validate: func(cmd commandInit) bool { return true }, run: func(cmd commandInit) (string, error) { if !memeRateLimit.Try() { return "", nil } dj, err := newDadJoke() if err != nil { log.Warn().Msgf("error getting new dad joke: %v", err) return dadJokeErr, nil } return dj.Joke, nil }, help: "Get a random Dad joke", }) } func newDadJoke() (*dadJoke, error) { req, err := http.NewRequest(http.MethodGet, dadJokeAPI, nil) if err != nil { return nil, err } req.Header.Add("Accept", "application/json") resp, err := http.DefaultClient.Do(req) if err != nil { return nil, err } if resp.StatusCode != http.StatusOK { return nil, errors.New("non-ok status") } body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } var dj *dadJoke if err := json.Unmarshal(body, &dj); err != nil { return nil, errors.New("could not unmarshal") } // Check status again, in case API returned an error if dj.Status != http.StatusOK { return nil, errors.New("API error") } return dj, nil }