77 lines
2.9 KiB
Python
77 lines
2.9 KiB
Python
import os
|
||
import time
|
||
import logging
|
||
from datetime import datetime
|
||
from typing import Dict
|
||
|
||
from db.chat_log_db import get_waiting_customer_pool
|
||
from db.pending_transfer_db import count_open_pending_transfers
|
||
from services.service_wecom_bot import wecom_bot_service
|
||
|
||
logger = logging.getLogger("cs_agent")
|
||
|
||
DESIGNER_ALERT_START_HOUR = int(os.getenv("DESIGNER_ALERT_START_HOUR", "8"))
|
||
DESIGNER_ALERT_END_HOUR = int(os.getenv("DESIGNER_ALERT_END_HOUR", "24"))
|
||
DESIGNER_ALERT_COOLDOWN_SECONDS = int(os.getenv("DESIGNER_ALERT_COOLDOWN_SECONDS", "300"))
|
||
DESIGNER_ALERT_POOL_WINDOW_MINUTES = int(os.getenv("DESIGNER_ALERT_POOL_WINDOW_MINUTES", "30"))
|
||
|
||
|
||
class DesignerAlertService:
|
||
def __init__(self):
|
||
self._last_alert_at = 0.0
|
||
|
||
@staticmethod
|
||
def _in_active_window(now: datetime) -> bool:
|
||
hour = now.hour
|
||
return DESIGNER_ALERT_START_HOUR <= hour < DESIGNER_ALERT_END_HOUR
|
||
|
||
@staticmethod
|
||
def _render_shop_lines(pool: Dict) -> str:
|
||
shops = pool.get("shops") or []
|
||
if not shops:
|
||
return "- 暂无店铺明细"
|
||
lines = []
|
||
for item in shops[:10]:
|
||
acc_id = str(item.get("acc_id") or "")
|
||
waiting = int(item.get("waiting_customers") or 0)
|
||
lines.append(f"- {acc_id}:{waiting}人")
|
||
return "\n".join(lines)
|
||
|
||
async def notify_if_needed(self, *, trigger: str = "", customer_id: str = "", acc_id: str = "") -> bool:
|
||
now = datetime.now()
|
||
if not self._in_active_window(now):
|
||
return False
|
||
|
||
now_ts = time.time()
|
||
if now_ts - self._last_alert_at < max(DESIGNER_ALERT_COOLDOWN_SECONDS, 30):
|
||
return False
|
||
|
||
pending_count = count_open_pending_transfers()
|
||
pool = get_waiting_customer_pool(DESIGNER_ALERT_POOL_WINDOW_MINUTES)
|
||
waiting_total = int(pool.get("total_waiting_customers") or 0)
|
||
if pending_count <= 0 and waiting_total <= 0:
|
||
return False
|
||
|
||
content = (
|
||
"【设计师在线提醒】\n"
|
||
f"当前时间:{now.strftime('%Y-%m-%d %H:%M:%S')}\n"
|
||
"8点到24点内检测到暂无设计师接单,有客户待转接。\n"
|
||
f"触发来源:{trigger or '-'}\n"
|
||
f"当前会话:{customer_id or '-'} / {acc_id or '-'}\n"
|
||
f"待转接池:{pending_count}人\n"
|
||
f"当前客户池:{waiting_total}人(近{pool.get('window_minutes') or DESIGNER_ALERT_POOL_WINDOW_MINUTES}分钟最后一条仍是客户消息)\n"
|
||
"店铺分布:\n"
|
||
f"{self._render_shop_lines(pool)}\n"
|
||
"群里如果有设计师在线,麻烦看一下。"
|
||
)
|
||
ok = await wecom_bot_service.send_text(content)
|
||
if ok:
|
||
self._last_alert_at = now_ts
|
||
logger.info(
|
||
f"[DesignerAlert] 已发送企微提醒 trigger={trigger} pending={pending_count} waiting={waiting_total}"
|
||
)
|
||
return ok
|
||
|
||
|
||
designer_alert_service = DesignerAlertService()
|