> 触发词:英语日记、写日记、diary、English diary、日记练习、英语练习、日记改错、帮我写日记、日记翻译、英语学习日记
这个 skill 帮助用户通过日记形式学习英语写作。用户可以用中英文混写输入日记,skill 自动完成以下任务:添加日期/地点/天气头部信息、分析语法与用词错误、重写标准英文版本、附带中文翻译对照、生成 TTS 朗读跟读文件、将全部内容同步到 IMA 笔记知识库。
凭证存储路径:~/.config/ima/client_id 和 ~/.config/ima/api_key
在用户日记正文之前,自动生成以下三行元信息:
Date: [英文格式日期,如 Sunday, April 19, 2026]
Location: [自动获取电脑地理位置;无法获取则留空]
Weather: [根据地点调用天气接口;无法获取则留空]
地点获取方法(依次尝试,取第一个成功的结果):
https://ipapi.co/json/ — 取 city 字段
https://ip-api.com/json/?lang=en — 取 city 字段
天气获取方法(获取到地点后执行):
https://wttr.in/{city}?format=%C+%t 获取天气描述(如 Sunny +28°C)
> ⚠️ 踩坑经验:Windows PowerShell 的 Invoke-RestMethod 对某些 API 返回 CLIXML 垃圾导致解析失败。必须使用 Python (python / python3) 的 urllib.request 来获取 IP 定位和天气数据,不要用 PowerShell。
逐条列出用户日记中存在的问题,格式如下:
## ✏️ Writing Analysis
### Grammar Errors(语法错误)
1. ❌ 原文:"..." → ✅ 建议:"..."
📝 说明:[中文解释错误原因]
### Word Choice(用词问题)
1. ❌ 原文:"..." → ✅ 建议:"..."
📝 说明:[中文解释,包括更自然的表达方式]
### Chinese → English(中文词汇对照)
| 你写的中文 | 对应英文表达 | 例句 |
|-----------|------------|------|
| ... | ... | ... |
### 🌟 Strengths(写得好的地方)
- [正面反馈,鼓励用户]
分析原则:
## 📖 Standard English Version
[完整的英文日记,包含 Part1 的头部信息]
---
*Rewritten for clarity and natural expression.*
重写原则:
在标准英文重写之后,附上对应的完整中文翻译。这是帮助用户理解 AI 重写内容的关键环节。
## 🔄 Chinese Translation (中文翻译)
[将 Part3 的英文日记逐段翻译成通顺的中文]
---
*翻译说明:以上为英文版的标准中文翻译,方便对照学习。*
翻译原则:
展示格式建议(段落对照):
| 📖 English | 📝 中文 |
|-----------|--------|
| [英文段落1] | [对应中文] |
| [英文段落2] | [对应中文] |
| ... | ... |
生成英文朗读控制器,帮助用户练习口语。提供两种输出,其中方式二为通用方案,无论什么载体(对话/IMA笔记/任何设备)均可使用。
调用 show_widget 工具,生成一个包含 Part3 英文全文和 TTS 控制的 HTML widget。
TTS Player - [日期]
["Preparing audio player","Loading text-to-speech","Almost ready"]
SpeechSynthesisUtterance,语言 en-US
> ⚠️ 若 show_widget 沙箱不支持 speechSynthesis,自动改用方式二。
将完整 TTS 播放器写入工作目录 tts_player_[YYYYMMDD].html。
用户可用任何浏览器打开,不依赖 WorkBuddy 环境,可离线使用,可通过 IMA 笔记链接或文件分享。
HTML 文件生成步骤:
[DATE] [LOCATION] [ENGLISH_TEXT] 替换为实际内容(注意 HTML 转义 &<>"')
c:\Users\kixp\WorkBuddy\20260419114607\tts_player_[YYYYMMDD].html
HTML 模板(写入文件用,使用 Write 工具):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Listen & Repeat - [DATE]</title>
<style>
body{font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;max-width:720px;margin:40px auto;padding:0 20px;background:#f5f5f5;color:#333}
.card{background:#fff;border-radius:12px;padding:24px;box-shadow:0 1px 3px rgba(0,0,0,.1);margin-bottom:20px}
h1{font-size:18px;font-weight:600;margin:0 0 16px 0}
.meta{font-size:13px;color:#666;margin-bottom:16px}
.text-content{font-size:15px;line-height:1.8}
.text-content p{margin:0 0 12px 0}
.controls{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-top:20px}
button{padding:8px 20px;font-size:14px;border:1px solid #ccc;border-radius:8px;background:#fff;cursor:pointer}
button:hover{background:#f0f0f0}
button.primary{background:#007AFF;color:#fff;border-color:#007AFF}
button.primary:hover{background:#0056CC}
select{padding:8px 12px;font-size:14px;border:1px solid #ccc;border-radius:8px;background:#fff}
.status{font-size:13px;color:#666;margin-top:12px}
</style>
</head>
<body>
<div class="card">
<h1>🔊 Listen & Repeat</h1>
<div class="meta">Date: [DATE] | Location: [LOCATION]</div>
<div class="text-content" id="diary-text">[ENGLISH_TEXT]</div>
<div class="controls">
<button class="primary" id="btn-play">▶ Play</button>
<button id="btn-pause">⏸ Pause</button>
<button id="btn-stop">■ Stop</button>
<select id="sel-rate">
<option value="0.7">Slow (0.7x)</option>
<option value="1" selected>Normal (1x)</option>
<option value="1.3">Fast (1.3x)</option>
</select>
</div>
<div class="status" id="status">Ready - click Play to start</div>
</div>
<div class="card">
<h2 style="font-size:15px;font-weight:600;margin:0 0 12px 0">Practice Tips</h2>
<ul style="font-size:14px;line-height:1.8;padding-left:20px;margin:0">
<li>Listen to one sentence → pause → repeat aloud</li>
<li>Match the rhythm and intonation</li>
<li>Use Slow mode for difficult sentences</li>
<li>Record yourself and compare with AI voice</li>
</ul>
</div>
<script>
var s=window.speechSynthesis,u=null,rate=1;
var t=document.getElementById('diary-text').innerText;
document.getElementById('sel-rate').onchange=function(){rate=parseFloat(this.value);if(u)u.rate=rate;};
document.getElementById('btn-play').onclick=function(){
if(s.speaking&&s.paused){s.resume();return;}
s.cancel();u=new SpeechSynthesisUtterance(t);
u.lang='en-US';u.rate=rate;
u.onstart=function(){document.getElementById('status').innerText='Playing...';};
u.onend=function(){document.getElementById('status').innerText='Finished';};
s.speak(u);
};
document.getElementById('btn-pause').onclick=function(){if(s.speaking&&!s.paused)s.pause();};
document.getElementById('btn-stop').onclick=function(){s.cancel();document.getElementById('status').innerText='Stopped';};
</script>
</body>
</html>
将所有五部分内容合并(Part1 头部 + 原始日记 + 错误分析 + 英文重写 + 中文翻译),自动调用 IMA API 创建一篇新笔记。
笔记标题格式:English Diary - [英文日期,如 April 19, 2026]
笔记内容结构(Markdown 格式):
# English Diary - [日期]
---
## 📅 Diary Entry (原始日记)
**Date:** [日期]
**Location:** [地点或空]
**Weather:** [天气或空]
[用户原始日记内容(保留原文,中英混杂)]
---
## ✏️ Writing Analysis (错误分析)
[Part 2 的错误分析内容]
---
## 📖 Standard English Version (标准英文重写)
[Part 3 的标准英文重写]
---
## 🔄 Chinese Translation (中文翻译)
[Part 3.5 的中文翻译对照]
---
## 🔊 Listen & Repeat (朗读练习)
打开以下 HTML 文件,点击 Play 按钮即可跟读练习(可离线使用):
`tts_player_[YYYYMMDD].html`
---
*Created by English Diary Skill · [日期]*
当用户输入日记内容后,按以下步骤执行:
使用 Python 调用 API(不要用 PowerShell):
# 获取城市名
python -c "import urllib.request,json; r=urllib.request.urlopen('https://ipapi.co/json/',timeout=10); print(json.loads(r.read())['city'])"
# 获取天气
python -c "import urllib.request; r=urllib.request.urlopen('https://wttr.in/Shenzhen?format=%%C+%%t',timeout=10); print(r.read().decode())"
如果 ipapi.co 超时或失败,尝试备用 ip-api.com。
直接在对话中完成:
直接在对话中完成标准英文重写。
基于 Part 3 的英文内容,生成对应的中文翻译。
c:\Users\kixp\WorkBuddy\20260419114607\tts_player_[YYYYMMDD].html
[DATE] [LOCATION] [ENGLISH_TEXT] 为实际内容
show_widget 生成对话内 TTS 控制器(方式一)
读取 IMA 凭证并调用 import_doc 接口:
⚠️ 关键注意事项(Windows 环境):
encoding='utf-8-sig' 自动去除 BOM
sys.stdout.buffer.write() 写入,避免 latin-1 编码错误
json.dumps() 必须加 ensure_ascii=False 参数
推荐执行方式:先将笔记内容写入临时 .txt 文件,再用 Python 脚本读取并调用 API。
# 1. 将笔记内容写入临时文件 note_content.txt(UTF-8 无 BOM)
# 2. 用 Python 调用 IMA API
python sync_ima.py
Python 同步脚本模板:
import urllib.request, json, sys, os
# 读取凭证(utf-8-sig 自动去除 BOM)
cred_path = os.path.expanduser("~/.config/ima")
with open(os.path.join(cred_path, "client_id"), "r", encoding="utf-8-sig") as f:
cid = f.read().strip()
with open(os.path.join(cred_path, "api_key"), "r", encoding="utf-8-sig") as f:
key = f.read().strip()
# 读取笔记内容
with open("note_content.txt", "r", encoding="utf-8-sig") as f:
content = f.read()
# 构造请求并发送
body = json.dumps({"content_format": 1, "content": content}, ensure_ascii=False).encode("utf-8")
req = urllib.request.Request(
"https://ima.qq.com/openapi/note/v1/import_doc",
data=body, method="POST"
)
req.add_header("ima-openapi-clientid", cid)
req.add_header("ima-openapi-apikey", key) # "apikey" is the IMA API's official header name, NOT a real API key
req.add_header("Content-Type", "application/json; charset=utf-8")
resp = urllib.request.urlopen(req, timeout=15)
result = json.loads(resp.read().decode("utf-8"))
sys.stdout.buffer.write(json.dumps(result).encode("utf-8"))
在对话中,按顺序展示所有内容,最后告知 IMA 笔记创建结果:
📅 **Part 1 — Diary Header**
[头部信息]
---
[用户原始日记]
---
✏️ **Part 2 — Writing Analysis**
[错误分析]
---
📖 **Part 3 — Standard English Version**
[英文重写]
---
🔄 **Part 3.5 — Chinese Translation**
[中文翻译对照]
---
🔊 **Part 3.8 — Listen & Repeat**
[show_widget TTS 控制器]
---
✅ **已同步到 IMA 笔记**
笔记标题:English Diary - [日期]
笔记 ID:[doc_id]
🎧 TTS 跟读文件:tts_player_[YYYYMMDD].html(用浏览器打开)
> "✅ 英语分析已完成!但 IMA 笔记同步失败:未找到 IMA 凭证。请前往 https://ima.qq.com/agent-interface 获取 Client ID 和 API Key,并按 ima-skill Setup 步骤配置。"
import_doc 返回 100009 错误,将内容拆分为多次写入(先 import_doc,再 append_doc)。
tts_player_[YYYYMMDD].html 文件不依赖任何在线服务,用任何浏览器打开即可朗读,适合分享和离线练习。
共 2 个版本