diff --git a/ROADMAP.md b/ROADMAP.md index 7ad6414..17314fe 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -26,8 +26,8 @@ * [x] Media/files * [ ] Message deletions * [x] Avatars - * [ ] Presence - * [ ] Typing notifications + * [x] Presence + * [x] Typing notifications * [x] Read receipts * [ ] Admin/superadmin status * [ ] Membership actions diff --git a/puppet.go b/puppet.go index 2bcd86e..8058fa1 100644 --- a/puppet.go +++ b/puppet.go @@ -132,6 +132,8 @@ type Puppet struct { bridge *Bridge log log.Logger + typingIn types.MatrixRoomID + MXID types.MatrixUserID } diff --git a/user.go b/user.go index 88c09ce..1c96f86 100644 --- a/user.go +++ b/user.go @@ -261,6 +261,25 @@ func (user *User) HandleConnInfo(info whatsapp_ext.ConnInfo) { } } +func (user *User) HandlePresence(info whatsapp_ext.Presence) { + puppet := user.GetPuppetByJID(info.SenderJID) + switch info.Status { + case whatsapp_ext.PresenceUnavailable: + puppet.Intent().SetPresence("offline") + case whatsapp_ext.PresenceAvailable: + if len(puppet.typingIn) > 0 { + puppet.Intent().UserTyping(puppet.typingIn, false, 0) + puppet.typingIn = "" + } else { + puppet.Intent().SetPresence("online") + } + case whatsapp_ext.PresenceComposing: + portal := user.GetPortalByJID(info.JID) + puppet.typingIn = portal.MXID + puppet.Intent().UserTyping(portal.MXID, true, 15 * 1000) + } +} + func (user *User) HandleMsgInfo(info whatsapp_ext.MsgInfo) { if (info.Command == whatsapp_ext.MsgInfoCommandAck || info.Command == whatsapp_ext.MsgInfoCommandAcks) && info.Acknowledgement == whatsapp_ext.AckMessageRead { portal := user.GetPortalByJID(info.ToJID) diff --git a/whatsapp-ext/presence.go b/whatsapp-ext/presence.go index 2659f50..2248697 100644 --- a/whatsapp-ext/presence.go +++ b/whatsapp-ext/presence.go @@ -17,9 +17,10 @@ package whatsapp_ext import ( - "github.com/Rhymen/go-whatsapp" "encoding/json" "strings" + + "github.com/Rhymen/go-whatsapp" ) type PresenceType string @@ -27,12 +28,15 @@ type PresenceType string const ( PresenceUnavailable PresenceType = "unavailable" PresenceAvailable PresenceType = "available" + PresenceComposing PresenceType = "composing" ) type Presence struct { JID string `json:"id"` + SenderJID string `json:"participant"` Status PresenceType `json:"type"` Timestamp int64 `json:"t"` + Deny bool `json:"deny"` } type PresenceHandler interface { @@ -48,6 +52,11 @@ func (ext *ExtendedConn) handleMessagePresence(message []byte) { return } event.JID = strings.Replace(event.JID, OldUserSuffix, NewUserSuffix, 1) + if len(event.SenderJID) == 0 { + event.SenderJID = event.JID + } else { + event.SenderJID = strings.Replace(event.SenderJID, OldUserSuffix, NewUserSuffix, 1) + } for _, handler := range ext.handlers { presenceHandler, ok := handler.(PresenceHandler) if !ok {