This repository has been archived on 2020-09-27. You can view files and clone it, but cannot push or open issues or pull requests.
thrempp/component/threema/receive.go

153 lines
5.0 KiB
Go
Raw Normal View History

package threema
import (
2019-09-06 03:08:58 +02:00
"encoding/base32"
"errors"
"fmt"
"strconv"
2019-09-06 03:08:58 +02:00
"strings"
"github.com/bdlm/log"
"github.com/o3ma/o3"
2019-06-28 03:03:38 +02:00
"gosrc.io/xmpp/stanza"
)
2019-06-28 03:03:38 +02:00
func (a *Account) receiver(out chan<- stanza.Packet) {
for receivedMessage := range a.receive {
2019-06-03 00:02:18 +02:00
if receivedMessage.Err != nil {
log.Warnf("Error Receiving Message: %s\n", receivedMessage.Err)
2019-06-28 03:03:38 +02:00
xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, To: a.XMPP.String()})
2019-06-03 00:02:18 +02:00
xMSG.Body = fmt.Sprintf("error on decoding message:\n%v", receivedMessage.Err)
out <- xMSG
continue
}
2019-08-30 17:28:21 +02:00
header := receivedMessage.Msg.Header()
sender := header.Sender.String()
if string(a.TID) == sender {
continue
}
2019-06-06 20:53:06 +02:00
if p, err := a.receiving(receivedMessage.Msg); err != nil {
2019-06-28 03:03:38 +02:00
xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String()})
2019-08-30 17:28:21 +02:00
xMSG.Body = fmt.Sprintf("error on decoding message: %s\n%v", err, receivedMessage.Msg)
out <- xMSG
} else if p != nil {
out <- p
}
}
}
2019-06-28 03:03:38 +02:00
func requestExtensions(xMSG *stanza.Message) {
xMSG.Extensions = append(xMSG.Extensions, stanza.ReceiptRequest{})
xMSG.Extensions = append(xMSG.Extensions, stanza.Markable{})
xMSG.Extensions = append(xMSG.Extensions, stanza.StateActive{})
}
2019-09-06 03:08:58 +02:00
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)
}
2019-06-28 03:03:38 +02:00
func (a *Account) receiving(receivedMessage o3.Message) (stanza.Packet, error) {
2019-08-30 17:28:21 +02:00
header := receivedMessage.Header()
sender := header.Sender.String()
2019-06-06 20:53:06 +02:00
logger := log.WithFields(map[string]interface{}{
2019-09-06 03:08:58 +02:00
"from": sender,
"to_t": header.Recipient.String(),
2019-06-06 20:53:06 +02:00
"to": a.XMPP.String(),
})
2019-09-06 03:08:58 +02:00
sender = strings.ToLower(sender)
2019-06-06 20:53:06 +02:00
switch msg := receivedMessage.(type) {
2019-09-06 03:08:58 +02:00
case *o3.TextMessage:
dbText := "recv text"
2019-08-30 17:28:21 +02:00
xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String(), Id: strconv.FormatUint(header.ID, 10)})
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)})
dbText = "recv grouptext"
} else {
requestExtensions(&xMSG)
}
2019-08-30 17:28:21 +02:00
xMSG.Body = msg.Body
2019-09-06 03:57:27 +02:00
logger.WithFields(map[string]interface{}{
"from_x": xMSG.From,
"id": xMSG.Id,
"text": xMSG.Body,
}).Debug(dbText)
return xMSG, nil
case *o3.AudioMessage:
if a.threema.httpUploadPath == "" {
return nil, errors.New("no place to store files at transport configurated")
}
data, err := msg.GetData()
if err != nil {
logger.Warnf("unable to read data from message: %s", err)
return nil, err
}
xMSG, err := a.FileToXMPP(sender, header.ID, "mp3", data)
if err != nil {
logger.Warnf("unable to create data from message: %s", err)
return nil, err
}
requestExtensions(&xMSG)
logger.WithField("url", xMSG.Body).Debug("recv audio")
return xMSG, nil
case *o3.ImageMessage:
if a.threema.httpUploadPath == "" {
return nil, errors.New("no place to store files at transport configurated")
}
data, err := msg.GetData(a.ThreemaID)
if err != nil {
logger.Warnf("unable to read data from message: %s", err)
return nil, err
}
xMSG, err := a.FileToXMPP(sender, header.ID, "jpg", data)
if err != nil {
logger.Warnf("unable to create data from message: %s", err)
return nil, err
}
requestExtensions(&xMSG)
logger.WithField("url", xMSG.Body).Debug("recv image")
return xMSG, nil
2019-09-06 03:08:58 +02:00
case *o3.DeliveryReceiptMessage:
2019-08-30 17:28:21 +02:00
xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String()})
2019-06-06 20:53:06 +02:00
state := ""
2019-08-30 17:28:21 +02:00
if msg.Status == o3.MSGDELIVERED {
2019-06-06 20:53:06 +02:00
state = "delivered"
2019-08-30 17:28:21 +02:00
if id, ok := a.deliveredMSG[msg.MessageID]; ok {
2019-06-28 03:03:38 +02:00
xMSG.Extensions = append(xMSG.Extensions, stanza.ReceiptReceived{ID: id})
xMSG.Extensions = append(xMSG.Extensions, stanza.MarkReceived{ID: id})
2019-08-30 17:28:21 +02:00
delete(a.deliveredMSG, msg.MessageID)
} else {
2019-06-06 20:53:06 +02:00
logger.Warnf("found not id in cache to announce received on xmpp side")
}
}
2019-08-30 17:28:21 +02:00
if msg.Status == o3.MSGREAD {
2019-06-06 20:53:06 +02:00
state = "displayed"
2019-08-30 17:28:21 +02:00
if id, ok := a.readedMSG[msg.MessageID]; ok {
2019-06-28 03:03:38 +02:00
xMSG.Extensions = append(xMSG.Extensions, stanza.MarkDisplayed{ID: id})
2019-08-30 17:28:21 +02:00
delete(a.readedMSG, msg.MessageID)
} else {
2019-06-06 20:53:06 +02:00
logger.Warnf("found not id in cache to announce readed on xmpp side")
}
}
if len(xMSG.Extensions) > 0 {
2019-09-06 03:57:27 +02:00
logger.WithField("state", state).Debug("recv state")
return xMSG, nil
}
return nil, nil
2019-09-06 03:08:58 +02:00
case *o3.TypingNotificationMessage:
2019-08-30 17:28:21 +02:00
xMSG := stanza.NewMessage(stanza.Attrs{Type: stanza.MessageTypeChat, From: sender, To: a.XMPP.String(), Id: strconv.FormatUint(header.ID, 10)})
2019-06-06 20:53:06 +02:00
if msg.OnOff != 0 {
2019-06-28 03:03:38 +02:00
xMSG.Extensions = append(xMSG.Extensions, stanza.StateComposing{})
2019-06-06 20:53:06 +02:00
} else {
2019-06-28 03:03:38 +02:00
xMSG.Extensions = append(xMSG.Extensions, stanza.StateInactive{})
2019-06-06 20:53:06 +02:00
}
2019-09-06 03:57:27 +02:00
logger.WithField("on", msg.OnOff).Debug("recv typing")
2019-06-06 20:53:06 +02:00
return xMSG, nil
}
return nil, errors.New("not known data format")
}