package xmpp import ( "context" "fmt" "kas/cps" "log" "gosrc.io/xmpp" "gosrc.io/xmpp/stanza" ) func messageHandler(s xmpp.Sender, p stanza.Packet) { msg, ok := p.(stanza.Message) if !ok { log.Print("xmpp: ignore packet %T", p) return } response, err := cps.Handle(context.Background(), msg.Body) if err != nil { err = fmt.Errorf("xmpp message handler: %w", err) log.Print(err) } reply := stanza.Message{ Attrs: stanza.Attrs{ To: msg.From, }, Body: response.String(), } err = s.Send(reply) if err != nil { log.Printf("xmpp: failed to send reply to %s: %s", msg.From, err) } } func logError(err error) { err = fmt.Errorf("xmpp: %w", err) log.Print(err) } func Start(cfg *Config) error { log.Printf("starting XMPP server for %s", cfg.Account) config, err := cfg.xmppConfig() if err != nil { return err } go func() { for { // TODO: what happens if we ask the bot to stop? // Best answer: systemd service. runClient(config) } }() return nil } func runClient(cfg *xmpp.Config) { router := xmpp.NewRouter() router.HandleFunc("message", messageHandler) client, err := xmpp.NewClient(cfg, router, logError) if err != nil { logError(err) return } // If you pass the client to a connection manager, it will handle the reconnect policy // for you automatically. cm := xmpp.NewStreamManager(client, nil) log.Print(cm.Run()) }