WechatOnCloud/bridge/woc_bridge/models/batch_send.py

68 lines
2.0 KiB
Python
Raw Normal View History

"""群发消息相关数据模型。"""
from __future__ import annotations
from typing import Optional, Literal
from pydantic import BaseModel, Field
class BatchSendRequest(BaseModel):
"""群发请求。
三层幂等
- 批级client_request_idNone 时自动生成 batch_id
- 单条内部按 f"{batch_id}:{to_wxid}" 作为 client_request_id 传给 orchestrator
- orchestrator复用 IdemCacheTTL=300s
"""
targets: list[str] = Field(
...,
min_length=1,
max_length=200,
description="目标 wxid 列表(去重后 ≤ 200",
)
content: str = Field(
...,
min_length=1,
max_length=2000,
description="消息内容(支持 {nickname} 占位符,发送前按目标联系人替换)",
)
client_request_id: Optional[str] = Field(
None,
description="可选:批级幂等 IDNone 时自动生成 batch_id",
)
abort_on_consecutive_fail: int = Field(
5,
ge=1,
le=20,
description="连续失败 N 次中止整批(剩余标记 skipped",
)
class BatchItemResult(BaseModel):
"""单条群发结果。"""
to_wxid: str
# unknown: 发送被 cancel 中断实际发送状态未知send_queue worker 可能已发出)
status: Literal["success", "failed", "skipped", "pending", "unknown"]
error_code: Optional[str] = None
error_message: Optional[str] = None
verified: Optional[bool] = None
class BatchSendStatus(BaseModel):
"""群发任务状态。"""
batch_id: str
status: Literal["pending", "running", "completed", "failed", "cancelled"] = "pending"
total: int = 0
processed: int = 0
success: int = 0
failed: int = 0
skipped: int = 0
progress: float = Field(0.0, ge=0.0, le=1.0)
estimated_remaining_sec: Optional[int] = None
abort_reason: Optional[str] = None
items: Optional[list[BatchItemResult]] = None # 详细结果(可选,列表大时省略)