from __future__ import annotations import logging from yuxi.channel.extensions.helpscout.auth import HelpScoutAuth from yuxi.channel.extensions.helpscout.client import HelpScoutClient from yuxi.channel.extensions.helpscout.config import resolve_account from yuxi.channel.extensions.helpscout.types import OutboundResult logger = logging.getLogger(__name__) FAQ_RULES: dict[str, dict] = { "reset password": { "reply": ( "To reset your password, please visit https://example.com/reset-password " "and follow the instructions. If you need further assistance, please let us know." ), "tags": ["account", "password"], }, "cancel subscription": { "reply": ( "To cancel your subscription, please go to your Account Settings > Billing " "and click 'Cancel Subscription'. If you have any questions, we're here to help." ), "tags": ["billing", "subscription"], }, "contact support": { "reply": ( "You can reach our support team by replying to this email or visiting " "https://example.com/support. Our team is available Monday-Friday, 9 AM - 6 PM." ), "tags": ["support"], }, } class HelpScoutAutoReply: async def check_faq_match(self, body_text: str) -> dict | None: text_lower = body_text.lower() for keyword, faq in FAQ_RULES.items(): if keyword in text_lower: logger.debug( "Help Scout FAQ match: keyword=%s", keyword, ) return {"keyword": keyword, **faq} return None async def send_faq_reply( self, conversation_id: int, reply_text: str, tags: list[str] | None = None, account_id: str | None = None, ) -> OutboundResult: account = resolve_account(account_id or "default") client = self._build_client(account) try: result = await client.reply_conversation( conversation_id=conversation_id, text=reply_text, draft=True, ) reply_id = str(result.get("id", "")) if tags: conv = await client.get_conversation(conversation_id) existing_tags = conv.get("tags", []) new_tags = [t for t in tags if t not in existing_tags] if new_tags: await client.update_conversation( conversation_id, {"tags": existing_tags + new_tags}, ) note = "Auto-reply draft generated from FAQ match. Review and send when ready." await client.create_note(conversation_id=conversation_id, text=note) logger.info( "Help Scout FAQ auto-reply drafted: conv=%d", conversation_id, ) return OutboundResult(success=True, message_id=reply_id) except Exception as e: logger.exception( "Help Scout FAQ auto-reply failed: conv=%d", conversation_id, ) return OutboundResult(success=False, error="exception", detail=str(e)) finally: await client.close() @staticmethod def _build_client(account: dict) -> HelpScoutClient: auth = HelpScoutAuth(account["app_id"], account["app_secret"]) return HelpScoutClient(auth)