[filesay] Add FileSay actor

Signed-off-by: Knut Ahlers <knut@ahlers.me>
This commit is contained in:
Knut Ahlers 2022-03-04 23:34:59 +01:00
parent 1ea971d9a3
commit 56f980c48f
Signed by: luzifer
GPG key ID: 0066F03ED215AD7D
3 changed files with 130 additions and 0 deletions

View file

@ -0,0 +1,115 @@
package filesay
import (
"bufio"
"context"
"net/http"
"net/url"
"time"
"github.com/go-irc/irc"
"github.com/pkg/errors"
"github.com/Luzifer/twitch-bot/plugins"
)
const (
actorName = "filesay"
httpTimeout = 5 * time.Second
)
var (
formatMessage plugins.MsgFormatter
send plugins.SendMessageFunc
)
func Register(args plugins.RegistrationArguments) error {
formatMessage = args.FormatMessage
send = args.SendMessage
args.RegisterActor(actorName, func() plugins.Actor { return &actor{} })
args.RegisterActorDocumentation(plugins.ActionDocumentation{
Description: "Takes the content of an URL and pastes it to the current channel",
Name: "FileSay",
Type: actorName,
Fields: []plugins.ActionDocumentationField{
{
Default: "",
Description: "Source of the content to post",
Key: "source",
Name: "source",
Optional: false,
SupportTemplate: true,
Type: plugins.ActionDocumentationFieldTypeString,
},
},
})
return nil
}
type actor struct{}
func (a actor) Execute(c *irc.Client, m *irc.Message, r *plugins.Rule, eventData *plugins.FieldCollection, attrs *plugins.FieldCollection) (preventCooldown bool, err error) {
ptrStringEmpty := func(v string) *string { return &v }("")
source, err := formatMessage(attrs.MustString("source", ptrStringEmpty), m, r, eventData)
if err != nil {
return false, errors.Wrap(err, "executing source template")
}
if source == "" {
return false, errors.New("source template evaluated to empty string")
}
if _, err := url.Parse(source); err != nil {
return false, errors.Wrap(err, "parsing URL")
}
ctx, cancel := context.WithTimeout(context.Background(), httpTimeout)
defer cancel()
req, err := http.NewRequestWithContext(ctx, http.MethodGet, source, nil)
if err != nil {
return false, errors.Wrap(err, "creating HTTP request")
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
return false, errors.Wrap(err, "executing HTTP request")
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return false, errors.Errorf("http status %d", resp.StatusCode)
}
scanner := bufio.NewScanner(resp.Body)
for scanner.Scan() {
if err = c.WriteMessage(&irc.Message{
Command: "PRIVMSG",
Params: []string{
plugins.DeriveChannel(m, eventData),
scanner.Text(),
},
}); err != nil {
return false, errors.Wrap(err, "sending message")
}
}
return false, nil
}
func (a actor) IsAsync() bool { return true }
func (a actor) Name() string { return actorName }
func (a actor) Validate(attrs *plugins.FieldCollection) error {
if v, err := attrs.String("source"); err != nil || v == "" {
return errors.New("source is expected to be non-empty string")
}
return nil
}

View file

@ -13,6 +13,7 @@ import (
"github.com/Luzifer/twitch-bot/internal/actors/ban"
"github.com/Luzifer/twitch-bot/internal/actors/delay"
deleteactor "github.com/Luzifer/twitch-bot/internal/actors/delete"
"github.com/Luzifer/twitch-bot/internal/actors/filesay"
"github.com/Luzifer/twitch-bot/internal/actors/modchannel"
"github.com/Luzifer/twitch-bot/internal/actors/nuke"
"github.com/Luzifer/twitch-bot/internal/actors/punish"
@ -37,6 +38,7 @@ var (
ban.Register,
delay.Register,
deleteactor.Register,
filesay.Register,
modchannel.Register,
nuke.Register,
punish.Register,

View file

@ -57,6 +57,19 @@ Execute external script / command
skip_cooldown_on_error: false
```
## FileSay
Takes the content of an URL and pastes it to the current channel
```yaml
- type: filesay
attributes:
# Source of the content to post
# Optional: false
# Type: string (Supports Templating)
source: ""
```
## Modify Counter
Update counter values