group message support - WIP

This commit is contained in:
Martin/Geno 2019-09-06 03:08:58 +02:00 committed by genofire
parent b535a6f685
commit 887d6ac3ff
10 changed files with 73 additions and 27 deletions

3
.gitmodules vendored
View File

@ -4,4 +4,5 @@
branch = fixtests branch = fixtests
[submodule "vendor/gosrc.io/xmpp"] [submodule "vendor/gosrc.io/xmpp"]
path = 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

View File

@ -1,6 +1,7 @@
package component package component
import ( import (
"github.com/bdlm/log"
"gosrc.io/xmpp" "gosrc.io/xmpp"
"gosrc.io/xmpp/stanza" "gosrc.io/xmpp/stanza"
) )
@ -17,10 +18,10 @@ type Config struct {
comp Component comp Component
} }
func (c *Config) Start() (err error) { func (c *Config) Start() error {
out, err := c.comp.Connect() out, err := c.comp.Connect()
if err != nil { if err != nil {
return return err
} }
router := xmpp.NewRouter() router := xmpp.NewRouter()
@ -38,10 +39,14 @@ func (c *Config) Start() (err error) {
Type: "service", Type: "service",
}, router) }, router)
if err != nil { if err != nil {
return return err
} }
cm := xmpp.NewStreamManager(c.xmpp, nil) 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) go c.sender(out)
return nil return nil

View File

