mirror of
http://88.130.71.182:3000/BlitTech/deals24togo_be.git
synced 2026-06-12 23:33:21 +00:00
Initial commit
This commit is contained in:
159
app/services/message_service.py
Normal file
159
app/services/message_service.py
Normal file
@@ -0,0 +1,159 @@
|
||||
"""Message / contact service."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import datetime, timezone
|
||||
from typing import Optional
|
||||
|
||||
from app.core.config import get_settings
|
||||
from app.core.exceptions import ForbiddenException, NotFoundException
|
||||
from app.core.supabase import get_supabase_admin
|
||||
from app.services.email_service import EmailService
|
||||
|
||||
|
||||
class MessageService:
|
||||
def __init__(self):
|
||||
self.db = get_supabase_admin()
|
||||
|
||||
def send_message(self, data: dict) -> dict:
|
||||
# Resolve agency_id and listing title
|
||||
listing_row = (
|
||||
self.db.table("listings")
|
||||
.select("agency_id, title")
|
||||
.eq("id", data["listing_id"])
|
||||
.execute()
|
||||
)
|
||||
if not listing_row.data:
|
||||
raise NotFoundException("Listing not found")
|
||||
|
||||
agency_id = listing_row.data[0]["agency_id"]
|
||||
listing_title = listing_row.data[0].get("title", "")
|
||||
|
||||
now = datetime.now(timezone.utc).isoformat()
|
||||
msg_data = {
|
||||
**data,
|
||||
"agency_id": agency_id,
|
||||
"read": False,
|
||||
"created_at": now,
|
||||
}
|
||||
result = self.db.table("messages").insert(msg_data).execute()
|
||||
if not result.data:
|
||||
raise Exception("Failed to send message")
|
||||
|
||||
# Notify agency via email (non-blocking)
|
||||
try:
|
||||
agency_row = (
|
||||
self.db.table("agencies")
|
||||
.select("name, email")
|
||||
.eq("id", agency_id)
|
||||
.execute()
|
||||
)
|
||||
if agency_row.data:
|
||||
agency = agency_row.data[0]
|
||||
settings = get_settings()
|
||||
dashboard_url = f"{settings.FRONTEND_URL}/agency/dashboard"
|
||||
EmailService().send_new_message_notification(
|
||||
to_email=agency["email"],
|
||||
agency_name=agency["name"],
|
||||
sender_name=data.get("name", "Someone"),
|
||||
listing_title=listing_title,
|
||||
dashboard_url=dashboard_url,
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return result.data[0]
|
||||
|
||||
def list_messages(
|
||||
self,
|
||||
agency_id: str,
|
||||
user_id: str,
|
||||
user_role: str,
|
||||
read_filter: Optional[bool] = None,
|
||||
page: int = 1,
|
||||
page_size: int = 20,
|
||||
) -> dict:
|
||||
# Verify ownership
|
||||
if user_role != "admin":
|
||||
agency = (
|
||||
self.db.table("agencies")
|
||||
.select("user_id")
|
||||
.eq("id", agency_id)
|
||||
.execute()
|
||||
)
|
||||
if not agency.data or agency.data[0]["user_id"] != user_id:
|
||||
raise ForbiddenException("Not authorized")
|
||||
|
||||
query = (
|
||||
self.db.table("messages")
|
||||
.select("*, listings(title)", count="exact")
|
||||
.eq("agency_id", agency_id)
|
||||
)
|
||||
if read_filter is not None:
|
||||
query = query.eq("read", read_filter)
|
||||
|
||||
offset = (page - 1) * page_size
|
||||
result = (
|
||||
query.order("created_at", desc=True)
|
||||
.range(offset, offset + page_size - 1)
|
||||
.execute()
|
||||
)
|
||||
|
||||
messages = []
|
||||
for m in result.data:
|
||||
listings_data = m.pop("listings", None)
|
||||
if listings_data and isinstance(listings_data, dict):
|
||||
m["listing_title"] = listings_data.get("title")
|
||||
messages.append(m)
|
||||
|
||||
return {
|
||||
"messages": messages,
|
||||
"total": result.count or 0,
|
||||
"page": page,
|
||||
"page_size": page_size,
|
||||
}
|
||||
|
||||
def mark_read(self, message_id: str, user_id: str, user_role: str, read: bool = True) -> dict:
|
||||
msg = self.db.table("messages").select("*, agencies(user_id)").eq("id", message_id).execute()
|
||||
if not msg.data:
|
||||
raise NotFoundException("Message not found")
|
||||
|
||||
message = msg.data[0]
|
||||
agencies_data = message.get("agencies")
|
||||
if user_role != "admin":
|
||||
if not agencies_data or agencies_data.get("user_id") != user_id:
|
||||
raise ForbiddenException("Not authorized")
|
||||
|
||||
result = (
|
||||
self.db.table("messages")
|
||||
.update({"read": read})
|
||||
.eq("id", message_id)
|
||||
.execute()
|
||||
)
|
||||
if not result.data:
|
||||
raise NotFoundException("Message not found")
|
||||
return result.data[0]
|
||||
|
||||
def get_unread_count(self, agency_id: str) -> int:
|
||||
result = (
|
||||
self.db.table("messages")
|
||||
.select("id", count="exact")
|
||||
.eq("agency_id", agency_id)
|
||||
.eq("read", False)
|
||||
.execute()
|
||||
)
|
||||
return result.count or 0
|
||||
|
||||
def delete_message(self, message_id: str, user_id: str, user_role: str) -> dict:
|
||||
msg = self.db.table("messages").select("*, agencies(user_id)").eq("id", message_id).execute()
|
||||
if not msg.data:
|
||||
raise NotFoundException("Message not found")
|
||||
|
||||
message = msg.data[0]
|
||||
agencies_data = message.get("agencies")
|
||||
if user_role != "admin":
|
||||
if not agencies_data or agencies_data.get("user_id") != user_id:
|
||||
raise ForbiddenException("Not authorized")
|
||||
|
||||
self.db.table("messages").delete().eq("id", message_id).execute()
|
||||
return {"message": "Message deleted"}
|
||||
Reference in New Issue
Block a user