aboutsummaryrefslogtreecommitdiff
path: root/xmpp/component.go
diff options
context:
space:
mode:
authorbodqhrohro <bodqhrohro@gmail.com>2019-11-14 23:11:04 +0300
committerbodqhrohro <bodqhrohro@gmail.com>2019-11-14 23:11:04 +0300
commit736abcb5bc3a7e2c0f1f1dfd3052cb6153b60d02 (patch)
treed98db15053f0889f999ae60e0fd67be8c3a963f9 /xmpp/component.go
parent47cf94ad01b4db8749c55c1a1dca50c9b94daf02 (diff)
Send presence for recovered sessions
Diffstat (limited to 'xmpp/component.go')
-rw-r--r--xmpp/component.go102
1 files changed, 99 insertions, 3 deletions
diff --git a/xmpp/component.go b/xmpp/component.go
index a341a2e..3e85f28 100644
--- a/xmpp/component.go
+++ b/xmpp/component.go
@@ -1,6 +1,7 @@
package xmpp
import (
+ "encoding/xml"
"github.com/pkg/errors"
"dev.narayana.im/narayana/telegabber/config"
@@ -8,12 +9,15 @@ import (
"dev.narayana.im/narayana/telegabber/telegram"
log "github.com/sirupsen/logrus"
+ "github.com/soheilhy/args"
"gosrc.io/xmpp"
+ "gosrc.io/xmpp/stanza"
)
var jid *xmpp.Jid
var tgConf config.TelegramConfig
var sessions map[string]telegram.Client
+var queue map[string]*stanza.Presence
var db persistence.SessionsYamlDB
// 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)
- go maintenance()
+ go maintenance(component)
return cm, nil
}
-func maintenance() {
- // TODO
+func maintenance(component *xmpp.Component) {
+ probeType := SPType("probe")
+ for jid := range sessions {
+ sendPresence(component, jid, probeType)
+ }
}
func loadSessions(dbPath string) error {
@@ -95,3 +102,92 @@ func getTelegramInstance(jid string, savedSession *persistence.Session) (telegra
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
+ }
+}