diff --git a/internal/template/api/api.go b/internal/template/api/api.go index 87dc96b..96a59b4 100644 --- a/internal/template/api/api.go +++ b/internal/template/api/api.go @@ -4,6 +4,7 @@ import "github.com/Luzifer/twitch-bot/v3/plugins" func Register(args plugins.RegistrationArguments) error { args.RegisterTemplateFunction("jsonAPI", plugins.GenericTemplateFunctionGetter(jsonAPI)) + args.RegisterTemplateFunction("textAPI", plugins.GenericTemplateFunctionGetter(textAPI)) return nil } diff --git a/internal/template/api/textAPI.go b/internal/template/api/textAPI.go new file mode 100644 index 0000000..ebc96e4 --- /dev/null +++ b/internal/template/api/textAPI.go @@ -0,0 +1,58 @@ +package api + +import ( + "bytes" + "context" + "io" + "net/http" + "net/url" + + "github.com/pkg/errors" +) + +func textAPI(uri string, fallback ...string) (string, error) { + u, err := url.Parse(uri) + if err != nil { + return "", errors.Wrap(err, "parsing URL") + } + + reqCtx, cancel := context.WithTimeout(context.Background(), remoteRequestTimeout) + defer cancel() + + req, err := http.NewRequestWithContext(reqCtx, http.MethodGet, u.String(), nil) + if err != nil { + return "", errors.Wrap(err, "assembling request") + } + req.Header.Set("User-Agent", "Luzifer/twitch-bot template/api/jsonAPI (https://github.com/Luzifer/twitch-bot)") + + resp, err := http.DefaultClient.Do(req) + if err != nil { + return "", errors.Wrap(err, "executing request") + } + defer resp.Body.Close() + + switch resp.StatusCode { + case http.StatusOK: + // That's what we wanna see + + case http.StatusNoContent: + if len(fallback) > 0 { + return fallback[0], nil + } + return "", errors.Errorf("unexpected HTTP status %d without fallback", resp.StatusCode) + + default: + return "", errors.Errorf("unexpected HTTP status %d", resp.StatusCode) + } + + content, err := io.ReadAll(resp.Body) + if err != nil { + return "", errors.Wrap(err, "reading response body") + } + + if len(bytes.TrimSpace(content)) == 0 && len(fallback) > 0 { + return fallback[0], nil + } + + return string(content), nil +} diff --git a/wiki/Templating.md b/wiki/Templating.md index ee4ef45..af27010 100644 --- a/wiki/Templating.md +++ b/wiki/Templating.md @@ -389,6 +389,21 @@ Example: < luziferus ``` +#### `textAPI` + +Fetches remote URL and returns the result as string. (Remote API needs to return status 200 within 5 seconds.) + +Syntax: `textAPI "https://example.com/" ["fallback"]` + +Example: + +``` +! !weather (.*) +> !weather Hamburg +# {{ textAPI (printf "https://api.scorpstuff.com/weather.php?units=metric&city=%s" (urlquery (group 1))) }} +< Weather for Hamburg, DE: Few clouds with a temperature of 22 C (71.6 F). [...] +``` + #### `variable` Returns the variable value or default in case it is empty