Send presence for recovered sessions

This commit is contained in:
bodqhrohro 2019-11-14 22:11:04 +02:00
parent 47cf94ad01
commit 736abcb5bc
6 changed files with 206 additions and 4 deletions

View file

@ -4,7 +4,7 @@ all:
go build -o telegabber go build -o telegabber
test: test:
go test -v ./config ./ ./telegram go test -v ./config ./ ./telegram ./xmpp
lint: lint:
$(GOPATH)/bin/golint ./... $(GOPATH)/bin/golint ./...

1
go.mod
View file

@ -7,6 +7,7 @@ require (
github.com/pkg/errors v0.8.1 github.com/pkg/errors v0.8.1
github.com/santhosh-tekuri/jsonschema v1.2.4 github.com/santhosh-tekuri/jsonschema v1.2.4
github.com/sirupsen/logrus v1.4.2 github.com/sirupsen/logrus v1.4.2
github.com/soheilhy/args v0.0.0-20150720134047-6bcf4c78e87e
github.com/zelenin/go-tdlib v0.1.0 github.com/zelenin/go-tdlib v0.1.0
gopkg.in/yaml.v2 v2.2.4 gopkg.in/yaml.v2 v2.2.4
gosrc.io/xmpp v0.1.3 gosrc.io/xmpp v0.1.3

2
go.sum
View file

@ -61,6 +61,8 @@ github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHi
github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/soheilhy/args v0.0.0-20150720134047-6bcf4c78e87e h1:Xmvww1DnnCj49ZNwQAw069Kc6X3Q0MUd9OiFQ092yQQ=
github.com/soheilhy/args v0.0.0-20150720134047-6bcf4c78e87e/go.mod h1:RUak+ZC0a3E2NDNxZmA34Hk4Jm9nJMCSKLpKeB06clM=
github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=

View file

@ -1,6 +1,7 @@
package xmpp package xmpp
import ( import (
"encoding/xml"
"github.com/pkg/errors" "github.com/pkg/errors"
"dev.narayana.im/narayana/telegabber/config" "dev.narayana.im/narayana/telegabber/config"
@ -8,12 +9,15 @@ import (
"dev.narayana.im/narayana/telegabber/telegram" "dev.narayana.im/narayana/telegabber/telegram"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/soheilhy/args"
"gosrc.io/xmpp" "gosrc.io/xmpp"
"gosrc.io/xmpp/stanza"
) )
var jid *xmpp.Jid var jid *xmpp.Jid
var tgConf config.TelegramConfig var tgConf config.TelegramConfig
var sessions map[string]telegram.Client var sessions map[string]telegram.Client
var queue map[string]*stanza.Presence
var db persistence.SessionsYamlDB var db persistence.SessionsYamlDB
// NewComponent starts a new component and wraps it in // NewComponent starts a new component and wraps it in
@ -52,13 +56,16 @@ func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig) (*xmpp.Strea
cm := xmpp.NewStreamManager(component, nil) cm := xmpp.NewStreamManager(component, nil)
go maintenance() go maintenance(component)
return cm, nil return cm, nil
} }
func maintenance() { func maintenance(component *xmpp.Component) {
// TODO probeType := SPType("probe")
for jid := range sessions {
sendPresence(component, jid, probeType)
}
} }
func loadSessions(dbPath string) error { func loadSessions(dbPath string) error {
@ -95,3 +102,92 @@ func getTelegramInstance(jid string, savedSession *persistence.Session) (telegra
return session, true return session, true
} }
// SPFrom is a Telegram user id
var SPFrom = args.NewString()
// SPType is a presence type
var SPType = args.NewString()
// SPShow is a availability status
var SPShow = args.NewString()
// SPStatus is a verbose status
var SPStatus = args.NewString()
// SPNickname is a XEP-0172 nickname
var SPNickname = args.NewString()
// SPPhoto is a XEP-0153 hash of avatar in vCard
var SPPhoto = args.NewString()
// SPImmed skips queueing
var SPImmed = args.NewBool(args.Default(true))
func newPresence(bareJid string, to string, args ...args.V) stanza.Presence {
var presenceFrom string
if SPFrom.IsSet(args) {
presenceFrom = SPFrom.Get(args) + "@" + bareJid
} else {
presenceFrom = bareJid
}
presence := stanza.Presence{Attrs: stanza.Attrs{
From: presenceFrom,
To: to,
}}
if SPType.IsSet(args) {
presence.Attrs.Type = stanza.StanzaType(SPType.Get(args))
}
if SPShow.IsSet(args) {
presence.Show = stanza.PresenceShow(SPShow.Get(args))
}
if SPStatus.IsSet(args) {
presence.Status = SPStatus.Get(args)
}
if SPNickname.IsSet(args) {
presence.Extensions = append(presence.Extensions, PresenceNickExtension{
Text: SPNickname.Get(args),
})
}
if SPPhoto.IsSet(args) {
presence.Extensions = append(presence.Extensions, PresenceXVCardUpdateExtension{
Photo: PresenceXVCardUpdatePhoto{
Text: SPPhoto.Get(args),
},
})
}
return presence
}
func sendPresence(component *xmpp.Component, to string, args ...args.V) {
var logFrom string
bareJid := jid.Bare()
if SPFrom.IsSet(args) {
logFrom = SPFrom.Get(args)
} else {
logFrom = bareJid
}
log.WithFields(log.Fields{
"type": SPType.Get(args),
"from": logFrom,
"to": to,
}).Info("Got presence")
presence := newPresence(bareJid, to, args...)
// explicit check, as marshalling is expensive
if log.GetLevel() == log.DebugLevel {
log.Debug(xml.Marshal(presence))
}
immed := SPImmed.Get(args)
if immed {
component.Send(presence)
} else {
queue[presence.From+presence.To] = &presence
}
}

54
xmpp/component_test.go Normal file
View file

@ -0,0 +1,54 @@
package xmpp
import (
"encoding/xml"
"testing"
"gosrc.io/xmpp/stanza"
)
func testPresence(t *testing.T, presence stanza.Presence, reference string) {
byteXML, err := xml.Marshal(presence)
if err != nil {
t.Errorf("XML parse error: %v", err)
}
xmlText := string(byteXML)
if xmlText != reference {
t.Errorf("%v does not match %v", xmlText, reference)
}
}
func TestPresenceFrom(t *testing.T) {
presence := newPresence("from@test", "to@test", SPFrom("test"))
testPresence(t, presence, "<presence from=\"test@from@test\" to=\"to@test\"></presence>")
}
func TestPresenceNoFrom(t *testing.T) {
presence := newPresence("from@test", "to@test")
testPresence(t, presence, "<presence from=\"from@test\" to=\"to@test\"></presence>")
}
func TestPresenceType(t *testing.T) {
presence := newPresence("from@test", "to@test", SPType("subscribe"))
testPresence(t, presence, "<presence type=\"subscribe\" from=\"from@test\" to=\"to@test\"></presence>")
}
func TestPresenceShow(t *testing.T) {
presence := newPresence("from@test", "to@test", SPShow("dnd"))
testPresence(t, presence, "<presence from=\"from@test\" to=\"to@test\"><show>dnd</show></presence>")
}
func TestPresenceStatus(t *testing.T) {
presence := newPresence("from@test", "to@test", SPStatus("cooking"))
testPresence(t, presence, "<presence from=\"from@test\" to=\"to@test\"><status>cooking</status></presence>")
}
func TestPresenceNickname(t *testing.T) {
presence := newPresence("from@test", "to@test", SPNickname("Ishmael"))
testPresence(t, presence, "<presence from=\"from@test\" to=\"to@test\"><nick xmlns=\"http://jabber.org/protocol/nick\">Ishmael</nick></presence>")
}
func TestPresencePhoto(t *testing.T) {
presence := newPresence("from@test", "to@test", SPPhoto("01b87fcd030b72895ff8e88db57ec525450f000d"))
testPresence(t, presence, "<presence from=\"from@test\" to=\"to@test\"><x xmlns=\"vcard-temp:x:update\"><photo>01b87fcd030b72895ff8e88db57ec525450f000d</photo></x></presence>")
}

49
xmpp/extensions.go Normal file
View file

@ -0,0 +1,49 @@
package xmpp
import (
"encoding/xml"
"gosrc.io/xmpp/stanza"
)
// PresenceNickExtension is from XEP-0172
type PresenceNickExtension struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/nick nick"`
Text string `xml:",chardata"`
}
// PresenceXVCardUpdateExtension is from XEP-0153
type PresenceXVCardUpdateExtension struct {
XMLName xml.Name `xml:"vcard-temp:x:update x"`
Photo PresenceXVCardUpdatePhoto
}
// PresenceXVCardUpdatePhoto is from XEP-0153
type PresenceXVCardUpdatePhoto struct {
XMLName xml.Name `xml:"photo"`
Text string `xml:",chardata"`
}
// Namespace is a namespace!
func (c PresenceNickExtension) Namespace() string {
return c.XMLName.Space
}
// Namespace is a namespace!
func (c PresenceXVCardUpdateExtension) Namespace() string {
return c.XMLName.Space
}
func init() {
// presence nick
stanza.TypeRegistry.MapExtension(stanza.PKTPresence, xml.Name{
"http://jabber.org/protocol/nick",
"nick",
}, PresenceNickExtension{})
// presence vcard update
stanza.TypeRegistry.MapExtension(stanza.PKTPresence, xml.Name{
"vcard-temp:x:update",
"x",
}, PresenceXVCardUpdateExtension{})
}