Presence/iq handling and rudimental telegram client
This commit is contained in:
parent
7e036fd795
commit
aaf7233c89
|
@ -13,6 +13,7 @@
|
||||||
:device_model: 'telegabber'
|
:device_model: 'telegabber'
|
||||||
:application_version: '2.0'
|
:application_version: '2.0'
|
||||||
:use_chat_info_database: false
|
:use_chat_info_database: false
|
||||||
|
:use_secret_chats: true
|
||||||
|
|
||||||
:xmpp:
|
:xmpp:
|
||||||
:loglevel: :warn
|
:loglevel: :warn
|
||||||
|
|
|
@ -43,7 +43,6 @@ type TelegramContentConfig struct {
|
||||||
// TelegramTdlibConfig is for :tdlib: subtree
|
// TelegramTdlibConfig is for :tdlib: subtree
|
||||||
type TelegramTdlibConfig struct {
|
type TelegramTdlibConfig struct {
|
||||||
Path string `yaml:":lib_path"`
|
Path string `yaml:":lib_path"`
|
||||||
Logfile string `yaml:":logfile"`
|
|
||||||
Client TelegramTdlibClientConfig `yaml:":client"`
|
Client TelegramTdlibClientConfig `yaml:":client"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +53,7 @@ type TelegramTdlibClientConfig struct {
|
||||||
DeviceModel string `yaml:":device_model"`
|
DeviceModel string `yaml:":device_model"`
|
||||||
ApplicationVersion string `yaml:":application_version"`
|
ApplicationVersion string `yaml:":application_version"`
|
||||||
UseChatInfoDatabase bool `yaml:":use_chat_info_database"`
|
UseChatInfoDatabase bool `yaml:":use_chat_info_database"`
|
||||||
|
UseSecretChats bool `yaml:":use_secret_chats"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadConfig reads the specified config file, validates it and returns a struct
|
// ReadConfig reads the specified config file, validates it and returns a struct
|
||||||
|
|
|
@ -39,7 +39,8 @@
|
||||||
"required": [":api_id", ":api_hash"],
|
"required": [":api_id", ":api_hash"],
|
||||||
"properties": {
|
"properties": {
|
||||||
":api_id": {
|
":api_id": {
|
||||||
"$ref": "#/definitions/non-empty-string"
|
"type": "string",
|
||||||
|
"pattern": "^[0-9]+$"
|
||||||
},
|
},
|
||||||
":api_hash": {
|
":api_hash": {
|
||||||
"$ref": "#/definitions/non-empty-string"
|
"$ref": "#/definitions/non-empty-string"
|
||||||
|
@ -52,6 +53,9 @@
|
||||||
},
|
},
|
||||||
":use_chat_info_database": {
|
":use_chat_info_database": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
":use_secret_chats": {
|
||||||
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
3
go.mod
3
go.mod
|
@ -3,8 +3,11 @@ module dev.narayana.im/narayana/telegabber
|
||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Arman92/go-tdlib v0.0.0-20191002071913-526f4e1d15f7
|
||||||
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/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
|
||||||
)
|
)
|
||||||
|
|
13
go.sum
13
go.sum
|
@ -1,8 +1,21 @@
|
||||||
|
github.com/Arman92/go-tdlib v0.0.0-20191002071913-526f4e1d15f7 h1:GbV1Lv3lVHsSeKAqPTBem72OCsGjXntW4jfJdXciE+w=
|
||||||
|
github.com/Arman92/go-tdlib v0.0.0-20191002071913-526f4e1d15f7/go.mod h1:ZzkRfuaFj8etIYMj/ECtXtgfz72RE6U+dos27b3XIwk=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||||
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis=
|
github.com/santhosh-tekuri/jsonschema v1.2.4 h1:hNhW8e7t+H1vgY+1QeEQpveR6D4+OwKPXCfD2aieJis=
|
||||||
github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
|
github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHiuO9LYd+cIxzgEHCQI4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
|
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
|
||||||
|
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||||
|
github.com/zelenin/go-tdlib v0.1.0 h1:Qq+FGE0/EWdsRB6m26ULDndu2DtW558aFXNzi0Y/FqQ=
|
||||||
|
github.com/zelenin/go-tdlib v0.1.0/go.mod h1:Xs8fXbk5n7VaPyrSs9DP7QYoBScWYsjX+lUcWmx1DIU=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc=
|
||||||
|
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
|
||||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
|
|
||||||
"dev.narayana.im/narayana/telegabber/config"
|
"dev.narayana.im/narayana/telegabber/config"
|
||||||
"dev.narayana.im/narayana/telegabber/xmpp"
|
"dev.narayana.im/narayana/telegabber/xmpp"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
// YAML config, compatible with the format of Zhabogram 2.0.0
|
// YAML config, compatible with the format of Zhabogram 2.0.0
|
||||||
const configPath string = "config.yml"
|
const configPath string = "config.yml"
|
||||||
|
|
||||||
// JSON schema (not for editing by a user)
|
// JSON schema (not for editing by a user)
|
||||||
const schemaPath string = "./config_schema.json"
|
const schemaPath string = "./config_schema.json"
|
||||||
|
|
||||||
|
@ -18,7 +19,10 @@ func main() {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cm := xmpp.NewComponent(config.XMPP)
|
cm, err := xmpp.NewComponent(config.XMPP, config.Telegram)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
// reconnect automatically
|
// reconnect automatically
|
||||||
log.Fatal(cm.Run())
|
log.Fatal(cm.Run())
|
||||||
|
|
118
telegram/client.go
Normal file
118
telegram/client.go
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
package telegram
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"dev.narayana.im/narayana/telegabber/config"
|
||||||
|
|
||||||
|
"github.com/zelenin/go-tdlib/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
var logConstants = map[string]int32{
|
||||||
|
"fatal": 0,
|
||||||
|
"error": 1,
|
||||||
|
"warn": 2,
|
||||||
|
"info": 3,
|
||||||
|
"debug": 4,
|
||||||
|
"verbose": 5,
|
||||||
|
"all": 1023,
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringToLogConstant(c string) int32 {
|
||||||
|
level, ok := logConstants[c]
|
||||||
|
if !ok {
|
||||||
|
level = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
return level
|
||||||
|
}
|
||||||
|
|
||||||
|
type TelegramClient struct {
|
||||||
|
client *client.Client
|
||||||
|
jid string
|
||||||
|
parameters *client.TdlibParameters
|
||||||
|
online bool
|
||||||
|
logVerbosity client.Option
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewClient instantiates a Telegram App
|
||||||
|
func NewClient(conf config.TelegramConfig, jid string) (TelegramClient, error) {
|
||||||
|
logVerbosity := client.WithLogVerbosity(&client.SetLogVerbosityLevelRequest{
|
||||||
|
NewVerbosityLevel: stringToLogConstant(conf.Loglevel),
|
||||||
|
})
|
||||||
|
|
||||||
|
apiId, err := strconv.Atoi(conf.Tdlib.Client.APIID)
|
||||||
|
if err != nil {
|
||||||
|
return TelegramClient{}, errors.Wrap(err, "Wrong api_id")
|
||||||
|
}
|
||||||
|
|
||||||
|
parameters := client.TdlibParameters{
|
||||||
|
UseTestDc: false,
|
||||||
|
|
||||||
|
DatabaseDirectory: filepath.Join("./sessions/", jid),
|
||||||
|
FilesDirectory: filepath.Join("./sessions/", jid, "/files/"),
|
||||||
|
|
||||||
|
UseFileDatabase: true,
|
||||||
|
UseChatInfoDatabase: conf.Tdlib.Client.UseChatInfoDatabase,
|
||||||
|
UseMessageDatabase: true,
|
||||||
|
UseSecretChats: conf.Tdlib.Client.UseSecretChats,
|
||||||
|
|
||||||
|
ApiId: int32(apiId),
|
||||||
|
ApiHash: conf.Tdlib.Client.APIHash,
|
||||||
|
|
||||||
|
SystemLanguageCode: "en",
|
||||||
|
DeviceModel: conf.Tdlib.Client.DeviceModel,
|
||||||
|
SystemVersion: "1.0.0",
|
||||||
|
ApplicationVersion: conf.Tdlib.Client.ApplicationVersion,
|
||||||
|
|
||||||
|
EnableStorageOptimizer: true,
|
||||||
|
IgnoreFileNames: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
return TelegramClient{
|
||||||
|
parameters: ¶meters,
|
||||||
|
jid: jid,
|
||||||
|
logVerbosity: logVerbosity,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateHandler(tdlibClient *client.Client) {
|
||||||
|
listener := tdlibClient.GetListener()
|
||||||
|
defer listener.Close()
|
||||||
|
|
||||||
|
for update := range listener.Updates {
|
||||||
|
if update.GetClass() == client.ClassUpdate {
|
||||||
|
fmt.Printf("%#v", update)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramClient) Connect() error {
|
||||||
|
if c.online {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
authorizer := client.ClientAuthorizer()
|
||||||
|
authorizer.TdlibParameters <- c.parameters
|
||||||
|
|
||||||
|
tdlibClient, err := client.NewClient(authorizer, c.logVerbosity)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "Coudn't initialize a Telegram client instance")
|
||||||
|
}
|
||||||
|
|
||||||
|
c.client = tdlibClient
|
||||||
|
c.online = true
|
||||||
|
|
||||||
|
go updateHandler(c.client)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *TelegramClient) Disconnect() {
|
||||||
|
if !c.online {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,7 @@
|
||||||
:device_model: 'telegabber'
|
:device_model: 'telegabber'
|
||||||
:application_version: '2.0'
|
:application_version: '2.0'
|
||||||
:use_chat_info_database: false
|
:use_chat_info_database: false
|
||||||
|
:use_secret_chats: true
|
||||||
|
|
||||||
:xmpp:
|
:xmpp:
|
||||||
:loglevel: :warn
|
:loglevel: :warn
|
||||||
|
|
|
@ -1,16 +1,25 @@
|
||||||
package xmpp
|
package xmpp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"log"
|
|
||||||
|
|
||||||
"dev.narayana.im/narayana/telegabber/config"
|
"dev.narayana.im/narayana/telegabber/config"
|
||||||
|
|
||||||
"gosrc.io/xmpp"
|
"gosrc.io/xmpp"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var jid *xmpp.Jid
|
||||||
|
var tgConf config.TelegramConfig
|
||||||
|
|
||||||
// NewComponent starts a new component and wraps it in
|
// NewComponent starts a new component and wraps it in
|
||||||
// a stream manager that you should start yourself
|
// a stream manager that you should start yourself
|
||||||
func NewComponent(conf config.XMPPConfig) *xmpp.StreamManager {
|
func NewComponent(conf config.XMPPConfig, tc config.TelegramConfig) (*xmpp.StreamManager, error) {
|
||||||
|
var err error
|
||||||
|
jid, err = xmpp.NewJid(conf.Jid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tgConf = tc
|
||||||
|
|
||||||
options := xmpp.ComponentOptions{
|
options := xmpp.ComponentOptions{
|
||||||
Address: conf.Host + ":" + conf.Port,
|
Address: conf.Host + ":" + conf.Port,
|
||||||
Domain: conf.Jid,
|
Domain: conf.Jid,
|
||||||
|
@ -19,14 +28,16 @@ func NewComponent(conf config.XMPPConfig) *xmpp.StreamManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
router := xmpp.NewRouter()
|
router := xmpp.NewRouter()
|
||||||
|
router.HandleFunc("iq", HandleIq)
|
||||||
|
router.HandleFunc("presence", HandlePresence)
|
||||||
router.HandleFunc("message", HandleMessage)
|
router.HandleFunc("message", HandleMessage)
|
||||||
|
|
||||||
component, err := xmpp.NewComponent(options, router)
|
component, err := xmpp.NewComponent(options, router)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("%+v", err)
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cm := xmpp.NewStreamManager(component, nil)
|
cm := xmpp.NewStreamManager(component, nil)
|
||||||
|
|
||||||
return cm
|
return cm, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +1,109 @@
|
||||||
package xmpp
|
package xmpp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"dev.narayana.im/narayana/telegabber/telegram"
|
||||||
"os"
|
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"gosrc.io/xmpp"
|
"gosrc.io/xmpp"
|
||||||
"gosrc.io/xmpp/stanza"
|
"gosrc.io/xmpp/stanza"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var sessions map[string]telegram.TelegramClient
|
||||||
|
|
||||||
|
func logPacketType(p stanza.Packet) {
|
||||||
|
log.Warn("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
|
// HandleMessage processes an incoming XMPP message
|
||||||
func HandleMessage(s xmpp.Sender, p stanza.Packet) {
|
func HandleMessage(s xmpp.Sender, p stanza.Packet) {
|
||||||
msg, ok := p.(stanza.Message)
|
msg, ok := p.(stanza.Message)
|
||||||
if !ok {
|
if !ok {
|
||||||
_, _ = fmt.Fprintf(os.Stdout, "Ignoring packet: %T\n", p)
|
logPacketType(p)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
_, _ = fmt.Fprintf(os.Stdout, "Body = %s - from = %s\n", msg.Body, msg.From)
|
log.Printf("Message: %#v\n", msg)
|
||||||
reply := stanza.Message{Attrs: stanza.Attrs{To: msg.From}, Body: msg.Body}
|
reply := stanza.Message{Attrs: stanza.Attrs{To: msg.From}, Body: msg.Body}
|
||||||
_ = s.Send(reply)
|
_ = 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)
|
||||||
|
} else 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 := sessions[bareFromJid]
|
||||||
|
if !ok {
|
||||||
|
client, err := telegram.NewClient(tgConf, bareFromJid)
|
||||||
|
if err != nil {
|
||||||
|
log.Error("Invalid from JID!")
|
||||||
|
}
|
||||||
|
sessions[bareFromJid] = client
|
||||||
|
}
|
||||||
|
|
||||||
|
switch p.Type {
|
||||||
|
case "unsubscribed":
|
||||||
|
delete(sessions, bareFromJid)
|
||||||
|
case "unavailable", "error":
|
||||||
|
session.Disconnect()
|
||||||
|
case "":
|
||||||
|
session.Connect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue