138 lines
4.5 KiB
Python
138 lines
4.5 KiB
Python
from __future__ import annotations
|
|
|
|
import logging
|
|
import re
|
|
|
|
from yuxi.channel.extensions.feishu.utils import safe_filename, recover_latin1_filename
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
def detect_file_type(filename: str) -> str:
|
|
ext = filename.rsplit(".", 1)[-1].lower() if "." in filename else ""
|
|
type_map = {
|
|
"opus": "opus", "ogg": "opus",
|
|
"mp4": "mp4", "mov": "mp4", "avi": "mp4",
|
|
"pdf": "pdf",
|
|
"doc": "doc", "docx": "doc",
|
|
"xls": "xls", "xlsx": "xls",
|
|
"ppt": "ppt", "pptx": "ppt",
|
|
}
|
|
return type_map.get(ext, "stream")
|
|
|
|
|
|
def resolve_outbound_media_kind(filename: str, content_type: str = "") -> dict:
|
|
ext = filename.rsplit(".", 1)[-1].lower() if "." in filename else ""
|
|
|
|
image_exts = {"png", "jpg", "jpeg", "gif", "bmp", "webp", "tiff"}
|
|
opus_exts = {"opus", "ogg"}
|
|
video_exts = {"mp4", "mov", "avi", "mkv", "webm"}
|
|
|
|
if ext in image_exts or (content_type and content_type.startswith("image/")):
|
|
return {"msg_type": "image", "file_type": "image"}
|
|
|
|
if ext in opus_exts or content_type in ("audio/ogg", "audio/opus"):
|
|
return {"msg_type": "audio", "file_type": "opus"}
|
|
|
|
if ext in video_exts or (content_type and content_type.startswith("video/")):
|
|
return {"msg_type": "media", "file_type": "mp4"}
|
|
|
|
return {"msg_type": "file", "file_type": detect_file_type(filename)}
|
|
|
|
|
|
async def upload_image(
|
|
app_id: str,
|
|
app_secret: str,
|
|
domain: str,
|
|
file_path: str,
|
|
http_timeout_ms: int = 30000,
|
|
) -> dict:
|
|
try:
|
|
from yuxi.channel.extensions.feishu.client import get_client
|
|
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
|
|
|
import lark_oapi
|
|
|
|
with open(file_path, "rb") as f:
|
|
req = lark_oapi.im.v1.CreateImageRequest(
|
|
request_body=lark_oapi.im.v1.CreateImageRequestBody(
|
|
image_type="message",
|
|
image=f,
|
|
),
|
|
)
|
|
resp = await client.im.v1.image.create_async(req)
|
|
|
|
if resp.success():
|
|
return {"success": True, "image_key": getattr(resp.data, "image_key", "")}
|
|
else:
|
|
return {"success": False, "error": getattr(resp, "msg", "")}
|
|
except ImportError:
|
|
return {"success": False, "error": "lark-oapi SDK not installed"}
|
|
except Exception:
|
|
logger.exception("Feishu upload_image error")
|
|
return {"success": False, "error": "Internal error"}
|
|
|
|
|
|
async def upload_file(
|
|
app_id: str,
|
|
app_secret: str,
|
|
domain: str,
|
|
file_path: str,
|
|
file_type: str = "stream",
|
|
filename: str = "",
|
|
http_timeout_ms: int = 30000,
|
|
) -> dict:
|
|
try:
|
|
from yuxi.channel.extensions.feishu.client import get_client
|
|
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
|
|
|
import lark_oapi
|
|
|
|
with open(file_path, "rb") as f:
|
|
req = lark_oapi.im.v1.CreateFileRequest(
|
|
request_body=lark_oapi.im.v1.CreateFileRequestBody(
|
|
file_type=file_type,
|
|
file_name=filename or safe_filename(file_path),
|
|
file=f,
|
|
),
|
|
)
|
|
resp = await client.im.v1.file.create_async(req)
|
|
|
|
if resp.success():
|
|
return {"success": True, "file_key": getattr(resp.data, "file_key", "")}
|
|
else:
|
|
return {"success": False, "error": getattr(resp, "msg", "")}
|
|
except ImportError:
|
|
return {"success": False, "error": "lark-oapi SDK not installed"}
|
|
except Exception:
|
|
logger.exception("Feishu upload_file error")
|
|
return {"success": False, "error": "Internal error"}
|
|
|
|
|
|
async def download_image(
|
|
app_id: str,
|
|
app_secret: str,
|
|
domain: str,
|
|
image_key: str,
|
|
http_timeout_ms: int = 30000,
|
|
) -> dict:
|
|
try:
|
|
from yuxi.channel.extensions.feishu.client import get_client
|
|
client = get_client(app_id, app_secret, domain, http_timeout_ms)
|
|
|
|
import lark_oapi
|
|
req = lark_oapi.im.v1.GetImageRequest(image_key=image_key)
|
|
resp = await client.im.v1.image.get_async(req)
|
|
|
|
if resp.success():
|
|
return {
|
|
"success": True,
|
|
"content_type": resp.file.content_type if resp.file else "",
|
|
}
|
|
else:
|
|
return {"success": False, "error": getattr(resp, "msg", "")}
|
|
except ImportError:
|
|
return {"success": False, "error": "lark-oapi SDK not installed"}
|
|
except Exception:
|
|
logger.exception("Feishu download_image error")
|
|
return {"success": False, "error": "Internal error"} |