Content-Length: 230864 | pFad | https://github.com/oklahomer/go-sarah/wiki/CommandPropsBuilder

FC CommandPropsBuilder · oklahomer/go-sarah Wiki · GitHub
Skip to content

CommandPropsBuilder

Go Hagiwara edited this page Jul 21, 2019 · 4 revisions

Its Goal

Command wiki page introduced that any implementation of sarah.Command interface can be a command. That is the simplest form of sarah.Command creation. Use of sarah.CommandPropsBuilder is an alternate to construct sarah.Command on the fly. Its goal is...

  • to validate input and create a non-contradicting set of arguments to construct sarah.Command
  • to ease sarah.Command creation by providing handy builder method without damaging customizability

To use Live Configuration Update, the use of sarah.CommandProps returned from CommandPropsBuilder.Build is required. This is covered in the later section.

Usage

Basic

Here is the simplest form of sarah.CommandPropsBuilder usage.

// This is a simple command that echos whenever user input starts with ".echo".
var matchPattern = regexp.MustCompile(`^\.echo`)
var SlackProps = sarah.NewCommandPropsBuilder().
        BotType(slack.SLACK).
        Identifier("echo").
        InstructionFunc(func(_ *sarah.HelpInput) string {
                return `Input .echo "foo" to get "foo"`
        }).
        MatchPattern(matchPattern).
        Func(func(_ context.Context, input sarah.Input) (*sarah.CommandResponse, error) {
                // ".echo foo" to "foo"
                return slack.NewStringResponse(sarah.StripMessage(matchPattern, input.Message())), nil
        }).
        MustBuild()

Customized User Input Matching

Use CommandPropsBuilder.MatchFunc instead of CommandPropsBuilder.MatchPattern like below to have more customized input matching. With this setting the whole sarah.Input can be passed on matching.

func isAdminRoom(input sarah.Input) bool {
        // Do something with input to 
        return string(input.ReplyTo()) == "#admin"
}

var slackProps = sarah.NewCommandPropsBuilder().
	BotType(slack.SLACK).
	Identifier("morning").
        InstructionFunc(func(input *sarah.HelpInput) string {
                // 1. See if the input is from a privileged room.
                // If not return empty string so the instruction is not returned to the non-admin user.
                if !isAdminRoom(input) {
                        return ""
                }
                return `Input ".morning" to greet.`
        }).
	MatchFunc(func(input sarah.Input) bool {
                // 1. See if the input is from a privileged room.
                if !isAdminRoom(input) {
                        return false
                }

		// 2. See if the input message starts with ".morning"
		match := strings.HasPrefix(input.Message(), ".morning")
		if !match {
			return false
		}

		// 3. See if current time between 00:00 - 11:59
		hour := time.Now().Hour()
		return hour >= 0 && hour < 12
	}).
	Func(func(_ context.Context, _ sarah.Input) (*sarah.CommandResponse, error) {
		return slack.NewStringResponse("Good morning."), nil
	}).
	MustBuild()

sarah.RegisterCommandProps(slackProps)

Live Configuration Update

Live Configuration Update feature detects configuration file update event, and applies changes to corresponding configuration struct. During this process, sarah.Command is re-built. Since sarah.CommandProps represents a non-contradicting set of arguments, sarah.Runner does not have to worry about arguments' inconsistency.

// When config is passed to ConfigurableFunc and if sarah.Config.PluginConfigRoot is defined,
// sarah.Runner's internal watcher, sarah.Watcher implementation, supervises config directory to re-configure on file update event.
// File located at sarah.Config.PluginConfigRoot + "/" + BotType + "/" Identifier ".(yaml|yml|json) is subject to supervise.
config := &myConfig{}
var slackProps = sarah.NewCommandPropsBuilder().
	BotType(slack.SLACK).
	Identifier("morning").
        InstructionFunc(func(input *sarah.HelpInput) string {
                return `Input ".morning" to greet`
        }).
	MatchFunc(func(input sarah.Input) bool {
		return input.Message() == ".morning"
	}).
	ConfigurableFunc(config, func(_ context.Context, _ sarah.Input, cfg sarah.CommandConfig) (*sarah.CommandResponse, error) {
		typedConfig := cfg.(*myConfig)
		return slack.NewStringResponse(typedConfig.Foo), nil
	}).
	MustBuild()

sarah.RegisterCommandProps(slackProps)

Returned sarah.CommandProps

On CommandPropsBuilder.Build or CommandPropsBuilder.MustBuild, previously given arguments are validated and, if they are valid, an instance that represents a non-contradicting set of arguments to construct sarah.Command is returned. That is sarah.CommandProps. This can be passed to sarah.Runner as sarah.RunnerOption.

While sarah.Command can be directly added to sarah.Bot via Bot.AppendCommand, sarah.CommandProps is passed to sarah.Runner. This is because sarah.Runner is responsible for managing other components' life cycle.

var matchPattern = regexp.MustCompile(`^\.echo`)
var props = sarah.NewCommandPropsBuilder().
        BotType(slack.SLACK).
        Identifier("echo").
        InstructionFunc(func(input *sarah.HelpInput) string {
                return `Send ".echo knock knock" and see what happens.`
        }).
        MatchPattern(matchPattern).
        Func(func(_ context.Context, input sarah.Input) (*sarah.CommandResponse, error) {
                // ".echo foo" to "foo"
                return slack.NewStringResponse(sarah.StripMessage(matchPattern, input.Message())), nil
        }).
        MustBuild()

sarah.RegisterCommandProps(props)








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: https://github.com/oklahomer/go-sarah/wiki/CommandPropsBuilder

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy