ForcePilot/backend/package/yuxi/channel/extensions/intercom/handoff.py

55 lines
2.1 KiB
Python
Raw Normal View History

import logging
from yuxi.channel.extensions.intercom.client import IntercomClient
logger = logging.getLogger(__name__)
class HandoffDetector:
@staticmethod
async def is_human_takeover(client: IntercomClient, conversation_id: str, bot_admin_id: str) -> bool:
try:
conv = await client.get_conversation(conversation_id)
except Exception:
logger.warning("Failed to fetch conversation %s for handoff check", conversation_id, exc_info=True)
return False
assignee = conv.get("assignee") or {}
if assignee and assignee.get("type") == "admin":
admin_id = str(assignee.get("id", ""))
if admin_id and admin_id != bot_admin_id:
return True
return False
@staticmethod
async def check_recent_admin_reply(client: IntercomClient, conversation_id: str, bot_admin_id: str) -> bool:
try:
parts = await client.get_conversation_parts(conversation_id)
except Exception:
logger.warning("Failed to fetch conversation parts for handoff check", exc_info=True)
return False
for part in reversed(parts):
author = part.get("author", {})
if author.get("type") == "admin" and str(author.get("id", "")) != bot_admin_id:
return True
if part.get("part_type") == "comment" and author.get("type") in ("contact", "user"):
break
return False
@staticmethod
async def get_last_admin_reply_time(client: IntercomClient | None, conversation_id: str, bot_admin_id: str) -> float | None:
if client is None:
return None
try:
parts = await client.get_conversation_parts(conversation_id)
except Exception:
return None
for part in reversed(parts):
author = part.get("author", {})
if author.get("type") == "admin" and str(author.get("id", "")) != bot_admin_id:
created_at = part.get("created_at", 0)
return float(created_at) if created_at else None
return None