diff --git a/component/threema/account.go b/component/threema/account.go index b3d2631..6d987bf 100644 --- a/component/threema/account.go +++ b/component/threema/account.go @@ -14,9 +14,10 @@ import ( type Account struct { models.AccountThreema - Session o3.SessionContext - send chan<- o3.Message - recieve <-chan o3.ReceivedMsg + Session o3.SessionContext + send chan<- o3.Message + recieve <-chan o3.ReceivedMsg + deliveredMSG map[uint64]string } func (t *Threema) getAccount(jid *models.JID) *Account { @@ -44,6 +45,7 @@ func (t *Threema) getAccount(jid *models.JID) *Account { a.XMPP = *jid a.Session = o3.NewSessionContext(tid) a.send, a.recieve, err = a.Session.Run() + a.deliveredMSG = make(map[uint64]string) // TODO error handling if err != nil { @@ -53,7 +55,6 @@ func (t *Threema) getAccount(jid *models.JID) *Account { go a.reciever(t.out) t.accountJID[jid.String()] = a - t.accountTID[string(a.TID)] = a return a } @@ -71,14 +72,55 @@ func (a *Account) reciever(out chan<- xmpp.Packet) { } xMSG := xmpp.NewMessage("chat", sender, a.XMPP.String(), strconv.FormatUint(msg.ID(), 10), "en") xMSG.Body = msg.Text() + xMSG.Extensions = append(xMSG.Extensions, xmpp.ReceiptRequest{}) out <- xMSG case o3.DeliveryReceiptMessage: - // msg.MsgID() + if id, ok := a.deliveredMSG[msg.MsgID()]; ok { + xMSG := xmpp.NewMessage("chat", msg.Sender().String(), a.XMPP.String(), "", "en") + log.Warnf("found id %s", id) + xMSG.Extensions = append(xMSG.Extensions, xmpp.ReceiptReceived{ + Id: id, + }) + out <- xMSG + delete(a.deliveredMSG, msg.MsgID()) + } else { + log.Warnf("found not id in cache to announce received on xmpp side") + } } } } -func (a *Account) Send(to string, msg string) error { - return a.Session.SendTextMessage(to, msg, a.send) +func (a *Account) Send(to string, msg xmpp.Message) error { + reci := "" + for _, el := range msg.Extensions { + switch ex := el.(type) { + case *xmpp.ReceiptReceived: + reci = ex.Id + } + } + if reci != "" { + id, err := strconv.ParseUint(reci, 10, 64) + if err != nil { + return err + } + drm, err := o3.NewDeliveryReceiptMessage(&a.Session, to, id, o3.MSGDELIVERED) + if err != nil { + return err + } + a.send <- drm + log.WithFields(map[string]interface{}{ + "tid": to, + "msg_id": id, + }).Debug("delivered") + return nil + } + + msg3, err := o3.NewTextMessage(&a.Session, to, msg.Body) + if err != nil { + return err + } + a.deliveredMSG[msg3.ID()] = msg.Id + a.send <- msg3 + return nil } diff --git a/component/threema/main.go b/component/threema/main.go index 46015ba..0ff49e8 100644 --- a/component/threema/main.go +++ b/component/threema/main.go @@ -16,14 +16,12 @@ type Threema struct { component.Component out chan xmpp.Packet accountJID map[string]*Account - accountTID map[string]*Account } func NewThreema(config map[string]interface{}) (component.Component, error) { return &Threema{ out: make(chan xmpp.Packet), accountJID: make(map[string]*Account), - accountTID: make(map[string]*Account), }, nil } @@ -35,7 +33,7 @@ func (t *Threema) Connect() (chan xmpp.Packet, error) { log.WithFields(map[string]interface{}{ "jid": jid.String(), "threema": string(a.TID), - }).Debug("connected") + }).Info("connected") } return t.out, nil } @@ -45,11 +43,6 @@ func (t *Threema) Send(packet xmpp.Packet) { from := models.ParseJID(p.PacketAttrs.From) to := models.ParseJID(p.PacketAttrs.To) - logger := log.WithFields(map[string]interface{}{ - "from": from, - "to": to, - }) - logger.Debug(p.Body) if to.IsDomain() { msg := xmpp.NewMessage("chat", "", from.String(), "", "en") msg.Body = t.Bot(from, p.Body) @@ -66,7 +59,7 @@ func (t *Threema) Send(packet xmpp.Packet) { } threemaID := strings.ToUpper(to.Local) - if err := account.Send(threemaID, p.Body); err != nil { + if err := account.Send(threemaID, p); err != nil { msg := xmpp.NewMessage("chat", "", from.String(), "", "en") msg.Body = err.Error() t.out <- msg diff --git a/component/xmpp.go b/component/xmpp.go index 0ae5ada..4741661 100644 --- a/component/xmpp.go +++ b/component/xmpp.go @@ -43,11 +43,11 @@ func (c *Config) recieve(packets chan xmpp.Packet) { } else { p.PacketAttrs.From += "@" + c.Host } - loggerMSG := logger.WithFields(map[string]interface{}{ + logger.WithFields(map[string]interface{}{ "from": p.PacketAttrs.From, "to": p.PacketAttrs.To, - }) - loggerMSG.Debug(p.Body) + "id": p.PacketAttrs.Id, + }).Debug(p.XMPPFormat()) c.xmpp.Send(p) default: log.Warn("ignoring packet:", packet) @@ -90,6 +90,7 @@ func (c *Config) sender() { Features: []xmpp.Feature{ {Var: "http://jabber.org/protocol/disco#info"}, {Var: "http://jabber.org/protocol/disco#item"}, + {Var: xmpp.NSSpaceXEP0184Receipt}, }, } iq.AddPayload(&payload) @@ -124,6 +125,11 @@ func (c *Config) sender() { } case xmpp.Message: + logger.WithFields(map[string]interface{}{ + "from": p.PacketAttrs.From, + "to": p.PacketAttrs.To, + "id": p.PacketAttrs.Id, + }).Debug(p.XMPPFormat()) c.comp.Send(packet) case xmpp.Presence: