package xmpp import ( "github.com/pkg/errors" "dev.narayana.im/narayana/telegabber/persistence" log "github.com/sirupsen/logrus" "gosrc.io/xmpp" "gosrc.io/xmpp/stanza" ) func logPacketType(p stanza.Packet) { log.Warnf("Ignoring packet: %T\n", p) } // HandleIq processes an incoming XMPP iq func HandleIq(s xmpp.Sender, p stanza.Packet) { iq, ok := p.(stanza.IQ) if !ok { logPacketType(p) return } log.Printf("Iq: %#v\n", iq) } // HandleMessage processes an incoming XMPP message func HandleMessage(s xmpp.Sender, p stanza.Packet) { msg, ok := p.(stanza.Message) if !ok { logPacketType(p) return } log.Printf("Message: %#v\n", msg) reply := stanza.Message{Attrs: stanza.Attrs{To: msg.From}, Body: msg.Body} _ = s.Send(reply) } // HandlePresence processes an incoming XMPP presence func HandlePresence(s xmpp.Sender, p stanza.Packet) { prs, ok := p.(stanza.Presence) if !ok { logPacketType(p) return } if prs.Type == "subscribe" { handleSubscription(s, prs) } if prs.To == jid.Bare() { handlePresence(s, prs) } } func handleSubscription(s xmpp.Sender, p stanza.Presence) { log.WithFields(log.Fields{ "from": p.From, "to": p.To, }).Warn("Subscription request") log.Debugf("%#v", p) reply := stanza.Presence{Attrs: stanza.Attrs{ From: p.To, To: p.From, Id: p.Id, Type: "subscribed", }} _ = s.Send(reply) } func handlePresence(s xmpp.Sender, p stanza.Presence) { presenceType := p.Type if presenceType == "" { presenceType = "online" } log.WithFields(log.Fields{ "type": presenceType, "from": p.From, "to": p.To, }).Warn("Presence") log.Debugf("%#v", p) fromJid, err := xmpp.NewJid(p.From) if err != nil { log.Error("Invalid from JID!") return } bareFromJid := fromJid.Bare() session, ok := getTelegramInstance(bareFromJid, &persistence.Session{}) if !ok { return } switch p.Type { case "unsubscribed": session.Disconnect() delete(sessions, bareFromJid) case "unavailable", "error": session.Disconnect() case "": // due to the weird implentation of go-tdlib wrapper, it won't // return the client instance until successful authorization go func() { session.Connect() if err != nil { log.Error(errors.Wrap(err, "TDlib connection failure")) } }() } }