docs: add TTS voice reply capability to memory and TOOLS.md

This commit is contained in:
root
2026-03-30 01:36:47 +08:00
parent 84d47fc753
commit 7ce166affb
3 changed files with 233 additions and 85 deletions

View File

@@ -3,6 +3,7 @@
"""
邮件摘要脚本 - 每天早上9点推送前一天的邮件摘要
重点关注 fj@77ircloud.com 的邮件
需要回应的邮件会标记提醒
⚠️ 安全规则:此脚本仅读取邮件,不执行任何删除操作
"""
@@ -12,8 +13,6 @@ import ssl
import email
from email.header import decode_header
from datetime import datetime, timedelta
import json
import sys
def decode_str(s):
if s is None:
@@ -31,32 +30,46 @@ def decode_str(s):
result.append(part)
return ''.join(result)
def get_email_body(msg):
"""获取邮件正文"""
body = ''
if msg.is_multipart():
for part in msg.walk():
content_type = part.get_content_type()
if content_type == 'text/plain':
try:
charset = part.get_content_charset() or 'utf-8'
body = part.get_payload(decode=True).decode(charset, errors='replace')
break
except:
pass
elif content_type == 'text/html':
try:
charset = part.get_content_charset() or 'utf-8'
body = part.get_payload(decode=True).decode(charset, errors='replace')
except:
pass
else:
try:
charset = msg.get_content_charset() or 'utf-8'
body = msg.get_payload(decode=True).decode(charset, errors='replace')
except:
pass
return body[:500] if body else '(无正文)'
def get_body_preview(msg, max_len=200):
"""获取邮件正文预览"""
try:
if msg.is_multipart():
for part in msg.walk():
if part.get_content_type() == 'text/plain':
payload = part.get_payload(decode=True)
if payload:
charset = part.get_content_charset() or 'utf-8'
body = payload.decode(charset, errors='replace')
return body[:max_len].replace('\n', ' ').strip()
else:
payload = msg.get_payload(decode=True)
if payload:
charset = msg.get_content_charset() or 'utf-8'
body = payload.decode(charset, errors='replace')
return body[:max_len].replace('\n', ' ').strip()
except:
pass
return ''
def needs_response(subject, body, sender):
"""判断邮件是否需要回应"""
text = (subject + ' ' + body).lower()
sender_lower = sender.lower()
# 需要回应的关键词
response_keywords = [
'请回复', '请回复我', '需回复', '需要回复',
'请回复确认', '请回复一下', '请回复告知',
'请确认', '请批准', '请审核', '请审批',
'期待回复', '希望回复', '烦请', '麻烦',
'请知悉', '请查收', '请查阅',
'请协助', '请配合', '请支持', '请安排', '请处理',
]
# 重要发件人
important_senders = ['fj@77ircloud.com']
return any(kw in text for kw in response_keywords) or any(s in sender_lower for s in important_senders)
def fetch_yesterday_emails():
"""获取昨天的邮件"""
@@ -70,88 +83,122 @@ def fetch_yesterday_emails():
email_ids = messages[0].split()
yesterday = (datetime.now() - timedelta(days=1)).date()
yesterday_start = yesterday.strftime('%d-%b-%Y')
all_emails = []
important_emails = []
need_response_emails = []
for uid in reversed(email_ids[-50:] if len(email_ids) >= 50 else email_ids):
status, msg_data = mail.fetch(uid, '(RFC822.HEADER RFC822.TEXT)')
if not msg_data or not msg_data[0]:
continue
raw_email = msg_data[0][1] if isinstance(msg_data[0], tuple) else msg_data[0]
if isinstance(raw_email, tuple):
raw_email = raw_email[1]
# 扫描最近50封
scan_range = email_ids[-50:] if len(email_ids) >= 50 else email_ids
for uid in reversed(scan_range):
try:
msg = email.message_from_bytes(raw_email if isinstance(raw_email, bytes) else raw_email.encode('utf-8'))
except:
# 获取完整邮件(头部+正文)
status, msg_data = mail.fetch(uid, '(RFC822)')
if not msg_data or not msg_data[0]:
continue
raw_email = msg_data[0][1]
if isinstance(raw_email, tuple):
raw_email = raw_email[1]
msg = email.message_from_bytes(raw_email)
subject = decode_str(msg.get('Subject', '(无主题)'))
sender = decode_str(msg.get('From', ''))
date_str = msg.get('Date', '')
# 解析日期
try:
t = email.utils.parsedate_tz(date_str)
if t:
local_dt = datetime.fromtimestamp(email.utils.mktime_tz(t))
email_date = local_dt.date()
else:
continue
except:
continue
# 只取昨天的邮件
if email_date != yesterday:
continue
body = get_body_preview(msg, 300)
email_info = {
'subject': subject,
'sender': sender,
'date': date_str,
'body': body,
}
all_emails.append(email_info)
# 重点关注
if 'fj@77ircloud.com' in sender:
important_emails.append(email_info)
# 需要回应
if needs_response(subject, body, sender):
need_response_emails.append(email_info)
except Exception as e:
continue
subject = decode_str(msg.get('Subject', '(无主题)'))
sender = decode_str(msg.get('From', ''))
date_str = msg.get('Date', '')
# 解析日期
try:
email_date = email.utils.parsedate_to_datetime(date_str).date()
except:
continue
# 只取昨天的邮件
if email_date != yesterday:
continue
email_info = {
'subject': subject,
'sender': sender,
'date': date_str,
'body': get_email_body(msg)
}
all_emails.append(email_info)
# 重点关注 fj@77ircloud.com
if 'fj@77ircloud.com' in sender:
important_emails.append(email_info)
mail.logout()
return all_emails, important_emails, yesterday.strftime('%Y年%m月%d')
return all_emails, important_emails, need_response_emails, yesterday.strftime('%Y年%m月%d')
except Exception as e:
return [], [], str(e)
return [], [], [], str(e)
def format_summary():
"""格式化邮件摘要"""
emails, important, date_str = fetch_yesterday_emails()
emails, important, need_response, date_str = fetch_yesterday_emails()
if isinstance(important, str):
return f"⚠️ 获取邮件失败: {important}"
if not emails:
return f"📬 {date_str} 无新邮件"
return f"📬 {date_str} 无新邮件\n\n祝你一天好心情!😊"
lines = [f"📬 {date_str} 邮件摘要(共 {len(emails)} 封)\n"]
lines = [f"📬 {date_str} 邮件摘要\n"]
lines.append(f"共收到 **{len(emails)}** 封邮件\n")
if important:
lines.append(f"⭐ 重点关注fj@77ircloud.com{len(important)}\n")
for i, mail in enumerate(important, 1):
# 需要回应的邮件(最优先)
if need_response:
lines.append(f"🔔 **需要您回应({len(need_response)} 封)**\n")
lines.append("" * 40)
for i, mail in enumerate(need_response, 1):
lines.append(f" {i}. 📧 {mail['subject']}")
lines.append(f" 发件人: {mail['sender']}")
lines.append(f" 时间: {mail['date']}")
if mail['body'] and mail['body'] != '(无正文)':
lines.append(f" 摘要: {mail['body'][:200]}...")
if mail.get('body'):
lines.append(f" 摘要: {mail['body'][:150]}...")
lines.append("")
lines.append(f"\n📋 其他邮件({len(emails) - len(important)} 封):")
other = [e for e in emails if e not in important]
for i, mail in enumerate(other[:5], 1):
lines.append(f" {i}. 📧 {mail['subject']} - {mail['sender']} ({mail['date']})")
# 重点关注(排除已标记需要回应的)
important_only = [e for e in important if e not in need_response]
if important_only:
lines.append(f"⭐ **重点关注fj@77ircloud.com{len(important_only)} 封)**\n")
lines.append("" * 40)
for i, mail in enumerate(important_only, 1):
lines.append(f" {i}. 📧 {mail['subject']}")
lines.append(f" 发件人: {mail['sender']}")
lines.append("")
if len(other) > 5:
lines.append(f" ... 还有 {len(other) - 5} 封邮件")
# 其他邮件
other = [e for e in emails if e not in important and e not in need_response]
if other:
lines.append(f"\n📋 **其他邮件({len(other)} 封)**\n")
lines.append("" * 40)
for i, mail in enumerate(other[:8], 1):
lines.append(f" {i}. 📧 {mail['subject']}")
lines.append(f" 发件人: {mail['sender']}")
lines.append("")
if len(other) > 8:
lines.append(f" ... 还有 {len(other) - 8} 封邮件")
lines.append("\n" + "=" * 40)
lines.append("💡 提示:以上标记「需要回应」的邮件,请及时处理!")
return "\n".join(lines)