Merge pull request 'debug none sender uuid' (#4) from feature/remove-system-message into master
Reviewed-on: #4
This commit is contained in:
commit
c39bda076e
4 changed files with 28 additions and 25 deletions
|
|
@ -156,9 +156,14 @@ class MattermostClient:
|
||||||
|
|
||||||
return channel_id
|
return channel_id
|
||||||
|
|
||||||
def post_message(self, channel_id: str, message: str) -> str:
|
def post_message(self, channel_id: str, message: str, sender_uuid: UUID) -> str:
|
||||||
"""
|
"""
|
||||||
Post a message to the given channel using the admin token.
|
Post a message to the given channel using the admin token.
|
||||||
|
|
||||||
|
Every post is authored by the single service account, not the real
|
||||||
|
sender — there are no per-user tokens. `sender_uuid` is stamped into
|
||||||
|
the post's `props` so it can be recovered later in `get_posts()`;
|
||||||
|
Mattermost's own `user_id` on the post is always the service account.
|
||||||
Returns the opaque mattermost_post_id string.
|
Returns the opaque mattermost_post_id string.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
@ -166,6 +171,7 @@ class MattermostClient:
|
||||||
options={
|
options={
|
||||||
"channel_id": channel_id,
|
"channel_id": channel_id,
|
||||||
"message": message,
|
"message": message,
|
||||||
|
"props": {"sender_uuid": str(sender_uuid)},
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return post["id"]
|
return post["id"]
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ from apps.chat.events.publishers.push import PushPublisher
|
||||||
from apps.chat.events.publishers.websocket import WebSocketPublisher
|
from apps.chat.events.publishers.websocket import WebSocketPublisher
|
||||||
from apps.chat.exceptions import ConversationClosedError
|
from apps.chat.exceptions import ConversationClosedError
|
||||||
from apps.chat.integrations.mattermost.client import MattermostClient
|
from apps.chat.integrations.mattermost.client import MattermostClient
|
||||||
from apps.chat.models import Conversation, ConversationStatus, MattermostAccountMapping
|
from apps.chat.models import Conversation, ConversationStatus
|
||||||
from apps.chat.services.account import AccountService
|
from apps.chat.services.account import AccountService
|
||||||
from apps.chat.services.storage import StorageService
|
from apps.chat.services.storage import StorageService
|
||||||
|
|
||||||
|
|
@ -62,7 +62,9 @@ class MessageService:
|
||||||
else:
|
else:
|
||||||
mm_message = text or ""
|
mm_message = text or ""
|
||||||
|
|
||||||
post_id = self._mm.post_message(conversation.mattermost_channel_id, mm_message)
|
post_id = self._mm.post_message(
|
||||||
|
conversation.mattermost_channel_id, mm_message, sender_uuid
|
||||||
|
)
|
||||||
|
|
||||||
event = MessageSentEvent(
|
event = MessageSentEvent(
|
||||||
chat_uuid=conversation_uuid,
|
chat_uuid=conversation_uuid,
|
||||||
|
|
@ -99,19 +101,14 @@ class MessageService:
|
||||||
since=since,
|
since=since,
|
||||||
)
|
)
|
||||||
|
|
||||||
mm_user_ids = {p["user_id"] for p in raw_posts if p.get("user_id")}
|
return [self._normalize_post(p) for p in raw_posts]
|
||||||
mappings = {
|
|
||||||
m.mattermost_user_id: m.user_uuid
|
|
||||||
for m in MattermostAccountMapping.objects.filter(
|
|
||||||
mattermost_user_id__in=mm_user_ids
|
|
||||||
)
|
|
||||||
} if mm_user_ids else {}
|
|
||||||
|
|
||||||
return [self._normalize_post(p, mappings) for p in raw_posts]
|
def _normalize_post(self, post: dict) -> dict:
|
||||||
|
sender_uuid_raw = (post.get("props") or {}).get("sender_uuid")
|
||||||
def _normalize_post(self, post: dict, mappings: dict) -> dict:
|
try:
|
||||||
mm_uid = post.get("user_id")
|
sender_uuid = UUID(sender_uuid_raw) if sender_uuid_raw else None
|
||||||
sender_uuid = mappings.get(mm_uid)
|
except ValueError:
|
||||||
|
sender_uuid = None
|
||||||
msg = post.get("message", "")
|
msg = post.get("message", "")
|
||||||
created_ms = post.get("create_at")
|
created_ms = post.get("create_at")
|
||||||
created_at = (
|
created_at = (
|
||||||
|
|
|
||||||
|
|
@ -109,4 +109,4 @@ def test_send_message_after_reopen_succeeds():
|
||||||
result = svc.send(conv.uuid, sender_uuid, "text", text="hello again")
|
result = svc.send(conv.uuid, sender_uuid, "text", text="hello again")
|
||||||
|
|
||||||
assert result["post_id"] == "post-1"
|
assert result["post_id"] == "post-1"
|
||||||
mm_client.post_message.assert_called_once_with("ch-close", "hello again")
|
mm_client.post_message.assert_called_once_with("ch-close", "hello again", sender_uuid)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ from unittest.mock import Mock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from apps.chat.models import Conversation, MattermostAccountMapping
|
from apps.chat.models import Conversation
|
||||||
from apps.chat.services.message import MessageService
|
from apps.chat.services.message import MessageService
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -36,7 +36,7 @@ def test_send_text_message():
|
||||||
|
|
||||||
result = svc.send(conv.uuid, sender_uuid, "text", text="Hello world")
|
result = svc.send(conv.uuid, sender_uuid, "text", text="Hello world")
|
||||||
|
|
||||||
mm_client.post_message.assert_called_once_with("ch-send-text", "Hello world")
|
mm_client.post_message.assert_called_once_with("ch-send-text", "Hello world", sender_uuid)
|
||||||
storage.get_download_url.assert_not_called()
|
storage.get_download_url.assert_not_called()
|
||||||
ws_publisher.publish.assert_called_once()
|
ws_publisher.publish.assert_called_once()
|
||||||
|
|
||||||
|
|
@ -62,7 +62,9 @@ def test_send_image_message():
|
||||||
result = svc.send(conv.uuid, sender_uuid, "image", object_key=object_key)
|
result = svc.send(conv.uuid, sender_uuid, "image", object_key=object_key)
|
||||||
|
|
||||||
storage.get_download_url.assert_called_once_with(object_key)
|
storage.get_download_url.assert_called_once_with(object_key)
|
||||||
mm_client.post_message.assert_called_once_with("ch-send-image", f"image:{object_key}")
|
mm_client.post_message.assert_called_once_with(
|
||||||
|
"ch-send-image", f"image:{object_key}", sender_uuid
|
||||||
|
)
|
||||||
assert result["url"] == download_url
|
assert result["url"] == download_url
|
||||||
assert result["message_type"] == "image"
|
assert result["message_type"] == "image"
|
||||||
|
|
||||||
|
|
@ -71,11 +73,7 @@ def test_send_image_message():
|
||||||
def test_list_messages_normalized():
|
def test_list_messages_normalized():
|
||||||
conv = Conversation.objects.create(mattermost_channel_id="ch-list")
|
conv = Conversation.objects.create(mattermost_channel_id="ch-list")
|
||||||
sender_uuid = uuid.uuid4()
|
sender_uuid = uuid.uuid4()
|
||||||
mm_user_id = "mm-user-xyz"
|
mm_user_id = "mm-service-bot" # every post is authored by the service account
|
||||||
|
|
||||||
MattermostAccountMapping.objects.create(
|
|
||||||
user_uuid=sender_uuid, mattermost_user_id=mm_user_id
|
|
||||||
)
|
|
||||||
|
|
||||||
object_key = "voice/def456/clip.ogg"
|
object_key = "voice/def456/clip.ogg"
|
||||||
raw_posts = [
|
raw_posts = [
|
||||||
|
|
@ -83,12 +81,14 @@ def test_list_messages_normalized():
|
||||||
"id": "p1",
|
"id": "p1",
|
||||||
"user_id": mm_user_id,
|
"user_id": mm_user_id,
|
||||||
"message": "First message",
|
"message": "First message",
|
||||||
|
"props": {"sender_uuid": str(sender_uuid)},
|
||||||
"create_at": 1700000000000,
|
"create_at": 1700000000000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "p2",
|
"id": "p2",
|
||||||
"user_id": mm_user_id,
|
"user_id": mm_user_id,
|
||||||
"message": f"voice:{object_key}",
|
"message": f"voice:{object_key}",
|
||||||
|
"props": {"sender_uuid": str(sender_uuid)},
|
||||||
"create_at": 1700000001000,
|
"create_at": 1700000001000,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
@ -130,7 +130,7 @@ def test_list_messages_normalized():
|
||||||
|
|
||||||
system_msg = messages[2]
|
system_msg = messages[2]
|
||||||
assert system_msg["post_id"] == "sys1"
|
assert system_msg["post_id"] == "sys1"
|
||||||
assert system_msg["sender_uuid"] == sender_uuid
|
assert system_msg["sender_uuid"] is None
|
||||||
assert system_msg["mattermost_message_type"] == "system_add_to_channel"
|
assert system_msg["mattermost_message_type"] == "system_add_to_channel"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue