diff --git a/bridge/whatsappmulti/handlers.go b/bridge/whatsappmulti/handlers.go index cd0dc8ffae..1aeafd7c6e 100644 --- a/bridge/whatsappmulti/handlers.go +++ b/bridge/whatsappmulti/handlers.go @@ -86,6 +86,12 @@ func (b *Bwhatsapp) handleTextMessage(messageInfo types.MessageInfo, msg *proto. } } + parentID := "" + if msg.GetExtendedTextMessage() != nil { + ci := msg.GetExtendedTextMessage().GetContextInfo() + parentID = getParentIdFromCtx(ci) + } + rmsg := config.Message{ UserID: senderJID.String(), Username: senderName, @@ -94,12 +100,8 @@ func (b *Bwhatsapp) handleTextMessage(messageInfo types.MessageInfo, msg *proto. Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - ID: getMessageIdFormat(senderJID.String(), messageInfo.ID), - } - - if msg.GetExtendedTextMessage() != nil { - ci := msg.GetExtendedTextMessage().GetContextInfo() - appendParentID(ci, &rmsg) + ID: getMessageIdFormat(senderJID, messageInfo.ID), + ParentID: parentID, } if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { @@ -131,11 +133,10 @@ func (b *Bwhatsapp) handleImageMessage(msg *events.Message) { Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - ID: getMessageIdFormat(senderJID.String(), msg.Info.ID), + ID: getMessageIdFormat(senderJID, msg.Info.ID), + ParentID: getParentIdFromCtx(ci), } - appendParentID(ci, &rmsg) - if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { rmsg.Avatar = avatarURL } @@ -196,11 +197,10 @@ func (b *Bwhatsapp) handleVideoMessage(msg *events.Message) { Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - ID: getMessageIdFormat(senderJID.String(), msg.Info.ID), + ID: getMessageIdFormat(senderJID, msg.Info.ID), + ParentID: getParentIdFromCtx(ci), } - appendParentID(ci, &rmsg) - if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { rmsg.Avatar = avatarURL } @@ -254,11 +254,10 @@ func (b *Bwhatsapp) handleAudioMessage(msg *events.Message) { Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - ID: getMessageIdFormat(senderJID.String(), msg.Info.ID), + ID: getMessageIdFormat(senderJID, msg.Info.ID), + ParentID: getParentIdFromCtx(ci), } - appendParentID(ci, &rmsg) - if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { rmsg.Avatar = avatarURL } @@ -313,11 +312,10 @@ func (b *Bwhatsapp) handleDocumentMessage(msg *events.Message) { Account: b.Account, Protocol: b.Protocol, Extra: make(map[string][]interface{}), - ID: getMessageIdFormat(senderJID.String(), msg.Info.ID), + ID: getMessageIdFormat(senderJID, msg.Info.ID), + ParentID: getParentIdFromCtx(ci), } - appendParentID(ci, &rmsg) - if avatarURL, exists := b.userAvatars[senderJID.String()]; exists { rmsg.Avatar = avatarURL } diff --git a/bridge/whatsappmulti/helpers.go b/bridge/whatsappmulti/helpers.go index 7c59b9a9a8..963eafa1fd 100644 --- a/bridge/whatsappmulti/helpers.go +++ b/bridge/whatsappmulti/helpers.go @@ -7,7 +7,7 @@ import ( "fmt" "strings" - "github.com/42wim/matterbridge/bridge/config" + goproto "google.golang.org/protobuf/proto" "go.mau.fi/whatsmeow" "go.mau.fi/whatsmeow/binary/proto" @@ -126,12 +126,21 @@ func (b *Bwhatsapp) getDevice() (*store.Device, error) { return device, nil } -func appendParentID(ci *proto.ContextInfo, rmsg *config.Message) { +func (b *Bwhatsapp) getNewReplyContext(parentID string) (*proto.ContextInfo, error) { + replyInfo, err := b.parseMessageID(parentID) - if ci != nil && ci.StanzaId != nil { - // rmsg.ParentID = *ci.StanzaId - rmsg.ParentID = getMessageIdFormat(*ci.Participant, *ci.StanzaId) + if err != nil { + return nil, err + } + + sender := fmt.Sprintf("%s@%s", replyInfo.Sender.User, replyInfo.Sender.Server) + ctx := &proto.ContextInfo{ + StanzaId: &replyInfo.MessageID, + Participant: &sender, + QuotedMessage: &proto.Message{Conversation: goproto.String("")}, } + + return ctx, nil } func (b *Bwhatsapp) parseMessageID(id string) (*Replyable, error) { @@ -159,6 +168,20 @@ func (b *Bwhatsapp) parseMessageID(id string) (*Replyable, error) { return &Replyable{MessageID: id}, err } -func getMessageIdFormat(authorJID string, messageID string) string { - return fmt.Sprintf("%s/%s", authorJID, messageID) +func getParentIdFromCtx(ci *proto.ContextInfo) string { + if ci != nil && ci.StanzaId != nil { + senderJid, err := types.ParseJID(*ci.Participant) + + if err == nil { + return getMessageIdFormat(senderJid, *ci.StanzaId) + } + } + + return "" +} + +func getMessageIdFormat(jid types.JID, messageID string) string { + // we're crafting our own JID str as AD JID format messes with how stuff looks on a webclient + jidStr := fmt.Sprintf("%s@%s", jid.User, jid.Server) + return fmt.Sprintf("%s/%s", jidStr, messageID) } diff --git a/bridge/whatsappmulti/whatsapp.go b/bridge/whatsappmulti/whatsapp.go index c403be1623..6798d827eb 100644 --- a/bridge/whatsappmulti/whatsapp.go +++ b/bridge/whatsappmulti/whatsapp.go @@ -227,6 +227,10 @@ func (b *Bwhatsapp) PostDocumentMessage(msg config.Message, filetype string) (st // Post document message var message proto.Message + var ctx *proto.ContextInfo + if msg.ParentID != "" { + ctx, _ = b.getNewReplyContext(msg.ParentID) + } message.DocumentMessage = &proto.DocumentMessage{ Title: &fi.Name, @@ -238,6 +242,7 @@ func (b *Bwhatsapp) PostDocumentMessage(msg config.Message, filetype string) (st FileSha256: resp.FileSHA256, FileLength: goproto.Uint64(resp.FileLength), Url: &resp.URL, + ContextInfo: ctx, } b.Log.Debugf("=> Sending %#v as a document", msg) @@ -261,6 +266,10 @@ func (b *Bwhatsapp) PostImageMessage(msg config.Message, filetype string) (strin } var message proto.Message + var ctx *proto.ContextInfo + if msg.ParentID != "" { + ctx, _ = b.getNewReplyContext(msg.ParentID) + } message.ImageMessage = &proto.ImageMessage{ Mimetype: &filetype, @@ -270,6 +279,7 @@ func (b *Bwhatsapp) PostImageMessage(msg config.Message, filetype string) (strin FileSha256: resp.FileSHA256, FileLength: goproto.Uint64(resp.FileLength), Url: &resp.URL, + ContextInfo: ctx, } b.Log.Debugf("=> Sending %#v as an image", msg) @@ -289,6 +299,10 @@ func (b *Bwhatsapp) PostVideoMessage(msg config.Message, filetype string) (strin } var message proto.Message + var ctx *proto.ContextInfo + if msg.ParentID != "" { + ctx, _ = b.getNewReplyContext(msg.ParentID) + } message.VideoMessage = &proto.VideoMessage{ Mimetype: &filetype, @@ -298,6 +312,7 @@ func (b *Bwhatsapp) PostVideoMessage(msg config.Message, filetype string) (strin FileSha256: resp.FileSHA256, FileLength: goproto.Uint64(resp.FileLength), Url: &resp.URL, + ContextInfo: ctx, } b.Log.Debugf("=> Sending %#v as a video", msg) @@ -317,6 +332,10 @@ func (b *Bwhatsapp) PostAudioMessage(msg config.Message, filetype string) (strin } var message proto.Message + var ctx *proto.ContextInfo + if msg.ParentID != "" { + ctx, _ = b.getNewReplyContext(msg.ParentID) + } message.AudioMessage = &proto.AudioMessage{ Mimetype: &filetype, @@ -325,6 +344,7 @@ func (b *Bwhatsapp) PostAudioMessage(msg config.Message, filetype string) (strin FileSha256: resp.FileSHA256, FileLength: goproto.Uint64(resp.FileLength), Url: &resp.URL, + ContextInfo: ctx, } b.Log.Debugf("=> Sending %#v as audio", msg) @@ -341,39 +361,6 @@ func (b *Bwhatsapp) PostAudioMessage(msg config.Message, filetype string) (strin return ID, err } -func (b *Bwhatsapp) sendMessage(rmsg config.Message, message *proto.Message) (string, error) { - groupJID, _ := types.ParseJID(rmsg.Channel) - ID := whatsmeow.GenerateMessageID() - text := rmsg.Username + rmsg.Text - - // If we have a parent ID send an extended message - if rmsg.ParentID != "" { - replyInfo, err := b.parseMessageID(rmsg.ParentID) - - if err == nil { - sender := replyInfo.Sender.String() - - // append reply info - message.ExtendedTextMessage = &proto.ExtendedTextMessage{ - Text: &text, - ContextInfo: &proto.ContextInfo{ - StanzaId: &replyInfo.MessageID, - Participant: &sender, - QuotedMessage: &proto.Message{Conversation: goproto.String("")}, - }, - } - - _, err := b.wc.SendMessage(context.Background(), groupJID, message, whatsmeow.SendRequestExtra{ID: ID}) - - return getMessageIdFormat(b.Config.GetString("Number")[1:]+"@s.whatsapp.net", ID), err - } - } - - _, err := b.wc.SendMessage(context.TODO(), groupJID, message, whatsmeow.SendRequestExtra{ID: ID}) - - return getMessageIdFormat(b.Config.GetString("Number")[1:]+"@s.whatsapp.net", ID), err -} - // Send a message from the bridge to WhatsApp func (b *Bwhatsapp) Send(msg config.Message) (string, error) { groupJID, _ := types.ParseJID(msg.Channel) @@ -430,11 +417,35 @@ func (b *Bwhatsapp) Send(msg config.Message) (string, error) { } } + var message proto.Message text := msg.Username + msg.Text - var message proto.Message + // If we have a parent ID send an extended message + if msg.ParentID != "" { + replyContext, err := b.getNewReplyContext(msg.ParentID) + + if err == nil { + message = proto.Message{ + ExtendedTextMessage: &proto.ExtendedTextMessage{ + Text: &text, + ContextInfo: replyContext, + }, + } + + return b.sendMessage(msg, &message) + } + } message.Conversation = &text return b.sendMessage(msg, &message) } + +func (b *Bwhatsapp) sendMessage(rmsg config.Message, message *proto.Message) (string, error) { + groupJID, _ := types.ParseJID(rmsg.Channel) + ID := whatsmeow.GenerateMessageID() + + _, err := b.wc.SendMessage(context.Background(), groupJID, message, whatsmeow.SendRequestExtra{ID: ID}) + + return getMessageIdFormat(*b.wc.Store.ID, ID), err +}