Refactoring: move SendPresence to xmpp/gateway package
This commit is contained in:
parent
653b1bde94
commit
d6f6207ebb
2
Makefile
2
Makefile
|
@ -4,7 +4,7 @@ all:
|
||||||
go build -o telegabber
|
go build -o telegabber
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -v ./config ./ ./telegram ./xmpp
|
go test -v ./config ./ ./telegram ./xmpp/gateway
|
||||||
|
|
||||||
lint:
|
lint:
|
||||||
$(GOPATH)/bin/golint ./...
|
$(GOPATH)/bin/golint ./...
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package xmpp
|
package xmpp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -11,16 +10,14 @@ import (
|
||||||
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
|
"dev.narayana.im/narayana/telegabber/xmpp/gateway"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/soheilhy/args"
|
|
||||||
"gosrc.io/xmpp"
|
"gosrc.io/xmpp"
|
||||||
"gosrc.io/xmpp/stanza"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const pollingInterval time.Duration = 1e7
|
const pollingInterval time.Duration = 1e7
|
||||||
|
|
||||||
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 queue gateway.Queue
|
||||||
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
|
||||||
|
@ -33,6 +30,8 @@ func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig) (*xmpp.Strea
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
queue = make(gateway.Queue)
|
||||||
|
|
||||||
tgConf = tc
|
tgConf = tc
|
||||||
|
|
||||||
options := xmpp.ComponentOptions{
|
options := xmpp.ComponentOptions{
|
||||||
|
@ -64,19 +63,13 @@ func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig) (*xmpp.Strea
|
||||||
return sm, component, nil
|
return sm, component, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func logPresence(err error, presence *stanza.Presence) {
|
|
||||||
log.WithFields(log.Fields{
|
|
||||||
"presence": *presence,
|
|
||||||
}).Error(errors.Wrap(err, "Couldn't send presence"))
|
|
||||||
}
|
|
||||||
|
|
||||||
func heartbeat(component *xmpp.Component) {
|
func heartbeat(component *xmpp.Component) {
|
||||||
var err error
|
var err error
|
||||||
probeType := SPType("probe")
|
probeType := gateway.SPType("probe")
|
||||||
|
|
||||||
for jid := range sessions {
|
for jid := range sessions {
|
||||||
for {
|
for {
|
||||||
err = sendPresence(component, jid, probeType)
|
err = gateway.SendPresence(component, queue, jid, probeType)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -90,7 +83,7 @@ func heartbeat(component *xmpp.Component) {
|
||||||
for key, presence := range queue {
|
for key, presence := range queue {
|
||||||
err = component.Send(presence)
|
err = component.Send(presence)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logPresence(err, presence)
|
gateway.LogBadPresence(err, presence)
|
||||||
} else {
|
} else {
|
||||||
delete(queue, key)
|
delete(queue, key)
|
||||||
}
|
}
|
||||||
|
@ -135,106 +128,6 @@ func getTelegramInstance(jid string, savedSession *persistence.Session, componen
|
||||||
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) error {
|
|
||||||
var logFrom string
|
|
||||||
bareJid := gateway.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 {
|
|
||||||
xmlPresence, err := xml.Marshal(presence)
|
|
||||||
if err == nil {
|
|
||||||
log.Debug(string(xmlPresence))
|
|
||||||
} else {
|
|
||||||
log.Debugf("%#v", presence)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
immed := SPImmed.Get(args)
|
|
||||||
if immed {
|
|
||||||
err := component.Send(presence)
|
|
||||||
if err != nil {
|
|
||||||
logPresence(err, &presence)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
queue[presence.From+presence.To] = &presence
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close gracefully terminates the component and saves active sessions
|
// Close gracefully terminates the component and saves active sessions
|
||||||
func Close(component *xmpp.Component) {
|
func Close(component *xmpp.Component) {
|
||||||
log.Error("Disconnecting...")
|
log.Error("Disconnecting...")
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package xmpp
|
package extensions
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
|
@ -2,12 +2,19 @@ package gateway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
|
"dev.narayana.im/narayana/telegabber/xmpp/extensions"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"github.com/soheilhy/args"
|
||||||
"gosrc.io/xmpp"
|
"gosrc.io/xmpp"
|
||||||
"gosrc.io/xmpp/stanza"
|
"gosrc.io/xmpp/stanza"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Queue stores presences to send later
|
||||||
|
type Queue map[string]*stanza.Presence
|
||||||
|
|
||||||
// Jid stores the component's JID object
|
// Jid stores the component's JID object
|
||||||
var Jid *xmpp.Jid
|
var Jid *xmpp.Jid
|
||||||
|
|
||||||
|
@ -51,3 +58,111 @@ func SendMessage(to string, from string, body string, component *xmpp.Component)
|
||||||
|
|
||||||
_ = component.Send(message)
|
_ = component.Send(message)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// LogBadPresence verbosely logs a presence
|
||||||
|
func LogBadPresence(err error, presence *stanza.Presence) {
|
||||||
|
log.WithFields(log.Fields{
|
||||||
|
"presence": *presence,
|
||||||
|
}).Error(errors.Wrap(err, "Couldn't send presence"))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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, extensions.PresenceNickExtension{
|
||||||
|
Text: SPNickname.Get(args),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
if SPPhoto.IsSet(args) {
|
||||||
|
presence.Extensions = append(presence.Extensions, extensions.PresenceXVCardUpdateExtension{
|
||||||
|
Photo: extensions.PresenceXVCardUpdatePhoto{
|
||||||
|
Text: SPPhoto.Get(args),
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return presence
|
||||||
|
}
|
||||||
|
|
||||||
|
// SendPresence creates and sends a presence stanza
|
||||||
|
func SendPresence(component *xmpp.Component, queue Queue, to string, args ...args.V) error {
|
||||||
|
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 {
|
||||||
|
xmlPresence, err := xml.Marshal(presence)
|
||||||
|
if err == nil {
|
||||||
|
log.Debug(string(xmlPresence))
|
||||||
|
} else {
|
||||||
|
log.Debugf("%#v", presence)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
immed := SPImmed.Get(args)
|
||||||
|
if immed {
|
||||||
|
err := component.Send(presence)
|
||||||
|
if err != nil {
|
||||||
|
LogBadPresence(err, &presence)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
queue[presence.From+presence.To] = &presence
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package xmpp
|
package gateway
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/xml"
|
"encoding/xml"
|
Loading…
Reference in a new issue