feat: interactive inline buttons, SMTP reply, AI reply suggestions
- Inline keyboard: view original / back to summary toggle per message - SMTP config per account for sending replies - Reply button: click, type message, auto-send via SMTP - AI Reply button: generates 3 suggestions via DeepSeek - Simple replies (OK, Got it) send immediately on tap - Substantive replies require confirm before send - Hides AI Reply button when AI determines reply unnecessary - Telegram long polling integrated into main loop for real-time interaction
This commit is contained in:
@@ -40,6 +40,49 @@ def summarize_email(ai_cfg: AIConfig, recipient: str, subject: str, sender: str,
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
return _call_deepseek(ai_cfg, payload)
|
||||
|
||||
|
||||
REPLY_PROMPT = """你是一个邮件回复助手。根据以下邮件内容生成3个建议回复。
|
||||
|
||||
返回 JSON:
|
||||
{
|
||||
"can_reply": true/false,
|
||||
"suggestions": [
|
||||
{"text": "回复内容", "is_simple": true/false},
|
||||
{"text": "回复内容", "is_simple": true/false},
|
||||
{"text": "回复内容", "is_simple": true/false}
|
||||
]
|
||||
}
|
||||
|
||||
- can_reply 为 false 时表示无需回复或不适合自动建议(此时忽略 suggestions)
|
||||
- is_simple 为 true 表示纯确认性回复(如"好的""收到""明白"),用户选择后可直接发送
|
||||
- is_simple 为 false 表示涉及实质内容,需要用户确认后再发送
|
||||
- 每条回复控制在 50 字以内
|
||||
只返回 JSON,不要包含任何其他文字。"""
|
||||
|
||||
|
||||
@retry()
|
||||
def generate_reply_suggestions(ai_cfg: AIConfig, sender: str, subject: str, body: str) -> dict:
|
||||
content = f"发件人: {sender}\n主题: {subject}\n正文:\n{body[:4000]}"
|
||||
|
||||
payload = {
|
||||
"model": ai_cfg.model,
|
||||
"messages": [
|
||||
{"role": "system", "content": REPLY_PROMPT},
|
||||
{"role": "user", "content": content},
|
||||
],
|
||||
"response_format": {"type": "json_object"},
|
||||
}
|
||||
|
||||
return _call_deepseek(ai_cfg, payload)
|
||||
|
||||
|
||||
def _call_deepseek(ai_cfg: AIConfig, payload: dict) -> dict:
|
||||
headers = {
|
||||
"Authorization": f"Bearer {ai_cfg.api_key}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
resp = requests.post(
|
||||
f"{ai_cfg.base_url.rstrip('/')}/chat/completions",
|
||||
headers=headers,
|
||||
|
||||
Reference in New Issue
Block a user