This commit is contained in:
debu-2 2026-10-15 03:39:09 +05:30
parent 9f03e5df32
commit 33b6b5d26f
4 changed files with 159 additions and 50 deletions

View file

@ -303,11 +303,12 @@ async def whatsapp_account_refresh(
@router.get("/accounts/{account_id}/messages")
def whatsapp_account_messages(
account_id: str,
limit: int = Query(default=300, ge=1, le=500),
limit: int = Query(default=500, ge=1, le=500),
q: str = Query(default="", max_length=80),
db: Session = Depends(get_db),
user: UserAccount = Depends(current_user),
) -> list[dict]:
return list_account_messages(db, user, account_id, limit)
return list_account_messages(db, user, account_id, limit, q)
@router.post("/accounts/{account_id}/delivery")

View file

@ -16,7 +16,7 @@ from typing import Any
import httpx
from fastapi import HTTPException, status
from sqlalchemy import or_, select
from sqlalchemy import case, func, or_, select
from sqlalchemy.orm import Session, selectinload
from .config import settings
@ -1182,16 +1182,81 @@ def customer_token_for_phone(db: Session, user: UserAccount, phone_number_id: st
return token, phone.phone_number_id
def list_account_messages(db: Session, user: UserAccount, account_id: Any, limit: int = 300) -> list[dict[str, Any]]:
def _message_peer():
return case(
(WhatsAppMessage.direction == "inbound", WhatsAppMessage.from_number),
else_=WhatsAppMessage.to_number,
)
def _like_term(value: str) -> str:
escaped = value.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
return f"%{escaped}%"
def list_account_messages(
db: Session,
user: UserAccount,
account_id: Any,
limit: int = 500,
query: str | None = None,
) -> list[dict[str, Any]]:
account = _owned_account(db, user, account_id)
phone_ids = [phone.phone_number_id for phone in account.phones]
if not phone_ids:
return []
peer = _message_peer()
scoped = (
WhatsAppMessage.user_id == user.id,
WhatsAppMessage.phone_number_id.in_(phone_ids),
WhatsAppMessage.message_type != "status",
)
term = (query or "").strip()
if term:
pattern = _like_term(term)
matched = [
WhatsAppMessage.body.ilike(pattern, escape="\\"),
WhatsAppMessage.contact_name.ilike(pattern, escape="\\"),
WhatsAppMessage.from_number.ilike(pattern, escape="\\"),
WhatsAppMessage.to_number.ilike(pattern, escape="\\"),
]
digits = re.sub(r"\D", "", term)
if len(digits) >= 4:
matched.append(WhatsAppMessage.from_number.ilike(f"%{digits}%"))
matched.append(WhatsAppMessage.to_number.ilike(f"%{digits}%"))
peers = [
item
for item in db.scalars(select(peer).where(*scoped, or_(*matched)).distinct()).all()
if item
]
if not peers:
return []
rows = db.scalars(
select(WhatsAppMessage)
.where(*scoped, peer.in_(peers))
.order_by(WhatsAppMessage.created_at.desc())
.limit(5000)
).all()
return [serialize_message(row) for row in rows]
recent_peers = [
item
for item in db.scalars(
select(peer)
.where(*scoped)
.group_by(peer)
.order_by(func.max(WhatsAppMessage.created_at).desc())
.limit(min(max(limit, 1), 500))
).all()
if item
]
if not recent_peers:
return []
rows = db.scalars(
select(WhatsAppMessage)
.where(WhatsAppMessage.user_id == user.id, WhatsAppMessage.phone_number_id.in_(phone_ids))
.where(*scoped, peer.in_(recent_peers))
.order_by(WhatsAppMessage.created_at.desc())
.limit(min(limit, 500))
.limit(5000)
).all()
return [serialize_message(row) for row in rows]