From 3a6296c08ed9362d159235661a76fdf0a791c9b8 Mon Sep 17 00:00:00 2001 From: Martin/Geno Date: Fri, 6 Sep 2019 03:08:58 +0200 Subject: [PATCH] group message support - WIP --- .gitmodules | 3 ++- component/config.go | 13 +++++++++---- component/receiver.go | 2 +- component/send.go | 5 +++++ component/threema/account.go | 7 ++++--- component/threema/main.go | 15 ++++++++++++++- component/threema/receive.go | 27 +++++++++++++++++++++------ component/threema/send.go | 24 +++++++++++++++--------- vendor/github.com/o3ma/o3 | 2 +- vendor/gosrc.io/xmpp | 2 +- 10 files changed, 73 insertions(+), 27 deletions(-) diff --git a/.gitmodules b/.gitmodules index 2f5d250..f781543 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,4 +4,5 @@ branch = fixtests [submodule "vendor/gosrc.io/xmpp"] path = vendor/gosrc.io/xmpp - url = https://github.com/FluuxIO/go-xmpp.git + url = https://github.com/genofire/go-xmpp.git + branch = fix-component diff --git a/component/config.go b/component/config.go index 6f41a00..b72927d 100644 --- a/component/config.go +++ b/component/config.go @@ -1,6 +1,7 @@ package component import ( + "github.com/bdlm/log" "gosrc.io/xmpp" "gosrc.io/xmpp/stanza" ) @@ -17,10 +18,10 @@ type Config struct { comp Component } -func (c *Config) Start() (err error) { +func (c *Config) Start() error { out, err := c.comp.Connect() if err != nil { - return + return err } router := xmpp.NewRouter() @@ -38,10 +39,14 @@ func (c *Config) Start() (err error) { Type: "service", }, router) if err != nil { - return + return err } cm := xmpp.NewStreamManager(c.xmpp, nil) - go cm.Run() + go func() { + if err := cm.Run(); err != nil { + log.WithField("host", c.Host).Panicf("xmpp stream not started: %s", err) + } + }() go c.sender(out) return nil diff --git a/component/receiver.go b/component/receiver.go index 644d9d2..29a20c8 100644 --- a/component/receiver.go +++ b/component/receiver.go @@ -43,7 +43,7 @@ func (c *Config) handleDiscoInfo(s xmpp.Sender, p stanza.Packet) { iq.Payload = &payload log.WithFields(map[string]interface{}{ "type": c.Type, - "from": s, + "from": attrs.From, "to": attrs.To, }).Debug("disco info") s.Send(iq) diff --git a/component/send.go b/component/send.go index cc0fddd..a2a2c3c 100644 --- a/component/send.go +++ b/component/send.go @@ -1,11 +1,14 @@ package component import ( + "strings" + "github.com/bdlm/log" "gosrc.io/xmpp/stanza" ) func (c *Config) sender(packets chan stanza.Packet) { + log.Debugf("start xmpp sender for: %s", c.Host) for packet := range packets { if p := c.sending(packet); p != nil { c.xmpp.Send(p) @@ -19,6 +22,8 @@ func (c *Config) sending(packet stanza.Packet) stanza.Packet { case stanza.Message: if p.From == "" { p.From = c.Host + } else if strings.Contains(p.From, "{{DOMAIN}}") { + p.From = strings.Replace(p.From, "{{DOMAIN}}", c.Host, 1) } else { p.From += "@" + c.Host } diff --git a/component/threema/account.go b/component/threema/account.go index 8cb1e8d..bbb01fd 100644 --- a/component/threema/account.go +++ b/component/threema/account.go @@ -13,7 +13,7 @@ import ( type Account struct { models.AccountThreema threema *Threema - Session o3.SessionContext + ThreemaID *o3.ThreemaID send chan<- o3.Message receive <-chan o3.ReceivedMsg deliveredMSG map[uint64]string @@ -46,10 +46,11 @@ func (t *Threema) getAccount(jid *models.JID) (*Account, error) { a := &Account{ AccountThreema: account, - Session: o3.NewSessionContext(tid), + ThreemaID: &tid, threema: t, } - a.send, a.receive, err = a.Session.Run() + session := o3.NewSessionContext(tid) + a.send, a.receive, err = session.Run() if err != nil { return nil, err diff --git a/component/threema/main.go b/component/threema/main.go index d2e4033..1b237bd 100644 --- a/component/threema/main.go +++ b/component/threema/main.go @@ -70,7 +70,13 @@ func (t *Threema) send(packet stanza.Packet) stanza.Packet { case stanza.Message: from := models.ParseJID(p.Attrs.From) to := models.ParseJID(p.Attrs.To) - + if p.Attrs.Type == stanza.MessageTypeError { + msg := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, To: from.String()}) + if p.Error.Text == "User session not found" { + msg.Body = "please join groupchat xmpp:" + to.String() + "?join" + } + return msg + } if to.IsDomain() { if from == nil { log.Warn("receive message without sender") @@ -87,6 +93,13 @@ func (t *Threema) send(packet stanza.Packet) stanza.Packet { msg.Body = "It was not possible to send, because we have no account for you.\nPlease generate one, by sending `generate` to this gateway" return msg } + if to == nil { + log.WithFields(map[string]interface{}{ + "from": from, + "to": to, + }).Panicf("no to found") + return nil + } threemaID := strings.ToUpper(to.Local) if err := account.Send(threemaID, p); err != nil { diff --git a/component/threema/receive.go b/component/threema/receive.go index 64b38c5..c750f5e 100644 --- a/component/threema/receive.go +++ b/component/threema/receive.go @@ -1,9 +1,11 @@ package threema import ( + "encoding/base32" "errors" "fmt" "strconv" + "strings" "github.com/bdlm/log" "github.com/o3ma/o3" @@ -40,15 +42,29 @@ func requestExtensions(xMSG *stanza.Message) { xMSG.Extensions = append(xMSG.Extensions, stanza.StateActive{}) } +func jidFromThreemaGroup(sender string, header *o3.GroupMessageHeader) string { + cid := strings.ToLower(header.CreatorID.String()) + gid := strings.ToLower(base32.StdEncoding.EncodeToString(header.GroupID[:])) + return fmt.Sprintf("%s-%s@{{DOMAIN}}/%s", cid, gid, sender) +} + func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) { header := receivedMessage.Header() sender := header.Sender.String() logger := log.WithFields(map[string]interface{}{ - "from": header.Sender.String(), + "from": sender, + "to_t": header.Recipient.String(), "to": a.XMPP.String(), }) + sender = strings.ToLower(sender) switch msg := receivedMessage.(type) { - case o3.TextMessage: + case *o3.GroupTextMessage: + xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeGroupchat, From: jidFromThreemaGroup(sender, msg.GroupMessageHeader), To: a.XMPP.String(), Id: strconv.FormatUint(header.ID, 10)}) + xMSG.Body = msg.Body + requestExtensions(&xMSG) + logger.WithField("text", xMSG.Body).Debug("send text") + return xMSG, nil + case *o3.TextMessage: xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String(), Id: strconv.FormatUint(header.ID, 10)}) xMSG.Body = msg.Body requestExtensions(&xMSG) @@ -93,7 +109,7 @@ func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) { logger.WithField("url", xMSG.Body).Debug("send image") return xMSG, nil */ - case o3.DeliveryReceiptMessage: + case *o3.DeliveryReceiptMessage: xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String()}) state := "" @@ -122,15 +138,14 @@ func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) { return xMSG, nil } return nil, nil - case o3.TypingNotificationMessage: + case *o3.TypingNotificationMessage: xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String(), Id: strconv.FormatUint(header.ID, 10)}) if msg.OnOff != 0 { - logger.Debug("composing") xMSG.Extensions = append(xMSG.Extensions, stanza.StateComposing{}) } else { - logger.Debug("inactive") xMSG.Extensions = append(xMSG.Extensions, stanza.StateInactive{}) } + logger.Debug(msg.String()) return xMSG, nil } return nil, errors.New("not known data format") diff --git a/component/threema/send.go b/component/threema/send.go index fb9fede..9df3456 100644 --- a/component/threema/send.go +++ b/component/threema/send.go @@ -19,12 +19,14 @@ func (a *Account) Send(to string, msg stanza.Message) error { return nil } func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) { + from := string(a.AccountThreema.TID) logger := log.WithFields(map[string]interface{}{ - "from": a.XMPP.String(), - "to": to, + "from": a.XMPP.String(), + "from_t": from, + "to": to, }) msg3To := o3.NewIDString(to) - msg3From := o3.NewIDString(string(a.AccountThreema.TID)) + msg3From := o3.NewIDString(from) chatState := false chatStateComposing := false @@ -63,11 +65,12 @@ func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) { if err != nil { return nil, err } - drm := o3.DeliveryReceiptMessage{ + drm := &o3.DeliveryReceiptMessage{ MessageHeader: &o3.MessageHeader{ Sender: msg3From, ID: id, Recipient: msg3To, + PubNick: a.ThreemaID.Nick, }, Status: o3.MSGDELIVERED, } @@ -81,9 +84,11 @@ func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) { return drm, nil } if chatState { - tnm := o3.TypingNotificationMessage{ + tnm := &o3.TypingNotificationMessage{ MessageHeader: &o3.MessageHeader{ - Sender: o3.NewIDString(string(a.AccountThreema.TID)), + Sender: msg3From, + Recipient: msg3To, + PubNick: a.ThreemaID.Nick, }, } if chatStateComposing { @@ -91,18 +96,19 @@ func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) { } logger.WithFields(map[string]interface{}{ "state": chatStateComposing, - }).Debug("not send typing") - return nil, nil + }).Debug("send typing") + return tnm, nil } } msg3ID := o3.NewMsgID() // send text message - msg3 := o3.TextMessage{ + msg3 := &o3.TextMessage{ MessageHeader: &o3.MessageHeader{ Sender: o3.NewIDString(string(a.AccountThreema.TID)), ID: msg3ID, Recipient: msg3To, + PubNick: a.ThreemaID.Nick, }, Body: msg.Body, } diff --git a/vendor/github.com/o3ma/o3 b/vendor/github.com/o3ma/o3 index 0c0e149..b0d1109 160000 --- a/vendor/github.com/o3ma/o3 +++ b/vendor/github.com/o3ma/o3 @@ -1 +1 @@ -Subproject commit 0c0e14982ac6e2886901faef423ed731911b3b39 +Subproject commit b0d11096c694fa58af0598de8ec25a4e7a863db5 diff --git a/vendor/gosrc.io/xmpp b/vendor/gosrc.io/xmpp index 6f9808f..294fe3d 160000 --- a/vendor/gosrc.io/xmpp +++ b/vendor/gosrc.io/xmpp @@ -1 +1 @@ -Subproject commit 6f9808fe169ff8b3f9361c0e43ef6d8e55aaa41b +Subproject commit 294fe3d7148eefdb27515b465e767b88c290885d