feat: add reply/forward/pin message flow across backend and web
Some checks failed
CI / test (push) Failing after 24s
Some checks failed
CI / test (push) Failing after 24s
- add reply_to/forwarded_from message fields and chat pinned_message field - add forward and pin APIs plus reply support in message create - wire web actions: Reply, Fwd, Pin and reply composer state - fix spam policy bug: allow repeated identical messages, keep rate limiting
This commit is contained in:
@@ -6,12 +6,16 @@ from app.chats.service import ensure_chat_membership
|
||||
from app.messages import repository
|
||||
from app.messages.models import Message
|
||||
from app.messages.spam_guard import enforce_message_spam_policy
|
||||
from app.messages.schemas import MessageCreateRequest, MessageStatusUpdateRequest, MessageUpdateRequest
|
||||
from app.messages.schemas import MessageCreateRequest, MessageForwardRequest, MessageStatusUpdateRequest, MessageUpdateRequest
|
||||
from app.notifications.service import dispatch_message_notifications
|
||||
|
||||
|
||||
async def create_chat_message(db: AsyncSession, *, sender_id: int, payload: MessageCreateRequest) -> Message:
|
||||
await ensure_chat_membership(db, chat_id=payload.chat_id, user_id=sender_id)
|
||||
if payload.reply_to_message_id is not None:
|
||||
reply_to = await repository.get_message_by_id(db, payload.reply_to_message_id)
|
||||
if not reply_to or reply_to.chat_id != payload.chat_id:
|
||||
raise HTTPException(status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, detail="Invalid reply target")
|
||||
if payload.client_message_id:
|
||||
existing = await repository.get_message_by_client_message_id(
|
||||
db,
|
||||
@@ -30,6 +34,8 @@ async def create_chat_message(db: AsyncSession, *, sender_id: int, payload: Mess
|
||||
db,
|
||||
chat_id=payload.chat_id,
|
||||
sender_id=sender_id,
|
||||
reply_to_message_id=payload.reply_to_message_id,
|
||||
forwarded_from_message_id=None,
|
||||
message_type=payload.type,
|
||||
text=payload.text,
|
||||
)
|
||||
@@ -167,3 +173,29 @@ async def mark_message_status(
|
||||
"last_delivered_message_id": receipt.last_delivered_message_id or 0,
|
||||
"last_read_message_id": receipt.last_read_message_id or 0,
|
||||
}
|
||||
|
||||
|
||||
async def forward_message(
|
||||
db: AsyncSession,
|
||||
*,
|
||||
source_message_id: int,
|
||||
sender_id: int,
|
||||
payload: MessageForwardRequest,
|
||||
) -> Message:
|
||||
source = await repository.get_message_by_id(db, source_message_id)
|
||||
if not source:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Source message not found")
|
||||
await ensure_chat_membership(db, chat_id=source.chat_id, user_id=sender_id)
|
||||
await ensure_chat_membership(db, chat_id=payload.target_chat_id, user_id=sender_id)
|
||||
forwarded = await repository.create_message(
|
||||
db,
|
||||
chat_id=payload.target_chat_id,
|
||||
sender_id=sender_id,
|
||||
reply_to_message_id=None,
|
||||
forwarded_from_message_id=source.id,
|
||||
message_type=source.type,
|
||||
text=source.text,
|
||||
)
|
||||
await db.commit()
|
||||
await db.refresh(forwarded)
|
||||
return forwarded
|
||||
|
||||
Reference in New Issue
Block a user