// Author: Matthew Shiel package main import ( "embed" "encoding/json" "fmt" "html/template" "io/ioutil" "log" "net/http" "strings" "git.riomhaire.com/gremlin/elizaservice/eliza" "github.com/jaffee/commandeer" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" ) //go:embed web/* var web embed.FS //go:embed templates/* var templates embed.FS //go:embed bots/* var bots embed.FS type Main struct { BotName string `help:"What This Bot is Called."` Port int `help:"What port bot is listening too"` } func NewMain() *Main { return &Main{ BotName: "Eliza", Port: 8070, } } func findPersonality(name string) (personality eliza.Personality, err error) { filename := "bots/" + name + ".json" jsonFile, err := bots.Open(filename) // if we os.Open returns an error then handle it if err != nil { return } // fmt.Println("Successfully Opened ", filename) byteValue, _ := ioutil.ReadAll(jsonFile) // we initialize our Users array personality = eliza.Personality{} // we unmarshal our byteArray which contains our // jsonFile's content into 'users' which we defined above json.Unmarshal(byteValue, &personality) // defer the closing of our jsonFile so that we can parse it later on defer jsonFile.Close() return } func chantboInteractiontEndpoint(c echo.Context) error { // Extract question from GET request question := c.QueryParam("value") botname := c.QueryParam("bot") // default to eliza if len(botname) == 0 { botname = "eliza" } personality, err := findPersonality(strings.ToLower(botname)) // files are in lowercase if err != nil { fmt.Fprintf(c.Response(), "%s", err.Error()) return nil } // Return Eliza's response's so long as the user doesn't give a quit statement character := eliza.NewBotPersonality(&personality) answer := character.ReplyTo(question) // Return Eliza's answer fmt.Fprintf(c.Response(), "%s", answer) return nil } func chantbotEndpoint(c echo.Context) error { c.Response().WriteHeader(http.StatusOK) c.Response().Header().Add("Content-Type", "text/html") // Note the call to ParseFS instead of Parse personality := c.Param("personality") t, err := template.ParseFS(templates, fmt.Sprintf("templates/%s.html", personality)) if err != nil { log.Fatal(err) } // respond with the output of template execution t.Execute(c.Response(), struct { Id string GivenName string FamilyName string Name string Bot string }{ Id: c.QueryParam("user_id"), GivenName: c.QueryParam("given_name"), FamilyName: c.QueryParam("family_name"), Name: c.QueryParam("name"), Bot: strings.Title(strings.ToLower(personality)), }) return nil } func (m *Main) Run() error { fmt.Println(` ####### # ### ####### # # # # # # # # # # # # # ##### # # # # # # # # # ####### # # # # # # ####### ####### ### ####### # # `) fmt.Println() e := echo.New() var contentHandler = echo.WrapHandler(http.FileServer(http.FS(web))) var contentRewrite = middleware.Rewrite(map[string]string{"/*": "/web/$1"}) e.GET("/user-input", chantboInteractiontEndpoint) e.GET("/chatbot/:personality", chantbotEndpoint) e.GET("/*", contentHandler, contentRewrite) e.Logger.Fatal(e.Start(fmt.Sprintf(":%d", m.Port))) return nil } func main() { err := commandeer.Run(NewMain()) if err != nil { fmt.Println(err) } }