Add support for multi-contact messages

This commit is contained in:
Tulir Asokan 2022-01-03 16:11:39 +02:00
parent 5ff09b9041
commit e2b0879f16
3 changed files with 52 additions and 2 deletions

View file

@ -4,6 +4,7 @@
* Added overrides for mime type -> file extension mapping as some OSes have * Added overrides for mime type -> file extension mapping as some OSes have
very obscure extensions in their mime type database. very obscure extensions in their mime type database.
* Added support for personal filtering spaces (started by [@HelderFSFerreira] and [@clmnin] in [#413]). * Added support for personal filtering spaces (started by [@HelderFSFerreira] and [@clmnin] in [#413]).
* Added support for multi-contact messages.
* Fixed avatar remove events from WhatsApp being ignored. * Fixed avatar remove events from WhatsApp being ignored.
* Fixed the bridge using the wrong Olm session if a client established a new * Fixed the bridge using the wrong Olm session if a client established a new
one due to corruption. one due to corruption.

View file

@ -23,6 +23,7 @@ import (
waProto "go.mau.fi/whatsmeow/binary/proto" waProto "go.mau.fi/whatsmeow/binary/proto"
"go.mau.fi/whatsmeow/types" "go.mau.fi/whatsmeow/types"
"maunium.net/go/mautrix" "maunium.net/go/mautrix"
"maunium.net/go/mautrix/appservice" "maunium.net/go/mautrix/appservice"
"maunium.net/go/mautrix/event" "maunium.net/go/mautrix/event"
@ -509,6 +510,16 @@ func (portal *Portal) appendBatchEvents(converted *ConvertedMessage, info *types
*eventsArray = append(*eventsArray, mainEvt) *eventsArray = append(*eventsArray, mainEvt)
*infoArray = append(*infoArray, info) *infoArray = append(*infoArray, info)
} }
if converted.MultiEvent != nil {
for _, subEvtContent := range converted.MultiEvent {
subEvt, err := portal.wrapBatchEvent(info, converted.Intent, converted.Type, subEvtContent, nil)
if err != nil {
return err
}
*eventsArray = append(*eventsArray, subEvt)
*infoArray = append(*infoArray, nil)
}
}
return nil return nil
} }

View file

