Use unique user in unknown command test to avoid last-command fallback interference. Add plugin architecture with registered commands. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
87 lines
1.7 KiB
Go
87 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net/http"
|
|
"os"
|
|
)
|
|
|
|
type BotMessage struct {
|
|
User struct {
|
|
ID int `json:"id"`
|
|
Name string `json:"name"`
|
|
} `json:"user"`
|
|
|
|
Room struct {
|
|
ID int `json:"id"`
|
|
Name string `json:"name"`
|
|
} `json:"room"`
|
|
|
|
Message struct {
|
|
ID int `json:"id"`
|
|
Body struct {
|
|
HTML string `json:"html"`
|
|
Plain string `json:"plain"`
|
|
} `json:"body"`
|
|
} `json:"message"`
|
|
}
|
|
|
|
var userLastCommandType = make(map[string]string)
|
|
|
|
func init() {
|
|
registerPlugin(PingPlugin{})
|
|
registerPlugin(MathPlugin{})
|
|
registerPlugin(HiPlugin{})
|
|
registerPlugin(TracePlugin{})
|
|
registerPlugin(HelpPlugin{})
|
|
}
|
|
|
|
func main() {
|
|
fmt.Println("Sox started")
|
|
http.HandleFunc("/", commandHandler)
|
|
|
|
port := os.Getenv("PORT")
|
|
if port == "" {
|
|
port = "4567"
|
|
}
|
|
|
|
panic(http.ListenAndServe(":"+port, nil))
|
|
}
|
|
|
|
func commandHandler(w http.ResponseWriter, r *http.Request) {
|
|
var msg BotMessage
|
|
err := json.NewDecoder(r.Body).Decode(&msg)
|
|
if err != nil {
|
|
errorResponse(w, http.StatusBadRequest, "invalid request body")
|
|
return
|
|
}
|
|
|
|
fmt.Fprintln(w, executeCommand(msg))
|
|
}
|
|
|
|
func executeCommand(msg BotMessage) string {
|
|
command, arguments := SplitFirstWord(msg.Message.Body.Plain)
|
|
|
|
if p, ok := registry[command]; ok {
|
|
if command != "help" {
|
|
userLastCommandType[msg.User.Name] = command
|
|
}
|
|
return p.Execute(msg, arguments)
|
|
}
|
|
|
|
// Fall back to last command, treating full message as new args
|
|
if last, ok := userLastCommandType[msg.User.Name]; ok {
|
|
if p, ok := registry[last]; ok {
|
|
return p.Execute(msg, msg.Message.Body.Plain)
|
|
}
|
|
}
|
|
|
|
return "Not sure what to do... Try `help` to see what I can do!"
|
|
}
|
|
|
|
func errorResponse(w http.ResponseWriter, status int, msg string) {
|
|
w.WriteHeader(status)
|
|
fmt.Fprintf(w, "Error: %s", msg)
|
|
}
|