@ -43,7 +43,7 @@ func (c *Config) handleDiscoInfo(s xmpp.Sender, p stanza.Packet) {
iq.Payload = &payload iq.Payload = &payload
log.WithFields(map[string]interface{}{ log.WithFields(map[string]interface{}{
"type": c.Type, "type": c.Type,
"from": s, "from": attrs.From,
"to": attrs.To, "to": attrs.To,
}).Debug("disco info") }).Debug("disco info")
s.Send(iq) s.Send(iq)

View File

@ -1,11 +1,14 @@
package component package component
import ( import (
"strings"
"github.com/bdlm/log" "github.com/bdlm/log"
"gosrc.io/xmpp/stanza" "gosrc.io/xmpp/stanza"
) )
func (c *Config) sender(packets chan stanza.Packet) { func (c *Config) sender(packets chan stanza.Packet) {
log.Debugf("start xmpp sender for: %s", c.Host)
for packet := range packets { for packet := range packets {
if p := c.sending(packet); p != nil { if p := c.sending(packet); p != nil {
c.xmpp.Send(p) c.xmpp.Send(p)
@ -19,6 +22,8 @@ func (c *Config) sending(packet stanza.Packet) stanza.Packet {
case stanza.Message: case stanza.Message:
if p.From == "" { if p.From == "" {
p.From = c.Host p.From = c.Host
} else if strings.Contains(p.From, "{{DOMAIN}}") {
p.From = strings.Replace(p.From, "{{DOMAIN}}", c.Host, 1)
} else { } else {
p.From += "@" + c.Host p.From += "@" + c.Host
} }

View File

@ -13,7 +13,7 @@ import (
type Account struct { type Account struct {
models.AccountThreema models.AccountThreema
threema *Threema threema *Threema
Session o3.SessionContext ThreemaID *o3.ThreemaID
send chan<- o3.Message send chan<- o3.Message
receive <-chan o3.ReceivedMsg receive <-chan o3.ReceivedMsg
deliveredMSG map[uint64]string deliveredMSG map[uint64]string
@ -46,10 +46,11 @@ func (t *Threema) getAccount(jid *models.JID) (*Account, error) {
a := &Account{ a := &Account{
AccountThreema: account, AccountThreema: account,
Session: o3.NewSessionContext(tid), ThreemaID: &tid,
threema: t, threema: t,
} }
a.send, a.receive, err = a.Session.Run() session := o3.NewSessionContext(tid)
a.send, a.receive, err = session.Run()
if err != nil { if err != nil {
return nil, err return nil, err

View File

@ -70,7 +70,13 @@ func (t *Threema) send(packet stanza.Packet) stanza.Packet {
case stanza.Message: case stanza.Message:
from := models.ParseJID(p.Attrs.From) from := models.ParseJID(p.Attrs.From)
to := models.ParseJID(p.Attrs.To) 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 to.IsDomain() {
if from == nil { if from == nil {
log.Warn("receive message without sender") 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" 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 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) threemaID := strings.ToUpper(to.Local)
if err := account.Send(threemaID, p); err != nil { if err := account.Send(threemaID, p); err != nil {

View File

@ -1,9 +1,11 @@
package threema package threema
import ( import (
"encoding/base32"
"errors" "errors"
"fmt" "fmt"
"strconv" "strconv"
"strings"
"github.com/bdlm/log" "github.com/bdlm/log"
"github.com/o3ma/o3" "github.com/o3ma/o3"
@ -40,15 +42,29 @@ func requestExtensions(xMSG *stanza.Message) {
xMSG.Extensions = append(xMSG.Extensions, stanza.StateActive{}) 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) { func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) {
header := receivedMessage.Header() header := receivedMessage.Header()
sender := header.Sender.String() sender := header.Sender.String()
logger := log.WithFields(map[string]interface{}{ logger := log.WithFields(map[string]interface{}{
"from": header.Sender.String(), "from": sender,
"to_t": header.Recipient.String(),
"to": a.XMPP.String(), "to": a.XMPP.String(),
}) })
sender = strings.ToLower(sender)
switch msg := receivedMessage.(type) { 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 := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String(), Id: strconv.FormatUint(header.ID, 10)})
xMSG.Body = msg.Body xMSG.Body = msg.Body
requestExtensions(&xMSG) requestExtensions(&xMSG)
@ -93,7 +109,7 @@ func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) {
logger.WithField("url", xMSG.Body).Debug("send image") logger.WithField("url", xMSG.Body).Debug("send image")
return xMSG, nil return xMSG, nil
*/ */
case o3.DeliveryReceiptMessage: case *o3.DeliveryReceiptMessage:
xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String()}) xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String()})
state := "" state := ""
@ -122,15 +138,14 @@ func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) {
return xMSG, nil return xMSG, nil
} }
return nil, 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)}) xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String(), Id: strconv.FormatUint(header.ID, 10)})
if msg.OnOff != 0 { if msg.OnOff != 0 {
logger.Debug("composing")
xMSG.Extensions = append(xMSG.Extensions, stanza.StateComposing{}) xMSG.Extensions = append(xMSG.Extensions, stanza.StateComposing{})
} else { } else {
logger.Debug("inactive")
xMSG.Extensions = append(xMSG.Extensions, stanza.StateInactive{}) xMSG.Extensions = append(xMSG.Extensions, stanza.StateInactive{})
} }
logger.Debug(msg.String())
return xMSG, nil return xMSG, nil
} }
return nil, errors.New("not known data format") return nil, errors.New("not known data format")

View File

@ -19,12 +19,14 @@ func (a *Account) Send(to string, msg stanza.Message) error {
return nil return nil
} }
func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) { func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) {
from := string(a.AccountThreema.TID)
logger := log.WithFields(map[string]interface{}{ logger := log.WithFields(map[string]interface{}{
"from": a.XMPP.String(), "from": a.XMPP.String(),
"from_t": from,
"to": to, "to": to,
}) })
msg3To := o3.NewIDString(to) msg3To := o3.NewIDString(to)
msg3From := o3.NewIDString(string(a.AccountThreema.TID)) msg3From := o3.NewIDString(from)
chatState := false chatState := false
chatStateComposing := false chatStateComposing := false
@ -63,11 +65,12 @@ func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
drm := o3.DeliveryReceiptMessage{ drm := &o3.DeliveryReceiptMessage{
MessageHeader: &o3.MessageHeader{ MessageHeader: &o3.MessageHeader{
Sender: msg3From, Sender: msg3From,
ID: id, ID: id,
Recipient: msg3To, Recipient: msg3To,
PubNick: a.ThreemaID.Nick,
}, },
Status: o3.MSGDELIVERED, Status: o3.MSGDELIVERED,
} }
@ -81,9 +84,11 @@ func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) {
return drm, nil return drm, nil
} }
if chatState { if chatState {
tnm := o3.TypingNotificationMessage{ tnm := &o3.TypingNotificationMessage{
MessageHeader: &o3.MessageHeader{ MessageHeader: &o3.MessageHeader{
Sender: o3.NewIDString(string(a.AccountThreema.TID)), Sender: msg3From,
Recipient: msg3To,
PubNick: a.ThreemaID.Nick,
}, },
} }
if chatStateComposing { if chatStateComposing {
@ -91,18 +96,19 @@ func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) {
} }
logger.WithFields(map[string]interface{}{ logger.WithFields(map[string]interface{}{
"state": chatStateComposing, "state": chatStateComposing,
}).Debug("not send typing") }).Debug("send typing")
return nil, nil return tnm, nil
} }
} }
msg3ID := o3.NewMsgID() msg3ID := o3.NewMsgID()
// send text message // send text message
msg3 := o3.TextMessage{ msg3 := &o3.TextMessage{
MessageHeader: &o3.MessageHeader{ MessageHeader: &o3.MessageHeader{
Sender: o3.NewIDString(string(a.AccountThreema.TID)), Sender: o3.NewIDString(string(a.AccountThreema.TID)),
ID: msg3ID, ID: msg3ID,
Recipient: msg3To, Recipient: msg3To,
PubNick: a.ThreemaID.Nick,
}, },
Body: msg.Body, Body: msg.Body,
} }

2
vendor/github.com/o3ma/o3 generated vendored

@ -1 +1 @@
Subproject commit 0c0e14982ac6e2886901faef423ed731911b3b39 Subproject commit 2f9fc2c25d42892f10eff4c22e8b14fa12f7c39e

2
vendor/gosrc.io/xmpp generated vendored

@ -1 +1 @@
Subproject commit 8794ea6ed8e17c357c7398adef3e84838b2f9b87 Subproject commit 294fe3d7148eefdb27515b465e767b88c290885d