diff --git a/.gitmodules b/.gitmodules index 3ac4dc7..d71b41f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "vendor/gosrc.io/xmpp"] path = vendor/gosrc.io/xmpp url = https://github.com/genofire/go-xmpp - branch = msg_extension + branch = all diff --git a/component/config.go b/component/config.go index 122f5cb..756c190 100644 --- a/component/config.go +++ b/component/config.go @@ -9,6 +9,7 @@ type Config struct { Host string Connection string Secret string + XMPPLog bool `toml:"xmpp_log"` Special map[string]interface{} xmpp *xmpp.Component diff --git a/component/receiver.go b/component/receiver.go index 20dfd61..562eac0 100644 --- a/component/receiver.go +++ b/component/receiver.go @@ -55,6 +55,7 @@ func (c *Config) receiving(packet xmpp.Packet) (xmpp.Packet, bool) { {Var: xmpp.NSDiscoItems}, {Var: xmpp.NSMsgReceipts}, {Var: xmpp.NSMsgChatMarkers}, + {Var: xmpp.NSMsgChatStateNotifications}, }, } iq.AddPayload(&payload) @@ -90,12 +91,13 @@ func (c *Config) receiving(packet xmpp.Packet) (xmpp.Packet, bool) { } case xmpp.Message: - logger.WithFields(map[string]interface{}{ - "from": p.PacketAttrs.From, - "to": p.PacketAttrs.To, - "id": p.PacketAttrs.Id, - }).Debug(p.XMPPFormat()) - + if c.XMPPLog { + logger.WithFields(map[string]interface{}{ + "from": p.PacketAttrs.From, + "to": p.PacketAttrs.To, + "id": p.PacketAttrs.Id, + }).Debug(p.XMPPFormat()) + } return packet, false case xmpp.Presence: diff --git a/component/send.go b/component/send.go index 21a5179..9d0036a 100644 --- a/component/send.go +++ b/component/send.go @@ -22,11 +22,13 @@ func (c *Config) sending(packet xmpp.Packet) xmpp.Packet { } else { p.PacketAttrs.From += "@" + c.Host } - logger.WithFields(map[string]interface{}{ - "from": p.PacketAttrs.From, - "to": p.PacketAttrs.To, - "id": p.PacketAttrs.Id, - }).Debug(p.XMPPFormat()) + if c.XMPPLog { + logger.WithFields(map[string]interface{}{ + "from": p.PacketAttrs.From, + "to": p.PacketAttrs.To, + "id": p.PacketAttrs.Id, + }).Debug(p.XMPPFormat()) + } return p default: log.Warn("ignoring packet:", packet) diff --git a/component/threema/receive.go b/component/threema/receive.go index bbade52..a78f57a 100644 --- a/component/threema/receive.go +++ b/component/threema/receive.go @@ -23,7 +23,7 @@ func (a *Account) receiver(out chan<- xmpp.Packet) { if string(a.TID) == sender { continue } - if p, err := a.receiving(receivedMessage); err != nil { + if p, err := a.receiving(receivedMessage.Msg); err != nil { xMSG := xmpp.NewMessage("chat", sender, a.XMPP.String(), "", "en") xMSG.Body = fmt.Sprintf("error on decoding message: %s\n%v", err, receivedMessage.Msg.Serialize()) out <- xMSG @@ -36,15 +36,21 @@ func (a *Account) receiver(out chan<- xmpp.Packet) { func requestExtensions(xMSG *xmpp.Message) { xMSG.Extensions = append(xMSG.Extensions, xmpp.ReceiptRequest{}) xMSG.Extensions = append(xMSG.Extensions, xmpp.Markable{}) + xMSG.Extensions = append(xMSG.Extensions, xmpp.StateActive{}) } -func (a *Account) receiving(receivedMessage o3.ReceivedMsg) (xmpp.Packet, error) { - switch msg := receivedMessage.Msg.(type) { +func (a *Account) receiving(receivedMessage o3.Message) (xmpp.Packet, error) { + logger := log.WithFields(map[string]interface{}{ + "from": receivedMessage.Sender().String(), + "to": a.XMPP.String(), + }) + switch msg := receivedMessage.(type) { case o3.TextMessage: sender := msg.Sender().String() xMSG := xmpp.NewMessage("chat", sender, a.XMPP.String(), strconv.FormatUint(msg.ID(), 10), "en") xMSG.Body = msg.Text() requestExtensions(&xMSG) + logger.WithField("text", xMSG.Body).Debug("send text") return xMSG, nil case o3.AudioMessage: @@ -53,16 +59,17 @@ func (a *Account) receiving(receivedMessage o3.ReceivedMsg) (xmpp.Packet, error) } data, err := msg.GetAudioData(a.Session) if err != nil { - log.Warnf("unable to read data from message: %s", err) + logger.Warnf("unable to read data from message: %s", err) return nil, err } xMSG, err := a.FileToXMPP(msg.Sender().String(), msg.ID(), "mp3", data) if err != nil { - log.Warnf("unable to create data from message: %s", err) + logger.Warnf("unable to create data from message: %s", err) return nil, err } xMSG.Type = "chat" requestExtensions(&xMSG) + logger.WithField("url", xMSG.Body).Debug("send audio") return xMSG, nil case o3.ImageMessage: @@ -71,44 +78,59 @@ func (a *Account) receiving(receivedMessage o3.ReceivedMsg) (xmpp.Packet, error) } data, err := msg.GetImageData(a.Session) if err != nil { - log.Warnf("unable to read data from message: %s", err) + logger.Warnf("unable to read data from message: %s", err) return nil, err } xMSG, err := a.FileToXMPP(msg.Sender().String(), msg.ID(), "jpg", data) if err != nil { - log.Warnf("unable to create data from message: %s", err) + logger.Warnf("unable to create data from message: %s", err) return nil, err } xMSG.Type = "chat" requestExtensions(&xMSG) + logger.WithField("url", xMSG.Body).Debug("send image") return xMSG, nil case o3.DeliveryReceiptMessage: msgID := msg.MsgID() xMSG := xmpp.NewMessage("chat", msg.Sender().String(), a.XMPP.String(), "", "en") + state := "" if msg.Status() == o3.MSGDELIVERED { + state = "delivered" if id, ok := a.deliveredMSG[msgID]; ok { xMSG.Extensions = append(xMSG.Extensions, xmpp.ReceiptReceived{ID: id}) xMSG.Extensions = append(xMSG.Extensions, xmpp.MarkReceived{ID: id}) delete(a.deliveredMSG, msgID) } else { - log.Warnf("found not id in cache to announce received on xmpp side") + logger.Warnf("found not id in cache to announce received on xmpp side") } } if msg.Status() == o3.MSGREAD { + state = "displayed" if id, ok := a.readedMSG[msgID]; ok { xMSG.Extensions = append(xMSG.Extensions, xmpp.MarkDisplayed{ID: id}) delete(a.readedMSG, msgID) } else { - log.Warnf("found not id in cache to announce readed on xmpp side") + logger.Warnf("found not id in cache to announce readed on xmpp side") } } if len(xMSG.Extensions) > 0 { + logger.WithField("state", state).Debug("send state") return xMSG, nil } return nil, nil + case o3.TypingNotificationMessage: + xMSG := xmpp.NewMessage("chat", msg.Sender().String(), a.XMPP.String(), strconv.FormatUint(msg.ID(), 10), "en") + if msg.OnOff != 0 { + logger.Debug("composing") + xMSG.Extensions = append(xMSG.Extensions, xmpp.StateComposing{}) + } else { + logger.Debug("inactive") + xMSG.Extensions = append(xMSG.Extensions, xmpp.StateInactive{}) + } + return xMSG, nil } return nil, errors.New("not known data format") } diff --git a/component/threema/send.go b/component/threema/send.go index 42e9428..152d840 100644 --- a/component/threema/send.go +++ b/component/threema/send.go @@ -22,8 +22,19 @@ func (a *Account) sending(to string, msg xmpp.Message) (o3.Message, error) { // handle delivered / readed msgID := "" readed := false + composing := false + state := false for _, el := range msg.Extensions { switch ex := el.(type) { + case xmpp.StateComposing: + composing = true + state = true + case xmpp.StateInactive: + state = true + case xmpp.StateActive: + state = true + case xmpp.StateGone: + state = true case xmpp.ReceiptReceived: msgID = ex.ID case xmpp.MarkReceived: @@ -33,6 +44,12 @@ func (a *Account) sending(to string, msg xmpp.Message) (o3.Message, error) { msgID = ex.ID } } + if composing { + return nil, nil + } + if state && msg.Body == "" { + return nil, nil + } if msgID != "" { id, err := strconv.ParseUint(msgID, 10, 64) if err != nil { diff --git a/config_example.toml b/config_example.toml index 4111fdb..ab2821a 100644 --- a/config_example.toml +++ b/config_example.toml @@ -5,6 +5,7 @@ type = "threema" host = "threema.chat.sum7.eu" connection = "localhost:5347" secret = "change_me" +xmpp_log = false [component.special] http_upload_url = "https://example.org/upload/threema" diff --git a/vendor/gosrc.io/xmpp b/vendor/gosrc.io/xmpp index 5477997..1df9d46 160000 --- a/vendor/gosrc.io/xmpp +++ b/vendor/gosrc.io/xmpp @@ -1 +1 @@ -Subproject commit 5477997a38b217c86c462c8bfa8d96c3b925c1f5 +Subproject commit 1df9d46212f2d8cac64a52cc0c3779d3b774a8d6