Fix replies.

Sender JID can have a `:` inside of it, using `/` as a delimiter now.
Added messageID parser + struct.
messages sent with an attachment do not show replies
But at least common `sendMessage` will make repies from whatsapp to an attachement bridge across.

The new message ID format broke message deleting, so we change the messageID into the real id at the beginning of send.
We really do need the extra info for when we reply to a message though.
This commit is contained in:
Yousef Mansy
2023-02-23 03:19:04 -08:00
parent 39f909b28e
commit cffa6d3240
2 changed files with 72 additions and 52 deletions

View File

@@ -134,6 +134,31 @@ func appendParentID(ci *proto.ContextInfo, rmsg *config.Message) {
}
}
func getMessageIdFormat(authorJID string, messageID string) string {
return fmt.Sprintf("%s:%s", authorJID, messageID)
func (b *Bwhatsapp) parseMessageID(id string) (*Replyable, error) {
// No message ID in case action is executed on a message sent before the bridge was started
// and then the bridge cache doesn't have this message ID mapped
if id == "" {
return &Replyable{MessageID: id}, nil
}
replyInfo := strings.Split(id, "/")
if len(replyInfo) == 2 {
sender, err := types.ParseJID(replyInfo[0])
if err == nil {
return &Replyable{
MessageID: types.MessageID(replyInfo[1]),
Sender: sender,
}, nil
}
}
err := fmt.Errorf("MessageID does not match format of {senderJID}:{messageID} : \"%s\"", id)
return &Replyable{MessageID: id}, err
}
func getMessageIdFormat(authorJID string, messageID string) string {
return fmt.Sprintf("%s/%s", authorJID, messageID)
}

View File

@@ -10,7 +10,6 @@ import (
"mime"
"os"
"path/filepath"
"strings"
"time"
"github.com/42wim/matterbridge/bridge"
@@ -43,6 +42,11 @@ type Bwhatsapp struct {
userAvatars map[string]string
}
type Replyable struct {
MessageID types.MessageID
Sender types.JID
}
// New Create a new WhatsApp bridge. This will be called for each [whatsapp.<server>] entry you have in the config file
func New(cfg *bridge.Config) bridge.Bridger {
number := cfg.GetString(cfgNumber)
@@ -247,8 +251,6 @@ func (b *Bwhatsapp) PostDocumentMessage(msg config.Message, filetype string) (st
// Post an image message from the bridge to WhatsApp
// Handle, for sure image/jpeg, image/png and image/gif MIME types
func (b *Bwhatsapp) PostImageMessage(msg config.Message, filetype string) (string, error) {
groupJID, _ := types.ParseJID(msg.Channel)
fi := msg.Extra["file"][0].(config.FileInfo)
caption := msg.Username + fi.Comment
@@ -272,16 +274,11 @@ func (b *Bwhatsapp) PostImageMessage(msg config.Message, filetype string) (strin
b.Log.Debugf("=> Sending %#v as an image", msg)
ID := whatsmeow.GenerateMessageID()
_, err = b.wc.SendMessage(context.TODO(), groupJID, &message, whatsmeow.SendRequestExtra{ID: ID})
return ID, err
return b.sendMessage(msg, &message)
}
// Post a video message from the bridge to WhatsApp
func (b *Bwhatsapp) PostVideoMessage(msg config.Message, filetype string) (string, error) {
groupJID, _ := types.ParseJID(msg.Channel)
fi := msg.Extra["file"][0].(config.FileInfo)
caption := msg.Username + fi.Comment
@@ -305,10 +302,7 @@ func (b *Bwhatsapp) PostVideoMessage(msg config.Message, filetype string) (strin
b.Log.Debugf("=> Sending %#v as a video", msg)
ID := whatsmeow.GenerateMessageID()
_, err = b.wc.SendMessage(context.TODO(), groupJID, &message, whatsmeow.SendRequestExtra{ID: ID})
return ID, err
return b.sendMessage(msg, &message)
}
// Post audio inline
@@ -335,8 +329,7 @@ func (b *Bwhatsapp) PostAudioMessage(msg config.Message, filetype string) (strin
b.Log.Debugf("=> Sending %#v as audio", msg)
ID := whatsmeow.GenerateMessageID()
_, err = b.wc.SendMessage(context.TODO(), groupJID, &message, whatsmeow.SendRequestExtra{ID: ID})
ID, err := b.sendMessage(msg, &message)
var captionMessage proto.Message
caption := msg.Username + fi.Comment + "\u2B06" // the char on the end is upwards arrow emoji
@@ -348,10 +341,46 @@ 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)
extendedMsgID, _ := b.parseMessageID(msg.ID)
msg.ID = extendedMsgID.MessageID
b.Log.Debugf("=> Receiving %#v", msg)
// Delete message
@@ -403,43 +432,9 @@ func (b *Bwhatsapp) Send(msg config.Message) (string, error) {
text := msg.Username + msg.Text
ID := whatsmeow.GenerateMessageID()
// If we have a parent ID send an extended message
if msg.ParentID != "" {
// in appendParentID() we combine the "Participant" and the "StanzaID" as both are needed to send a reply
replyInfo := strings.Split(msg.ParentID, ":")
if len(replyInfo) != 2 {
b.Log.Debug("Malformed reply info to whatsapp: %s", msg.ParentID)
} else {
// Send message with reply (not working)
// https://github.com/tulir/whatsmeow/issues/88#issuecomment-1093195237
_, err := b.wc.SendMessage(
context.Background(),
groupJID,
&proto.Message{
ExtendedTextMessage: &proto.ExtendedTextMessage{
Text: &text,
ContextInfo: &proto.ContextInfo{
StanzaId: &replyInfo[1],
Participant: &replyInfo[0],
QuotedMessage: &proto.Message{Conversation: goproto.String("")},
},
},
},
whatsmeow.SendRequestExtra{ID: ID},
)
return getMessageIdFormat(b.Config.GetString("Number")[1:]+"@s.whatsapp.net", ID), err
}
}
var message proto.Message
message.Conversation = &text
_, err := b.wc.SendMessage(context.TODO(), groupJID, &message, whatsmeow.SendRequestExtra{ID: ID})
return getMessageIdFormat(b.Config.GetString("Number")[1:]+"@s.whatsapp.net", ID), err
return b.sendMessage(msg, &message)
}