aboutsummaryrefslogtreecommitdiff
path: root/xmpp/handlers.go
blob: 3709443b56dec11929fad9a0b8498ba4d6f12543 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package xmpp

import (
	"github.com/pkg/errors"

	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, nil)
	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"))
			}
		}()
	}
}