feat: bridge XMPP mentions as proper whatsapp mentions
This has outgoing mentions of participant usernames in MUCs be correctly represented as mentions in official WhatsApp clients.
This commit is contained in:
parent
c40c9747e4
commit
6727da086a
|
@ -148,6 +148,7 @@ type Message struct {
|
|||
ReplyBody string // The full body of the message this message is in reply to, if any.
|
||||
Attachments []Attachment // The list of file (image, video, etc.) attachments contained in this message.
|
||||
Preview Preview // A short description for the URL provided in the message body, if any.
|
||||
MentionJIDs []string // A list of JIDs mentioned in this message, if any.
|
||||
}
|
||||
|
||||
// A Attachment represents additional binary data (e.g. images, videos, documents) provided alongside
|
||||
|
|
|
@ -3,6 +3,7 @@ from datetime import datetime, timezone
|
|||
from typing import TYPE_CHECKING, Optional
|
||||
|
||||
from slidge.group import LegacyBookmarks, LegacyMUC, LegacyParticipant, MucType
|
||||
from slidge.util.types import Mention
|
||||
from slixmpp.exceptions import XMPPError
|
||||
|
||||
from .generated import whatsapp
|
||||
|
@ -96,7 +97,7 @@ class MUC(LegacyMUC[str, str, Participant, str]):
|
|||
participant.role = "moderator"
|
||||
|
||||
def replace_mentions(self, t: str):
|
||||
return replace_mentions(
|
||||
return replace_whatsapp_mentions(
|
||||
t,
|
||||
participants=(
|
||||
{
|
||||
|
@ -168,10 +169,19 @@ class Bookmarks(LegacyBookmarks[str, MUC]):
|
|||
return whatsapp_group_id
|
||||
|
||||
|
||||
def replace_mentions(t: str, participants: dict[str, str]):
|
||||
def match(m: re.Match):
|
||||
mat = m.group(0)
|
||||
sub = participants.get(mat.replace("@", "+"), mat)
|
||||
return sub
|
||||
def replace_xmpp_mentions(text: str, mentions: list[Mention]):
|
||||
offset: int = 0
|
||||
result: str = ""
|
||||
for m in mentions:
|
||||
legacy_id = "@" + m.contact.legacy_id[: m.contact.legacy_id.find("@")]
|
||||
result = result + text[offset : m.start] + legacy_id
|
||||
offset = m.end
|
||||
return result + text[offset:] if offset > 0 else text
|
||||
|
||||
return re.sub(r"@\d+", match, t)
|
||||
|
||||
def replace_whatsapp_mentions(text: str, participants: dict[str, str]):
|
||||
def match(m: re.Match):
|
||||
group = m.group(0)
|
||||
return participants.get(group.replace("@", "+"), group)
|
||||
|
||||
return re.sub(r"@\d+", match, text)
|
||||
|
|
|
@ -303,6 +303,17 @@ func (s *Session) getMessagePayload(message Message) *proto.Message {
|
|||
}
|
||||
}
|
||||
|
||||
// Attach any inline mentions extended metadata.
|
||||
if len(message.MentionJIDs) > 0 {
|
||||
if payload == nil {
|
||||
payload = &proto.Message{ExtendedTextMessage: &proto.ExtendedTextMessage{Text: &message.Body}}
|
||||
}
|
||||
if payload.ExtendedTextMessage.ContextInfo == nil {
|
||||
payload.ExtendedTextMessage.ContextInfo = &proto.ContextInfo{}
|
||||
}
|
||||
payload.ExtendedTextMessage.ContextInfo.MentionedJid = message.MentionJIDs
|
||||
}
|
||||
|
||||
if payload == nil {
|
||||
payload = &proto.Message{Conversation: &message.Body}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ from slidge.contact.roster import ContactIsUser
|
|||
from slidge.util import is_valid_phone_number
|
||||
from slidge.util.types import (
|
||||
LegacyAttachment,
|
||||
Mention,
|
||||
MessageReference,
|
||||
PseudoPresenceShow,
|
||||
ResourceDict,
|
||||
|
@ -26,7 +27,7 @@ from . import config
|
|||
from .contact import Contact, Roster
|
||||
from .gateway import Gateway
|
||||
from .generated import go, whatsapp
|
||||
from .group import MUC, Bookmarks
|
||||
from .group import MUC, Bookmarks, replace_xmpp_mentions
|
||||
from .util import get_bytes_temp
|
||||
|
||||
MESSAGE_PAIR_SUCCESS = (
|
||||
|
@ -244,7 +245,7 @@ class Session(BaseSession[str, Recipient]):
|
|||
reply_to_msg_id: Optional[str] = None,
|
||||
reply_to_fallback_text: Optional[str] = None,
|
||||
reply_to=None,
|
||||
mentions=None,
|
||||
mentions: Optional[list[Mention]] = None,
|
||||
**_,
|
||||
):
|
||||
"""
|
||||
|
@ -253,7 +254,11 @@ class Session(BaseSession[str, Recipient]):
|
|||
message_id = self.whatsapp.GenerateMessageID()
|
||||
message_preview = await self.__get_preview(text) or whatsapp.Preview()
|
||||
message = whatsapp.Message(
|
||||
ID=message_id, JID=chat.legacy_id, Body=text, Preview=message_preview
|
||||
ID=message_id,
|
||||
JID=chat.legacy_id,
|
||||
Body=replace_xmpp_mentions(text, mentions) if mentions else text,
|
||||
Preview=message_preview,
|
||||
MentionJIDs=go.Slice_string([m.contact.legacy_id for m in mentions or []]),
|
||||
)
|
||||
set_reply_to(chat, message, reply_to_msg_id, reply_to_fallback_text, reply_to)
|
||||
self.whatsapp.SendMessage(message)
|
||||
|
|
|
@ -1,26 +1,29 @@
|
|||
from slidge_whatsapp.group import replace_mentions
|
||||
from slidge_whatsapp.group import replace_whatsapp_mentions
|
||||
|
||||
|
||||
def test_replace_mentions():
|
||||
def test_replace_whatsapp_mentions():
|
||||
text = "Hayo @1234, it's cool in here in with @5678!! @123333"
|
||||
|
||||
assert (
|
||||
replace_mentions(
|
||||
replace_whatsapp_mentions(
|
||||
text,
|
||||
{"+1234": "bibi", "+5678": "baba"},
|
||||
)
|
||||
== "Hayo bibi, it's cool in here in with baba!! @123333"
|
||||
)
|
||||
|
||||
assert replace_mentions(text, {}) == text
|
||||
assert replace_whatsapp_mentions(text, {}) == text
|
||||
|
||||
assert replace_mentions(text, {"+123333": "prout"}) == text.replace(
|
||||
assert replace_whatsapp_mentions(text, {"+123333": "prout"}) == text.replace(
|
||||
"@123333", "prout"
|
||||
)
|
||||
|
||||
assert replace_mentions("+1234", {"+1234": "bibi", "+5678": "baba"}) == "+1234"
|
||||
assert (
|
||||
replace_whatsapp_mentions("+1234", {"+1234": "bibi", "+5678": "baba"})
|
||||
== "+1234"
|
||||
)
|
||||
|
||||
assert (
|
||||
replace_mentions("@1234@1234@123", {"+1234": "bibi", "+5678": "baba"})
|
||||
replace_whatsapp_mentions("@1234@1234@123", {"+1234": "bibi", "+5678": "baba"})
|
||||
== "bibibibi@123"
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue