first group fix
This commit is contained in:
parent
eef58dcfba
commit
91e2aa41b8
|
@ -72,7 +72,7 @@ func (c *Config) handleDiscoItems(s xmpp.Sender, p stanza.Packet) {
|
||||||
|
|
||||||
log.WithFields(map[string]interface{}{
|
log.WithFields(map[string]interface{}{
|
||||||
"type": c.Type,
|
"type": c.Type,
|
||||||
"from": s,
|
"id": attrs.Id,
|
||||||
"to": attrs.To,
|
"to": attrs.To,
|
||||||
}).Debug("disco items")
|
}).Debug("disco items")
|
||||||
s.Send(iq)
|
s.Send(iq)
|
||||||
|
@ -92,28 +92,32 @@ func (c *Config) handleIQ(s xmpp.Sender, p stanza.Packet) {
|
||||||
|
|
||||||
log.WithFields(map[string]interface{}{
|
log.WithFields(map[string]interface{}{
|
||||||
"type": c.Type,
|
"type": c.Type,
|
||||||
"from": s,
|
|
||||||
"to": attrs.To,
|
"to": attrs.To,
|
||||||
}).Debugf("ignore: %s", iq.Payload)
|
"id": attrs.Id,
|
||||||
|
}).Debugf("ignore: %v", iq.Payload)
|
||||||
s.Send(resp)
|
s.Send(resp)
|
||||||
}
|
}
|
||||||
func (c *Config) handleMessage(s xmpp.Sender, p stanza.Packet) {
|
func (c *Config) handleMessage(s xmpp.Sender, p stanza.Packet) {
|
||||||
msg, ok := p.(stanza.Message)
|
msg, ok := p.(stanza.Message)
|
||||||
attr := msg.Attrs
|
attrs := msg.Attrs
|
||||||
if !ok {
|
if !ok {
|
||||||
pr, ok := p.(stanza.Message)
|
pr, ok := p.(stanza.Presence)
|
||||||
attr = pr.Attrs
|
attrs = pr.Attrs
|
||||||
if !ok {
|
if !ok {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
logger := log.WithFields(map[string]interface{}{
|
||||||
|
"type": c.Type,
|
||||||
|
"id": attrs.Id,
|
||||||
|
"to": attrs.To,
|
||||||
|
})
|
||||||
|
if attrs.Type == "error" {
|
||||||
|
logger.Error(msg.XMPPFormat())
|
||||||
|
return
|
||||||
|
}
|
||||||
if c.XMPPDebug {
|
if c.XMPPDebug {
|
||||||
log.WithFields(map[string]interface{}{
|
logger.Debug(msg.XMPPFormat())
|
||||||
"type": c.Type,
|
|
||||||
"from": s,
|
|
||||||
"to": attr.To,
|
|
||||||
"id": attr.Id,
|
|
||||||
}).Debug(msg.XMPPFormat())
|
|
||||||
}
|
}
|
||||||
c.comp.Send(p)
|
c.comp.Send(p)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,32 @@ func (c *Config) sender(packets chan stanza.Packet) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) fixAddr(addr string) string {
|
||||||
|
if addr == "" {
|
||||||
|
return c.Host
|
||||||
|
}
|
||||||
|
if strings.Contains(addr, "{{DOMAIN}}") {
|
||||||
|
return strings.Replace(addr, "{{DOMAIN}}", c.Host, 1)
|
||||||
|
}
|
||||||
|
if !strings.Contains(addr, "@") {
|
||||||
|
return addr + "@" + c.Host
|
||||||
|
}
|
||||||
|
return addr
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Config) sending(packet stanza.Packet) stanza.Packet {
|
func (c *Config) sending(packet stanza.Packet) stanza.Packet {
|
||||||
logger := log.WithField("type", c.Type)
|
logger := log.WithField("type", c.Type)
|
||||||
switch p := packet.(type) {
|
switch p := packet.(type) {
|
||||||
|
case stanza.Presence:
|
||||||
|
p.From = c.fixAddr(p.From)
|
||||||
|
if p.To != "" {
|
||||||
|
p.To = c.fixAddr(p.To)
|
||||||
|
}
|
||||||
|
return p
|
||||||
case stanza.Message:
|
case stanza.Message:
|
||||||
if p.From == "" {
|
p.From = c.fixAddr(p.From)
|
||||||
p.From = c.Host
|
if p.To != "" {
|
||||||
} else if strings.Contains(p.From, "{{DOMAIN}}") {
|
p.To = c.fixAddr(p.To)
|
||||||
p.From = strings.Replace(p.From, "{{DOMAIN}}", c.Host, 1)
|
|
||||||
} else {
|
|
||||||
p.From += "@" + c.Host
|
|
||||||
}
|
}
|
||||||
if c.XMPPDebug {
|
if c.XMPPDebug {
|
||||||
logger.WithFields(map[string]interface{}{
|
logger.WithFields(map[string]interface{}{
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/o3ma/o3"
|
"github.com/o3ma/o3"
|
||||||
|
"gosrc.io/xmpp/stanza"
|
||||||
|
|
||||||
"dev.sum7.eu/genofire/golang-lib/database"
|
"dev.sum7.eu/genofire/golang-lib/database"
|
||||||
|
|
||||||
|
@ -16,8 +17,10 @@ type Account struct {
|
||||||
ThreemaID *o3.ThreemaID
|
ThreemaID *o3.ThreemaID
|
||||||
send chan<- o3.Message
|
send chan<- o3.Message
|
||||||
receive <-chan o3.ReceivedMsg
|
receive <-chan o3.ReceivedMsg
|
||||||
|
xmpp chan<- stanza.Packet
|
||||||
deliveredMSG map[uint64]string
|
deliveredMSG map[uint64]string
|
||||||
readedMSG map[uint64]string
|
readedMSG map[uint64]string
|
||||||
|
XMPPResource map[string]map[string]bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *Threema) getAccount(jid *models.JID) (*Account, error) {
|
func (t *Threema) getAccount(jid *models.JID) (*Account, error) {
|
||||||
|
@ -48,6 +51,10 @@ func (t *Threema) getAccount(jid *models.JID) (*Account, error) {
|
||||||
AccountThreema: account,
|
AccountThreema: account,
|
||||||
ThreemaID: &tid,
|
ThreemaID: &tid,
|
||||||
threema: t,
|
threema: t,
|
||||||
|
xmpp: t.out,
|
||||||
|
XMPPResource: make(map[string]map[string]bool),
|
||||||
|
deliveredMSG: make(map[uint64]string),
|
||||||
|
readedMSG: make(map[uint64]string),
|
||||||
}
|
}
|
||||||
session := o3.NewSessionContext(tid)
|
session := o3.NewSessionContext(tid)
|
||||||
a.send, a.receive, err = session.Run()
|
a.send, a.receive, err = session.Run()
|
||||||
|
@ -57,10 +64,8 @@ func (t *Threema) getAccount(jid *models.JID) (*Account, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
a.XMPP = *jid
|
a.XMPP = *jid
|
||||||
a.deliveredMSG = make(map[uint64]string)
|
|
||||||
a.readedMSG = make(map[uint64]string)
|
|
||||||
|
|
||||||
go a.receiver(t.out)
|
go a.receiver()
|
||||||
|
|
||||||
t.accountJID[jid.String()] = a
|
t.accountJID[jid.String()] = a
|
||||||
return a, nil
|
return a, nil
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
package threema
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base32"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/o3ma/o3"
|
||||||
|
"gosrc.io/xmpp"
|
||||||
|
)
|
||||||
|
|
||||||
|
func strFromThreemaGroup(header *o3.GroupMessageHeader) string {
|
||||||
|
cid := strings.ToLower(header.CreatorID.String())
|
||||||
|
gid := strings.ToLower(base32.StdEncoding.EncodeToString(header.GroupID[:]))
|
||||||
|
return fmt.Sprintf("%s-%s", cid, gid)
|
||||||
|
}
|
||||||
|
func jidFromThreemaGroup(sender string, header *o3.GroupMessageHeader) string {
|
||||||
|
return fmt.Sprintf("%s@{{DOMAIN}}/%s", strFromThreemaGroup(header), sender)
|
||||||
|
}
|
||||||
|
func jidToThreemaGroup(jidS string) (string, *o3.GroupMessageHeader) {
|
||||||
|
jid, err := xmpp.NewJid(jidS)
|
||||||
|
if err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
node := strings.ToUpper(jid.Node)
|
||||||
|
a := strings.SplitN(node, "-", 2)
|
||||||
|
if len(a) != 2 {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
header := &o3.GroupMessageHeader{
|
||||||
|
CreatorID: o3.NewIDString(a[0]),
|
||||||
|
}
|
||||||
|
|
||||||
|
result, err := base32.StdEncoding.DecodeString(a[1])
|
||||||
|
if err != nil {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
|
copy(header.GroupID[:], []byte(result))
|
||||||
|
|
||||||
|
return jid.Resource, header
|
||||||
|
}
|
|
@ -68,11 +68,19 @@ func (t *Threema) Send(packet stanza.Packet) {
|
||||||
func (t *Threema) send(packet stanza.Packet) stanza.Packet {
|
func (t *Threema) send(packet stanza.Packet) stanza.Packet {
|
||||||
switch p := packet.(type) {
|
switch p := packet.(type) {
|
||||||
case stanza.Presence:
|
case stanza.Presence:
|
||||||
log.Debug(p)
|
from := models.ParseJID(p.Attrs.From)
|
||||||
|
account, err := t.getAccount(from)
|
||||||
|
if err != nil {
|
||||||
|
msg := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, To: from.String()})
|
||||||
|
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
|
||||||
|
}
|
||||||
|
account.handlePresence(p)
|
||||||
return nil
|
return nil
|
||||||
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 {
|
if p.Attrs.Type == stanza.MessageTypeError {
|
||||||
msg := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, To: from.String()})
|
msg := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, To: from.String()})
|
||||||
if p.Error.Text == "User session not found" {
|
if p.Error.Text == "User session not found" {
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package threema
|
package threema
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base32"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -9,16 +8,17 @@ import (
|
||||||
|
|
||||||
"github.com/bdlm/log"
|
"github.com/bdlm/log"
|
||||||
"github.com/o3ma/o3"
|
"github.com/o3ma/o3"
|
||||||
|
"gosrc.io/xmpp"
|
||||||
"gosrc.io/xmpp/stanza"
|
"gosrc.io/xmpp/stanza"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (a *Account) receiver(out chan<- stanza.Packet) {
|
func (a *Account) receiver() {
|
||||||
for receivedMessage := range a.receive {
|
for receivedMessage := range a.receive {
|
||||||
if receivedMessage.Err != nil {
|
if receivedMessage.Err != nil {
|
||||||
log.Warnf("Error Receiving Message: %s\n", receivedMessage.Err)
|
log.Warnf("Error Receiving Message: %s\n", receivedMessage.Err)
|
||||||
xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, To: a.XMPP.String()})
|
xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, To: a.XMPP.String()})
|
||||||
xMSG.Body = fmt.Sprintf("error on decoding message:\n%v", receivedMessage.Err)
|
xMSG.Body = fmt.Sprintf("error on decoding message:\n%v", receivedMessage.Err)
|
||||||
out <- xMSG
|
a.xmpp <- xMSG
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
header := receivedMessage.Msg.Header()
|
header := receivedMessage.Msg.Header()
|
||||||
|
@ -26,12 +26,36 @@ func (a *Account) receiver(out chan<- stanza.Packet) {
|
||||||
if string(a.TID) == sender {
|
if string(a.TID) == sender {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if p, err := a.receiving(receivedMessage.Msg); err != nil {
|
if p, gh, err := a.receiving(receivedMessage.Msg); err != nil {
|
||||||
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()})
|
||||||
xMSG.Body = fmt.Sprintf("error on decoding message: %s\n%v", err, receivedMessage.Msg)
|
xMSG.Body = fmt.Sprintf("error on decoding message: %s\n%v", err, receivedMessage.Msg)
|
||||||
out <- xMSG
|
a.xmpp <- xMSG
|
||||||
} else if p != nil {
|
} else {
|
||||||
out <- p
|
if gh != nil {
|
||||||
|
xid := &xmpp.Jid{
|
||||||
|
Node: a.XMPP.Local,
|
||||||
|
Domain: a.XMPP.Domain,
|
||||||
|
}
|
||||||
|
id := strFromThreemaGroup(gh)
|
||||||
|
if len(a.XMPPResource[id]) == 0 {
|
||||||
|
xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String()})
|
||||||
|
//TODO please join
|
||||||
|
xMSG.Body = fmt.Sprintf(`ERROR: group message not delievered, please join
|
||||||
|
xmpp:%s@{{DOMAIN}}?join`, id)
|
||||||
|
a.xmpp <- xMSG
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
for r := range a.XMPPResource[id] {
|
||||||
|
xid.Resource = r
|
||||||
|
switch m := p.(type) {
|
||||||
|
case stanza.Message:
|
||||||
|
m.Attrs.To = xid.Full()
|
||||||
|
a.xmpp <- m
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
a.xmpp <- p
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,13 +66,7 @@ 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 {
|
func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, *o3.GroupMessageHeader, error) {
|
||||||
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()
|
header := receivedMessage.Header()
|
||||||
sender := header.Sender.String()
|
sender := header.Sender.String()
|
||||||
logger := log.WithFields(map[string]interface{}{
|
logger := log.WithFields(map[string]interface{}{
|
||||||
|
@ -62,53 +80,65 @@ func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) {
|
||||||
dbText := "recv text"
|
dbText := "recv text"
|
||||||
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.GroupMessageHeader != nil {
|
if msg.GroupMessageHeader != nil {
|
||||||
xMSG = stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeGroupchat, From: jidFromThreemaGroup(sender, msg.GroupMessageHeader), To: a.XMPP.String(), Id: strconv.FormatUint(header.ID, 10)})
|
to := a.XMPP.String()
|
||||||
|
ad := strings.SplitN(msg.Body, "=", 2)
|
||||||
|
from := sender
|
||||||
|
if len(ad) == 2 {
|
||||||
|
from = strings.ToLower(ad[0])[:len(ad[0])-3]
|
||||||
|
}
|
||||||
|
xMSG = stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeGroupchat, From: jidFromThreemaGroup(from, msg.GroupMessageHeader), To: to, Id: strconv.FormatUint(header.ID, 10)})
|
||||||
|
if len(ad) == 2 {
|
||||||
|
xMSG.Body = ad[1][4:]
|
||||||
|
} else {
|
||||||
|
xMSG.Body = msg.Body
|
||||||
|
}
|
||||||
dbText = "recv grouptext"
|
dbText = "recv grouptext"
|
||||||
} else {
|
} else {
|
||||||
|
xMSG.Body = msg.Body
|
||||||
requestExtensions(&xMSG)
|
requestExtensions(&xMSG)
|
||||||
}
|
}
|
||||||
xMSG.Body = msg.Body
|
|
||||||
logger.WithFields(map[string]interface{}{
|
logger.WithFields(map[string]interface{}{
|
||||||
"from_x": xMSG.From,
|
"from_x": xMSG.From,
|
||||||
"id": xMSG.Id,
|
"id": xMSG.Id,
|
||||||
"text": xMSG.Body,
|
"text": xMSG.Body,
|
||||||
}).Debug(dbText)
|
}).Debug(dbText)
|
||||||
return xMSG, nil
|
return xMSG, msg.GroupMessageHeader, nil
|
||||||
case *o3.AudioMessage:
|
case *o3.AudioMessage:
|
||||||
if a.threema.httpUploadPath == "" {
|
if a.threema.httpUploadPath == "" {
|
||||||
return nil, errors.New("no place to store files at transport configurated")
|
return nil, nil, errors.New("no place to store files at transport configurated")
|
||||||
}
|
}
|
||||||
data, err := msg.GetData()
|
data, err := msg.GetData()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warnf("unable to read data from message: %s", err)
|
logger.Warnf("unable to read data from message: %s", err)
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
xMSG, err := a.FileToXMPP(sender, header.ID, "mp3", data)
|
xMSG, err := a.FileToXMPP(sender, header.ID, "mp3", data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warnf("unable to create data from message: %s", err)
|
logger.Warnf("unable to create data from message: %s", err)
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
requestExtensions(&xMSG)
|
requestExtensions(&xMSG)
|
||||||
logger.WithField("url", xMSG.Body).Debug("recv audio")
|
logger.WithField("url", xMSG.Body).Debug("recv audio")
|
||||||
return xMSG, nil
|
return xMSG, nil, nil
|
||||||
|
|
||||||
case *o3.ImageMessage:
|
case *o3.ImageMessage:
|
||||||
if a.threema.httpUploadPath == "" {
|
if a.threema.httpUploadPath == "" {
|
||||||
return nil, errors.New("no place to store files at transport configurated")
|
return nil, nil, errors.New("no place to store files at transport configurated")
|
||||||
}
|
}
|
||||||
data, err := msg.GetData(a.ThreemaID)
|
data, err := msg.GetData(a.ThreemaID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warnf("unable to read data from message: %s", err)
|
logger.Warnf("unable to read data from message: %s", err)
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
xMSG, err := a.FileToXMPP(sender, header.ID, "jpg", data)
|
xMSG, err := a.FileToXMPP(sender, header.ID, "jpg", data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Warnf("unable to create data from message: %s", err)
|
logger.Warnf("unable to create data from message: %s", err)
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
requestExtensions(&xMSG)
|
requestExtensions(&xMSG)
|
||||||
logger.WithField("url", xMSG.Body).Debug("recv image")
|
logger.WithField("url", xMSG.Body).Debug("recv image")
|
||||||
return xMSG, nil
|
return xMSG, nil, 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 := ""
|
||||||
|
@ -135,9 +165,9 @@ func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) {
|
||||||
|
|
||||||
if len(xMSG.Extensions) > 0 {
|
if len(xMSG.Extensions) > 0 {
|
||||||
logger.WithField("state", state).Debug("recv state")
|
logger.WithField("state", state).Debug("recv state")
|
||||||
return xMSG, nil
|
return xMSG, nil, nil
|
||||||
}
|
}
|
||||||
return nil, nil
|
return nil, 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 {
|
||||||
|
@ -146,7 +176,7 @@ func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) {
|
||||||
xMSG.Extensions = append(xMSG.Extensions, stanza.StateInactive{})
|
xMSG.Extensions = append(xMSG.Extensions, stanza.StateInactive{})
|
||||||
}
|
}
|
||||||
logger.WithField("on", msg.OnOff).Debug("recv typing")
|
logger.WithField("on", msg.OnOff).Debug("recv typing")
|
||||||
return xMSG, nil
|
return xMSG, nil, nil
|
||||||
}
|
}
|
||||||
return nil, errors.New("not known data format")
|
return nil, nil, errors.New("not known data format")
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,7 @@ func createDummyAccount() Account {
|
||||||
a := Account{
|
a := Account{
|
||||||
deliveredMSG: make(map[uint64]string),
|
deliveredMSG: make(map[uint64]string),
|
||||||
readedMSG: make(map[uint64]string),
|
readedMSG: make(map[uint64]string),
|
||||||
|
xmpp: make(chan<- stanza.Packet),
|
||||||
}
|
}
|
||||||
a.TID = make([]byte, len(threemaFromIDByte))
|
a.TID = make([]byte, len(threemaFromIDByte))
|
||||||
copy(a.TID, threemaFromIDByte[:])
|
copy(a.TID, threemaFromIDByte[:])
|
||||||
|
|
|
@ -2,14 +2,73 @@ package threema
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
|
"encoding/xml"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/bdlm/log"
|
"github.com/bdlm/log"
|
||||||
"github.com/o3ma/o3"
|
"github.com/o3ma/o3"
|
||||||
|
"gosrc.io/xmpp"
|
||||||
"gosrc.io/xmpp/stanza"
|
"gosrc.io/xmpp/stanza"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PresMUCUserItem struct {
|
||||||
|
XMLName xml.Name `xml:"item"`
|
||||||
|
Affiliation string `xml:"affiliation,attr"`
|
||||||
|
Role string `xml:"role,attr"`
|
||||||
|
}
|
||||||
|
type PresMUCUserStatus struct {
|
||||||
|
XMLName xml.Name `xml:"status"`
|
||||||
|
Code int `xml:"code,attr"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PresMUCUserList struct {
|
||||||
|
XMLName xml.Name `xml:"http://jabber.org/protocol/muc#user x"`
|
||||||
|
Items []PresMUCUserItem
|
||||||
|
Status *PresMUCUserStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Account) handlePresence(p stanza.Presence) error {
|
||||||
|
logger := log.WithFields(map[string]interface{}{
|
||||||
|
"from": p.Attrs.From,
|
||||||
|
"to": p.Attrs.To,
|
||||||
|
})
|
||||||
|
_, header := jidToThreemaGroup(p.To)
|
||||||
|
if header == nil {
|
||||||
|
logger.Debug("no group presence")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
from, _ := xmpp.NewJid(p.From)
|
||||||
|
to, _ := xmpp.NewJid(p.To)
|
||||||
|
|
||||||
|
if a.XMPPResource[to.Node] == nil {
|
||||||
|
a.XMPPResource[to.Node] = make(map[string]bool)
|
||||||
|
}
|
||||||
|
a.XMPPResource[to.Node][from.Resource] = true
|
||||||
|
|
||||||
|
ownsender := strings.ToLower(a.ThreemaID.ID.String())
|
||||||
|
//TODO list current users
|
||||||
|
senders := []string{header.CreatorID.String(), ownsender}
|
||||||
|
for _, sender := range senders {
|
||||||
|
sender = strings.ToLower(sender)
|
||||||
|
pres := stanza.NewPresence(stanza.Attrs{To: p.Attrs.From, From: jidFromThreemaGroup(sender, header)})
|
||||||
|
presMUCUserList := PresMUCUserList{
|
||||||
|
Items: []PresMUCUserItem{
|
||||||
|
{
|
||||||
|
Affiliation: "admin",
|
||||||
|
Role: "moderator",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if sender == ownsender {
|
||||||
|
presMUCUserList.Status = &PresMUCUserStatus{Code: 110}
|
||||||
|
}
|
||||||
|
pres.Extensions = append(pres.Extensions, presMUCUserList)
|
||||||
|
a.xmpp <- pres
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
func (a *Account) Send(to string, msg stanza.Message) error {
|
func (a *Account) Send(to string, msg stanza.Message) error {
|
||||||
m, err := a.sending(to, msg)
|
m, err := a.sending(to, msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -125,6 +184,7 @@ func (a *Account) sending(to string, msg stanza.Message) (o3.Message, error) {
|
||||||
if groupHeader != nil {
|
if groupHeader != nil {
|
||||||
logger.Debug("send grouptext")
|
logger.Debug("send grouptext")
|
||||||
// TODO iterate of all occupants
|
// TODO iterate of all occupants
|
||||||
|
//msg3.GroupMessageHeader.Recipient: o3.NewIDString(to),
|
||||||
return msg3, nil
|
return msg3, nil
|
||||||
}
|
}
|
||||||
a.deliveredMSG[msg3ID] = msg.Id
|
a.deliveredMSG[msg3ID] = msg.Id
|
||||||
|
|
Reference in New Issue