diff --git a/examples/00_test/ext/ext.go b/examples/00_test/ext/ext.go index 2d2570b..3a1260f 100644 --- a/examples/00_test/ext/ext.go +++ b/examples/00_test/ext/ext.go @@ -3,26 +3,21 @@ package main import ( "log" - "github.com/jaimeteb/chatto/extension" - "github.com/jaimeteb/chatto/query" + ext "github.com/jaimeteb/chatto/extension" ) -func greetFunc(req *extension.ExecuteCommandFuncRequest) (res *extension.ExecuteCommandFuncResponse) { - return &extension.ExecuteCommandFuncResponse{ - FSM: req.FSM, - Answers: []query.Answer{{ - Text: "Hello Universe", - Image: "https://i.imgur.com/pPdjh6x.jpg", - }}, - } +func greetFunc(req *ext.ExecuteCommandFuncRequest) (res *ext.ExecuteCommandFuncResponse) { + return req.NewExecuteCommandFuncResponse( + ext.WithTextAnswer("Hello Universe"), + ) } -var registeredCommandFuncs = extension.RegisteredCommandFuncs{ +var registeredCommandFuncs = ext.RegisteredCommandFuncs{ "any": greetFunc, } func main() { - if err := extension.ServeREST(registeredCommandFuncs); err != nil { + if err := ext.ServeREST(registeredCommandFuncs); err != nil { log.Fatalln(err) } } diff --git a/examples/04_trivia/ext/ext.go b/examples/04_trivia/ext/ext.go index 3b7a51f..3c730a3 100644 --- a/examples/04_trivia/ext/ext.go +++ b/examples/04_trivia/ext/ext.go @@ -4,8 +4,6 @@ import ( "log" "github.com/jaimeteb/chatto/extension" - "github.com/jaimeteb/chatto/fsm" - "github.com/jaimeteb/chatto/query" ) func validateAnswer1(req *extension.ExecuteCommandFuncRequest) (res *extension.ExecuteCommandFuncResponse) { @@ -13,23 +11,20 @@ func validateAnswer1(req *extension.ExecuteCommandFuncRequest) (res *extension.E fsmDomain := req.Domain if !(ans == "1" || ans == "2" || ans == "3") { - return &extension.ExecuteCommandFuncResponse{ - FSM: &fsm.FSM{ - State: fsmDomain.StateTable["question_1"], - Slots: req.FSM.Slots, - }, - Answers: []query.Answer{{Text: "Select one of the options"}}, - } + return req.NewExecuteCommandFuncResponse( + extension.WithTextAnswer("Select one of the options"), + extension.WithState(fsmDomain.StateTable["question_1"]), + ) } - return &extension.ExecuteCommandFuncResponse{ - FSM: req.FSM, - Answers: []query.Answer{{Text: "Question 2:\n" + + return req.NewExecuteCommandFuncResponse( + extension.WithTextAnswer("Question 2:\n" + "What is the capital of the state of Utah?\n" + "1. Salt Lake City\n" + "2. Jefferson City\n" + - "3. Cheyenne"}}, - } + "3. Cheyenne"), + ) + } func validateAnswer2(req *extension.ExecuteCommandFuncRequest) (res *extension.ExecuteCommandFuncResponse) { @@ -37,23 +32,19 @@ func validateAnswer2(req *extension.ExecuteCommandFuncRequest) (res *extension.E fsmDomain := req.Domain if !(ans == "1" || ans == "2" || ans == "3") { - return &extension.ExecuteCommandFuncResponse{ - FSM: &fsm.FSM{ - State: fsmDomain.StateTable["question_2"], - Slots: req.FSM.Slots, - }, - Answers: []query.Answer{{Text: "Select one of the options"}}, - } + return req.NewExecuteCommandFuncResponse( + extension.WithTextAnswer("Select one of the options"), + extension.WithState(fsmDomain.StateTable["question_2"]), + ) } - return &extension.ExecuteCommandFuncResponse{ - FSM: req.FSM, - Answers: []query.Answer{{Text: "Question 3:\n" + + return req.NewExecuteCommandFuncResponse( + extension.WithTextAnswer("Question 3:\n" + "Who painted Starry Night?\n" + "1. Pablo Picasso\n" + "2. Claude Monet\n" + - "3. Vincent Van Gogh"}}, - } + "3. Vincent Van Gogh"), + ) } func calculateScore(req *extension.ExecuteCommandFuncRequest) (res *extension.ExecuteCommandFuncResponse) { @@ -62,13 +53,10 @@ func calculateScore(req *extension.ExecuteCommandFuncRequest) (res *extension.Ex slt := req.FSM.Slots if !(ans == "1" || ans == "2" || ans == "3") { - return &extension.ExecuteCommandFuncResponse{ - FSM: &fsm.FSM{ - State: fsmDomain.StateTable["question_3"], - Slots: req.FSM.Slots, - }, - Answers: []query.Answer{{Text: "Select one of the options"}}, - } + return req.NewExecuteCommandFuncResponse( + extension.WithTextAnswer("Select one of the options"), + extension.WithState(fsmDomain.StateTable["question_3"]), + ) } answer1 := slt["answer_1"] @@ -98,10 +86,9 @@ func calculateScore(req *extension.ExecuteCommandFuncRequest) (res *extension.Ex message = "You got 3/3 answers right.\nYou are good! Congrats!" } - return &extension.ExecuteCommandFuncResponse{ - FSM: req.FSM, - Answers: []query.Answer{{Text: message}}, - } + return req.NewExecuteCommandFuncResponse( + extension.WithTextAnswer(message), + ) } var registeredCommandFuncs = extension.RegisteredCommandFuncs{ diff --git a/extension/server.go b/extension/server.go index 09185c0..d932256 100644 --- a/extension/server.go +++ b/extension/server.go @@ -337,3 +337,47 @@ func (l *ListenerREST) GetBuildVersion(w http.ResponseWriter, r *http.Request) { return } } + +// ExecuteCommandFuncResponseOption functions represent an option to build a new ExecuteCommandFuncResponse +type ExecuteCommandFuncResponseOption func(*ExecuteCommandFuncResponse) + +// NewExecuteCommandFuncResponse creates a new ExecuteCommandFuncResponse based on the data from +// the ExecuteCommandFuncRequest that was sent to the extension command function +func (r *ExecuteCommandFuncRequest) NewExecuteCommandFuncResponse(opts ...ExecuteCommandFuncResponseOption) *ExecuteCommandFuncResponse { + response := ExecuteCommandFuncResponse{ + FSM: r.FSM, + Answers: make([]query.Answer, 0), + } + for _, o := range opts { + o(&response) + } + return &response +} + +// WithAnswer appends a text and image answer to the response +func WithAnswer(text, image string) ExecuteCommandFuncResponseOption { + return func(r *ExecuteCommandFuncResponse) { + r.Answers = append(r.Answers, query.Answer{Text: text, Image: image}) + } +} + +// WithTextAnswer appends a text answer to the response +func WithTextAnswer(text string) ExecuteCommandFuncResponseOption { + return func(r *ExecuteCommandFuncResponse) { + r.Answers = append(r.Answers, query.Answer{Text: text}) + } +} + +// WithState sets a different state to the response's FSM +func WithState(state int) ExecuteCommandFuncResponseOption { + return func(r *ExecuteCommandFuncResponse) { + r.FSM.State = state + } +} + +// WithSlot sets a slot value to the response's FSM +func WithSlot(key, value string) ExecuteCommandFuncResponseOption { + return func(r *ExecuteCommandFuncResponse) { + r.FSM.Slots[key] = value + } +}