group message support - WIP
This commit is contained in:
parent
b535a6f685
commit
887d6ac3ff
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 0c0e14982ac6e2886901faef423ed731911b3b39
|
||||
Subproject commit 2f9fc2c25d42892f10eff4c22e8b14fa12f7c39e
|
|
@ -1 +1 @@
|
|||
Subproject commit 8794ea6ed8e17c357c7398adef3e84838b2f9b87
|
||||
Subproject commit 294fe3d7148eefdb27515b465e767b88c290885d
|
Reference in New Issue