@ -267,7 +267,7 @@ func containsSupportedMessage(waMsg *waProto.Message) bool {
return waMsg.Conversation != nil || waMsg.ExtendedTextMessage != nil || waMsg.ImageMessage != nil || return waMsg.Conversation != nil || waMsg.ExtendedTextMessage != nil || waMsg.ImageMessage != nil ||
waMsg.StickerMessage != nil || waMsg.AudioMessage != nil || waMsg.VideoMessage != nil || waMsg.StickerMessage != nil || waMsg.AudioMessage != nil || waMsg.VideoMessage != nil ||
waMsg.DocumentMessage != nil || waMsg.ContactMessage != nil || waMsg.LocationMessage != nil || waMsg.DocumentMessage != nil || waMsg.ContactMessage != nil || waMsg.LocationMessage != nil ||
waMsg.LiveLocationMessage != nil || waMsg.GroupInviteMessage != nil waMsg.LiveLocationMessage != nil || waMsg.GroupInviteMessage != nil || waMsg.ContactsArrayMessage != nil
} }
func isPotentiallyInteresting(waMsg *waProto.Message) bool { func isPotentiallyInteresting(waMsg *waProto.Message) bool {
@ -276,7 +276,7 @@ func isPotentiallyInteresting(waMsg *waProto.Message) bool {
} }
// List of message types that aren't supported, but might potentially be interesting // List of message types that aren't supported, but might potentially be interesting
// (so a warning should be logged if they are encountered). // (so a warning should be logged if they are encountered).
return waMsg.Call != nil || waMsg.Chat != nil || waMsg.ContactsArrayMessage != nil || return waMsg.Call != nil || waMsg.Chat != nil ||
waMsg.HighlyStructuredMessage != nil || waMsg.SendPaymentMessage != nil || waMsg.LiveLocationMessage != nil || waMsg.HighlyStructuredMessage != nil || waMsg.SendPaymentMessage != nil || waMsg.LiveLocationMessage != nil ||
waMsg.RequestPaymentMessage != nil || waMsg.DeclinePaymentRequestMessage != nil || waMsg.RequestPaymentMessage != nil || waMsg.DeclinePaymentRequestMessage != nil ||
waMsg.CancelPaymentRequestMessage != nil || waMsg.TemplateMessage != nil || waMsg.CancelPaymentRequestMessage != nil || waMsg.TemplateMessage != nil ||
@ -304,6 +304,8 @@ func getMessageType(waMsg *waProto.Message) string {
return fmt.Sprintf("document %s", waMsg.GetDocumentMessage().GetMimetype()) return fmt.Sprintf("document %s", waMsg.GetDocumentMessage().GetMimetype())
case waMsg.ContactMessage != nil: case waMsg.ContactMessage != nil:
return "contact" return "contact"
case waMsg.ContactsArrayMessage != nil:
return "contact array"
case waMsg.LocationMessage != nil: case waMsg.LocationMessage != nil:
return "location" return "location"
case waMsg.LiveLocationMessage != nil: case waMsg.LiveLocationMessage != nil:
@ -342,6 +344,8 @@ func (portal *Portal) convertMessage(intent *appservice.IntentAPI, source *User,
return portal.convertMediaMessage(intent, source, info, waMsg.GetDocumentMessage()) return portal.convertMediaMessage(intent, source, info, waMsg.GetDocumentMessage())
case waMsg.ContactMessage != nil: case waMsg.ContactMessage != nil:
return portal.convertContactMessage(intent, waMsg.GetContactMessage()) return portal.convertContactMessage(intent, waMsg.GetContactMessage())
case waMsg.ContactsArrayMessage != nil:
return portal.convertContactsArrayMessage(intent, waMsg.GetContactsArrayMessage())
case waMsg.LocationMessage != nil: case waMsg.LocationMessage != nil:
return portal.convertLocationMessage(intent, waMsg.GetLocationMessage()) return portal.convertLocationMessage(intent, waMsg.GetLocationMessage())
case waMsg.LiveLocationMessage != nil: case waMsg.LiveLocationMessage != nil:
@ -478,6 +482,14 @@ func (portal *Portal) handleMessage(source *User, evt *events.Message) {
eventID = resp.EventID eventID = resp.EventID
} }
} }
if converted.MultiEvent != nil && existingMsg == nil {
for index, subEvt := range converted.MultiEvent {
resp, err = portal.sendMessage(converted.Intent, converted.Type, subEvt, nil, evt.Info.Timestamp.UnixMilli())
if err != nil {
portal.log.Errorfln("Failed to send sub-event %d of %s to Matrix: %v", index+1, msgID, err)
}
}
}
if len(eventID) != 0 { if len(eventID) != 0 {
portal.finishHandling(existingMsg, &evt.Info, resp.EventID, false) portal.finishHandling(existingMsg, &evt.Info, resp.EventID, false)
} }
@ -1302,6 +1314,8 @@ type ConvertedMessage struct {
Extra map[string]interface{} Extra map[string]interface{}
Caption *event.MessageEventContent Caption *event.MessageEventContent
MultiEvent []*event.MessageEventContent
ReplyTo types.MessageID ReplyTo types.MessageID
} }
@ -1455,6 +1469,30 @@ func (portal *Portal) convertContactMessage(intent *appservice.IntentAPI, msg *w
} }
} }
func (portal *Portal) convertContactsArrayMessage(intent *appservice.IntentAPI, msg *waProto.ContactsArrayMessage) *ConvertedMessage {
name := msg.GetDisplayName()
if len(name) == 0 {
name = fmt.Sprintf("%d contacts", len(msg.GetContacts()))
}
contacts := make([]*event.MessageEventContent, 0, len(msg.GetContacts()))
for _, contact := range msg.GetContacts() {
converted := portal.convertContactMessage(intent, contact)
if converted != nil {
contacts = append(contacts, converted.Content)
}
}
return &ConvertedMessage{
Intent: intent,
Type: event.EventMessage,
Content: &event.MessageEventContent{
MsgType: event.MsgNotice,
Body: fmt.Sprintf("Sent %s", name),
},
ReplyTo: msg.GetContextInfo().GetStanzaId(),
MultiEvent: contacts,
}
}
func (portal *Portal) tryKickUser(userID id.UserID, intent *appservice.IntentAPI) error { func (portal *Portal) tryKickUser(userID id.UserID, intent *appservice.IntentAPI) error {
_, err := intent.KickUser(portal.MXID, &mautrix.ReqKickUser{UserID: userID}) _, err := intent.KickUser(portal.MXID, &mautrix.ReqKickUser{UserID: userID})
if err != nil { if err != nil {