interact: fix private command

This commit is contained in:
c9s 2022-01-14 00:17:41 +08:00
parent a6fb0caff3
commit 91c831140c
2 changed files with 55 additions and 12 deletions

View File

@ -35,7 +35,7 @@ func (c *Command) Transit(state1, state2 State, f interface{}) *Command {
return c return c
} }
func (c *Command) NamedNext(n string, f interface{}) *Command { func (c *Command) NamedNext(n State, f interface{}) *Command {
var curState State var curState State
if c.lastState == "" { if c.lastState == "" {
curState = State(c.Name + "_" + strconv.Itoa(c.stateID)) curState = State(c.Name + "_" + strconv.Itoa(c.stateID))
@ -43,7 +43,7 @@ func (c *Command) NamedNext(n string, f interface{}) *Command {
curState = c.lastState curState = c.lastState
} }
nextState := State(n) nextState := n
c.states[curState] = nextState c.states[curState] = nextState
c.statesFunc[curState] = f c.statesFunc[curState] = f
c.lastState = nextState c.lastState = nextState

View File

@ -80,7 +80,7 @@ func (i *Interact) AddCustomInteraction(custom CustomInteraction) {
func (i *Interact) PrivateCommand(command string, f interface{}) *Command { func (i *Interact) PrivateCommand(command string, f interface{}) *Command {
cmd := NewCommand(command, f) cmd := NewCommand(command, f)
i.commands[command] = cmd i.privateCommands[command] = cmd
return cmd return cmd
} }
@ -108,7 +108,7 @@ func (i *Interact) getNextState(currentState State) (nextState State, final bool
} }
func (i *Interact) setState(s State) { func (i *Interact) setState(s State) {
log.Infof("[interact]: tansiting state from %s -> %s", i.currentState, s) log.Infof("[interact]: transiting state from %s -> %s", i.currentState, s)
i.currentState = s i.currentState = s
} }
@ -135,15 +135,35 @@ func (i *Interact) handleResponse(text string, ctxObjects ...interface{}) error
return nil return nil
} }
func (i *Interact) getCommand(command string) (*Command, error) {
switch i.currentState {
case StateAuthenticated:
if cmd, ok := i.privateCommands[command]; ok {
return cmd, nil
}
case StatePublic:
if _, ok := i.privateCommands[command]; ok {
return nil, fmt.Errorf("private command can not be executed in the public mode")
}
}
if cmd, ok := i.commands[command]; ok {
return cmd, nil
}
return nil, fmt.Errorf("command %s not found", command)
}
func (i *Interact) runCommand(command string, args []string, ctxObjects ...interface{}) error { func (i *Interact) runCommand(command string, args []string, ctxObjects ...interface{}) error {
cmd, ok := i.commands[command] cmd, err := i.getCommand(command)
if !ok { if err != nil {
return fmt.Errorf("command %s not found", command) return err
} }
i.setState(cmd.initState) i.setState(cmd.initState)
err := parseFuncArgsAndCall(cmd.F, args, ctxObjects...) if err := parseFuncArgsAndCall(cmd.F, args, ctxObjects...); err != nil {
if err != nil {
return err return err
} }
@ -165,9 +185,31 @@ func (i *Interact) SetMessenger(messenger Messenger) {
i.messenger = messenger i.messenger = messenger
} }
// builtin initializes the built-in commands
func (i *Interact) builtin() error {
i.Command("/auth", func(reply Reply) error {
reply.Message("Enter your authentication code")
return nil
}).NamedNext(StateAuthenticated, func(reply Reply, code string) error {
// check code
reply.Message("Great! You're authenticated!")
return nil
})
i.Command("/uptime", func(reply Reply) error {
reply.Message("uptime")
return nil
})
return nil
}
func (i *Interact) init() error { func (i *Interact) init() error {
if err := i.builtin(); err != nil {
return err
}
for n, cmd := range i.commands { for n, cmd := range i.commands {
_ = n
for s1, s2 := range cmd.states { for s1, s2 := range cmd.states {
if _, exist := i.states[s1]; exist { if _, exist := i.states[s1]; exist {
return fmt.Errorf("state %s already exists", s1) return fmt.Errorf("state %s already exists", s1)
@ -184,9 +226,10 @@ func (i *Interact) init() error {
return fmt.Errorf("messenger is not set") return fmt.Errorf("messenger is not set")
} }
i.messenger.AddCommand(n, func(reply Reply, response string) error { commandName := n
i.messenger.AddCommand(commandName, func(reply Reply, response string) error {
args := parseCommand(response) args := parseCommand(response)
return i.runCommand(n, args, reply) return i.runCommand(commandName, args, reply)
}) })
} }