From 07f721458d83e79de384e846440cc156c773146d Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Wed, 16 Oct 2024 16:44:57 +0300 Subject: [PATCH] handlewhatsapp: implement status broadcast related config options --- pkg/connector/backfill.go | 3 +++ pkg/connector/chatinfo.go | 8 ++++++++ pkg/connector/example-config.yaml | 1 - pkg/connector/handlematrix.go | 14 ++++++++++++++ pkg/connector/handlewhatsapp.go | 6 ++++++ 5 files changed, 31 insertions(+), 1 deletion(-) diff --git a/pkg/connector/backfill.go b/pkg/connector/backfill.go index 8f42791c..12dc2107 100644 --- a/pkg/connector/backfill.go +++ b/pkg/connector/backfill.go @@ -195,6 +195,9 @@ func (wa *WhatsAppClient) createPortalsFromHistorySync(ctx context.Context) { return } for _, conv := range conversations { + if conv.ChatJID == types.StatusBroadcastJID && !wa.Main.Config.EnableStatusBroadcast { + continue + } wrappedInfo, err := wa.getChatInfo(ctx, conv.ChatJID, conv) if errors.Is(err, whatsmeow.ErrNotInGroup) { log.Debug().Stringer("chat_jid", conv.ChatJID). diff --git a/pkg/connector/chatinfo.go b/pkg/connector/chatinfo.go index d7fb5419..64f074fa 100644 --- a/pkg/connector/chatinfo.go +++ b/pkg/connector/chatinfo.go @@ -158,6 +158,13 @@ func (wa *WhatsAppClient) wrapDMInfo(jid types.JID) *bridgev2.ChatInfo { } func (wa *WhatsAppClient) wrapStatusBroadcastInfo() *bridgev2.ChatInfo { + userLocal := &bridgev2.UserLocalPortalInfo{} + if wa.Main.Config.MuteStatusBroadcast { + userLocal.MutedUntil = ptr.Ptr(event.MutedForever) + } + if wa.Main.Config.StatusBroadcastTag != "" { + userLocal.Tag = ptr.Ptr(wa.Main.Config.StatusBroadcastTag) + } return &bridgev2.ChatInfo{ Name: ptr.Ptr(StatusBroadcastName), Topic: ptr.Ptr(StatusBroadcastTopic), @@ -168,6 +175,7 @@ func (wa *WhatsAppClient) wrapStatusBroadcastInfo() *bridgev2.ChatInfo { }, }, Type: ptr.Ptr(database.RoomTypeDefault), + UserLocal: userLocal, CanBackfill: false, } } diff --git a/pkg/connector/example-config.yaml b/pkg/connector/example-config.yaml index 42439455..0e655781 100644 --- a/pkg/connector/example-config.yaml +++ b/pkg/connector/example-config.yaml @@ -28,7 +28,6 @@ identity_change_notices: false # users to see when the whatsapp user on the other side is typing during a conversation. send_presence_on_typing: false # Should WhatsApp status messages be bridged into a Matrix room? -# Disabling this won't affect already created status broadcast rooms. enable_status_broadcast: true # Should sending WhatsApp status messages be allowed? # This can cause issues if the user has lots of contacts, so it's disabled by default. diff --git a/pkg/connector/handlematrix.go b/pkg/connector/handlematrix.go index 1a486da1..0b58c6f7 100644 --- a/pkg/connector/handlematrix.go +++ b/pkg/connector/handlematrix.go @@ -2,6 +2,7 @@ package connector import ( "context" + "errors" "fmt" "time" @@ -14,6 +15,7 @@ import ( "maunium.net/go/mautrix/bridgev2" "maunium.net/go/mautrix/bridgev2/database" "maunium.net/go/mautrix/bridgev2/networkid" + "maunium.net/go/mautrix/event" "go.mau.fi/mautrix-whatsapp/pkg/waid" ) @@ -62,12 +64,18 @@ func (wa *WhatsAppClient) HandleMatrixMessage(ctx context.Context, msg *bridgev2 return wa.handleConvertedMatrixMessage(ctx, msg, waMsg) } +var ErrBroadcastSendDisabled = bridgev2.WrapErrorInStatus(errors.New("sending status messages is disabled")).WithErrorAsMessage().WithIsCertain(true).WithSendNotice(true).WithErrorReason(event.MessageStatusUnsupported) +var ErrBroadcastReactionUnsupported = bridgev2.WrapErrorInStatus(errors.New("reacting to status messages is not currently supported")).WithErrorAsMessage().WithIsCertain(true).WithSendNotice(true).WithErrorReason(event.MessageStatusUnsupported) + func (wa *WhatsAppClient) handleConvertedMatrixMessage(ctx context.Context, msg *bridgev2.MatrixMessage, waMsg *waE2E.Message) (*bridgev2.MatrixMessageResponse, error) { messageID := wa.Client.GenerateMessageID() chatJID, err := waid.ParsePortalID(msg.Portal.ID) if err != nil { return nil, err } + if chatJID == types.StatusBroadcastJID && wa.Main.Config.DisableStatusBroadcastSend { + return nil, ErrBroadcastSendDisabled + } wrappedMsgID := waid.MakeMessageID(chatJID, wa.JID, messageID) msg.AddPendingToIgnore(networkid.TransactionID(wrappedMsgID)) resp, err := wa.Client.SendMessage(ctx, chatJID, waMsg, whatsmeow.SendRequestExtra{ @@ -91,6 +99,12 @@ func (wa *WhatsAppClient) handleConvertedMatrixMessage(ctx context.Context, msg } func (wa *WhatsAppClient) PreHandleMatrixReaction(_ context.Context, msg *bridgev2.MatrixReaction) (bridgev2.MatrixReactionPreResponse, error) { + portalJID, err := waid.ParsePortalID(msg.Portal.ID) + if err != nil { + return bridgev2.MatrixReactionPreResponse{}, err + } else if portalJID == types.StatusBroadcastJID { + return bridgev2.MatrixReactionPreResponse{}, ErrBroadcastReactionUnsupported + } return bridgev2.MatrixReactionPreResponse{ SenderID: waid.MakeUserID(wa.JID), Emoji: variationselector.Remove(msg.Content.RelatesTo.Key), diff --git a/pkg/connector/handlewhatsapp.go b/pkg/connector/handlewhatsapp.go index a2c1581c..53c5d2f7 100644 --- a/pkg/connector/handlewhatsapp.go +++ b/pkg/connector/handlewhatsapp.go @@ -237,6 +237,9 @@ func (wa *WhatsAppClient) handleWAMessage(evt *events.Message) { if evt.Info.Chat.Server == types.HiddenUserServer || evt.Info.Sender.Server == types.HiddenUserServer { return } + if evt.Info.Chat == types.StatusBroadcastJID && !wa.Main.Config.EnableStatusBroadcast { + return + } parsedMessageType := getMessageType(evt.Message) if parsedMessageType == "ignore" || strings.HasPrefix(parsedMessageType, "unknown_protocol_") { return @@ -263,6 +266,9 @@ func (wa *WhatsAppClient) handleWAUndecryptableMessage(evt *events.Undecryptable if evt.DecryptFailMode == events.DecryptFailHide || evt.Info.Chat.Server == types.HiddenUserServer || evt.Info.Sender.Server == types.HiddenUserServer { return } + if evt.Info.Chat == types.StatusBroadcastJID && !wa.Main.Config.EnableStatusBroadcast { + return + } wa.Main.Bridge.QueueRemoteEvent(wa.UserLogin, &WAUndecryptableMessage{ MessageInfoWrapper: &MessageInfoWrapper{ Info: evt.Info,