完成Help Scout渠道的完整功能实现,包含API客户端、webhook处理、轮询同步、自动回复、工单标签分配、客户资料管理等核心能力,附带完整的配置Schema与插件元信息
70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
|
|
import httpx
|
|
|
|
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
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
MAX_ATTACHMENT_SIZE_MB = 50
|
|
MAX_ATTACHMENT_SIZE_BYTES = MAX_ATTACHMENT_SIZE_MB * 1024 * 1024
|
|
|
|
|
|
async def upload_attachment(
|
|
file_content: bytes,
|
|
file_name: str,
|
|
mime_type: str,
|
|
account_id: str | None = None,
|
|
) -> dict:
|
|
if len(file_content) > MAX_ATTACHMENT_SIZE_BYTES:
|
|
raise ValueError(
|
|
f"Attachment size exceeds {MAX_ATTACHMENT_SIZE_MB}MB limit: {len(file_content) / 1024 / 1024:.1f}MB"
|
|
)
|
|
|
|
account = resolve_account(account_id or "default")
|
|
if not account.get("app_id") or not account.get("app_secret"):
|
|
raise RuntimeError("Help Scout account not configured")
|
|
|
|
auth = HelpScoutAuth(account["app_id"], account["app_secret"])
|
|
await auth.ensure_token()
|
|
|
|
async with httpx.AsyncClient(timeout=60.0) as client:
|
|
resp = await client.post(
|
|
"https://api.helpscout.net/v2/attachments",
|
|
files={"file": (file_name, file_content, mime_type)},
|
|
headers={"Authorization": f"Bearer {auth.access_token}"},
|
|
)
|
|
resp.raise_for_status()
|
|
result = resp.json()
|
|
logger.info(
|
|
"Help Scout attachment uploaded: id=%s name=%s",
|
|
result.get("id"),
|
|
file_name,
|
|
)
|
|
return result
|
|
|
|
|
|
async def download_attachment(
|
|
attachment_id: str,
|
|
conversation_id: int,
|
|
account_id: str | None = None,
|
|
) -> bytes:
|
|
account = resolve_account(account_id or "default")
|
|
auth = HelpScoutAuth(account["app_id"], account["app_secret"])
|
|
client = HelpScoutClient(auth)
|
|
|
|
try:
|
|
content = await client.download_attachment(attachment_id, conversation_id)
|
|
logger.debug(
|
|
"Help Scout attachment downloaded: id=%s size=%d",
|
|
attachment_id,
|
|
len(content),
|
|
)
|
|
return content
|
|
finally:
|
|
await client.close()
|