Send presence for recovered sessions
This commit is contained in:
parent
47cf94ad01
commit
736abcb5bc
2
Makefile
2
Makefile
|
@ -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
1
go.mod
|
@ -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
2
go.sum
|
@ -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=
|
||||||
|
|
|
@ -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
54
xmpp/component_test.go
Normal 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
49
xmpp/extensions.go
Normal 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{})
|
||||||
|
}
|
Loading…
Reference in a new issue