
Orangeapple Class Report
- 1 installs
- Updated June 27, 2026
- mz038197/vanscoding-skills
Runs the OrangeApple class report pipeline: scrape rosters and quiz scores, fix name errors in lesson transcripts, and produce a sandwich-feedback parent report in Obsidian.
About
Automates a multi-stage class report workflow for OrangeApple, pulling student rosters and unit scores, correcting misrecognized names in class-recording transcripts, and generating a parent-facing learning report, storing each stage in Obsidian. A tutor or operator uses it to produce end-of-session parent reports.
- Scrapes rosters and quiz scores via Chrome DevTools MCP
- Requires five confirmed inputs; writes stages to Obsidian CLI
Orangeapple Class Report by the numbers
- 1 all-time installs (skills.sh)
- Ranked #1,983 of 2,715 Automation & Workflows skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mz038197/vanscoding-skills --skill orangeapple-class-reportAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 1 |
|---|---|
| Last updated | June 27, 2026 |
| Repository | mz038197/vanscoding-skills ↗ |
What it does
Runs the OrangeApple class report pipeline: scrape rosters and quiz scores, fix name errors in lesson transcripts, and produce a sandwich-feedback parent report in Obsidian.
Files
橘子蘋果課後學習表現報告
工具需求
- Chrome DevTools MCP:抓取網頁資料
- Obsidian CLI:讀寫筆記(
obsidian指令,需確認 vault 已開啟) - Obsidian Vault:執行
obsidian vault確認當前 vault 路徑
---
開始前:向使用者確認五個必填值
在執行任何階段前,必須先向使用者確認以下五個值,全部缺一不可,不得自行猜測或沿用對話中出現過的舊值:
| 變數 | 說明 | 用途 |
|---|---|---|
{stage_id} | corp 網站的梯次 ID(URL 末段數字,例如 6755) | 階段一抓取梯次資訊的目標 URL |
{classroom_id} | 測驗平台的教室 ID(URL 末段字串,例如 DA5nmYlmnqKKy5usp06e) | 階段三抓取測驗成績的目標 URL |
{開課日期} | 這個梯次的課程開始日期(MMDD 格式) | 梯次資訊筆記的前綴 |
{上課日期} | 本次上課的日期(MMDD 格式) | 逐字稿、測驗、學習表現筆記的前綴 |
{測驗項目清單} | 本次要抓取的測驗名稱(可 1 個或多個,使用者指定) | 階段三的篩選與成績抓取範圍 |
兩個日期可能相同(第一堂課),也可能不同(例如第二堂課:開課日期是 0322,上課日期是 0329)。
`stage_id` 與 `classroom_id` 的取得優先順序:
1. 先嘗試讀取已存在的{開課日期}梯次資訊筆記,若 frontmatter 中有stage_id/classroom_id,直接使用,不需再詢問使用者
2. 若筆記不存在或 frontmatter 缺少這兩個值,再向使用者詢問
若使用者未提供且筆記中也無記錄,必須停下來詢問,不得自行猜測或沿用對話中出現過的舊值。
測驗項目清單必須每次都重新詢問(不同上課日可能不同),不得沿用上一次課程的項目。
---
完整流程(四階段)
進度追蹤:
- [ ] 階段一:確認 "{開課日期}梯次資訊" 筆記(已存在則核對欄位;不存在則抓取並新建)
- [ ] 階段二:修復逐字稿,存入 "{上課日期}修復逐字稿" 筆記
- [ ] 階段三:抓取測驗成績,存入 "{上課日期}課堂測驗" 筆記
- [ ] 階段四:彙整學習表現,存入 "{上課日期}學習表現" 筆記---
階段一:抓取梯次資訊
URL 格式:https://corp.orangeapple.co/stages/{stage_id}
步驟一:檢查筆記是否已存在
obsidian read "file={開課日期}梯次資訊"若筆記已存在 → 確認以下欄位是否齊全(對照必要欄位清單):
- 若有欄位遺漏,補齊後更新筆記
- 若資料完整,跳過本階段,直接進入階段二
若筆記不存在 → 進行步驟二,從網頁抓取並建立新筆記
步驟二:從網頁抓取資料
使用 Chrome DevTools 導航至 URL,取得快照後提取以下欄位:
| 必要欄位 | 說明 |
|---|---|
| 課程名稱 | 梯次所屬課程 |
| 狀態 | 例如 full、開放中 |
| 說明 | 上課時間、堂數、停課資訊 |
| 課程開始日期 / 結束日期 | |
| 線上教室會議室名稱 | |
| 教室名稱 / 地址 | |
| 佈告欄連結 | |
| 學習教練 | |
| 學生名單 | 姓名、年級 |
步驟三:建立筆記
筆記內容除了以上網頁資料外,必須在最前方加入 ID 記錄區塊,格式如下:
---
stage_id: {stage_id}
classroom_id: {classroom_id}
---記錄 stage_id 與 classroom_id 後,下次執行此流程時可直接從筆記讀取,不需要再向使用者詢問這兩個值。
存入路徑:vault 根目錄下的 {開課日期}梯次資訊.md。
學生名單是後續所有階段的姓名對照基準,務必完整保留。
---
階段二:修復逐字稿 → 學生互動分類
從 Obsidian 讀取原始逐字稿:
obsidian read "file={上課日期}原始逐字稿"姓名修復原則
逐字稿為語音轉文字,姓名幾乎全部誤植。對照梯次資訊的學生名單,依同音字規則修復:
| 常見誤植規律 | 說明 |
|---|---|
| 單字同音替換 | 「晨→陳」「鈞→軍」→ 趙晨鈞 變成「陳軍」 |
| 姓省略 / 字序顛倒 | 「辜理紗」→「李莎」(理→李、姓省略) |
| 整體音近 | 「蔡牧燊」→「穆森/木生/穆斯恩」 |
修復時以梯次資訊中的完整正式姓名為準。
互動紀錄提取規則
- 保留:老師點名、稱讚、提問、個別指導、師生對話的內容
- 忽略:純粹講課內容、未涉及特定學生的說明
輸出格式(存入 "{上課日期}修復逐字稿")
## {學生姓名}
1. {互動紀錄描述}
2. {互動紀錄描述}若某學生無個別互動,仍建立該學生的區塊並說明(例如:「僅確認出席,無個別互動紀錄」)。
---
階段三:抓取測驗成績
URL 格式:https://exam.orangeapple.co/classrooms/{classroom_id}
先決條件(必做)
- 開始階段三前,一定要先詢問使用者本次要抓取的測驗項目清單。
- 若使用者尚未明確提供
{測驗項目清單},不得開始抓取成績。 - 僅抓取使用者指定的項目,不得自行加抓或省略。
詢問範例:
請提供本次要抓取的測驗項目清單(可多個),例如:
- 【ITS Python 語法基礎教材】Unit1 資料型態
- 【ITS Python 語法基礎教材】Unit2 變數Chrome DevTools 操作注意事項
測驗平台使用 Material UI Chip 作為篩選按鈕,無法用標準 CSS selector 直接點擊。使用以下腳本操作:
// 點擊指定測驗篩選 Chip
() => {
const chips = document.querySelectorAll('.MuiChip-root');
const target = Array.from(chips).find(c => c.textContent.includes('Unit1 資料型態'));
if (target) { target.click(); return 'clicked: ' + target.textContent.trim(); }
return 'not found';
}提取成績資料
每次切換 Unit 後,用以下腳本從 [role="alert"] 元素提取學生成績:
() => {
const alerts = document.querySelectorAll('[role="alert"]');
const results = [];
for (const alert of alerts) {
const text = alert.textContent;
if (text.includes('作答者') && text.includes('成績')) {
const studentMatch = text.match(/作答者:(.+?)成績/);
const scoreMatch = text.match(/成績:(\d+)/);
if (studentMatch && scoreMatch) {
results.push({ student: studentMatch[1].trim(), score: parseInt(scoreMatch[1]) });
}
}
}
return results;
}依 {測驗項目清單} 對每個指定項目執行,收集完所有資料後,依學生分類整理成績表格,存入 {上課日期}課堂測驗 筆記。
---
階段四:彙整家長學習表現報告
同時讀取修復逐字稿與課堂測驗兩份筆記:
obsidian read "file={上課日期}修復逐字稿"
obsidian read "file={上課日期}課堂測驗"三明治回饋法結構
每位學生的報告依序包含:
1. 測驗成績表格(必須放在最前面) 2. 正面肯定:具體描述課堂中表現好的地方(成績、行為、態度) 3. 改進建議:點出分數偏低的單元,說明該單元的核心觀念是什麼,以及如何補強 4. 鼓勵收尾:依據整體趨勢給出有根據的期許,不誇飾、不悲觀
撰寫原則
- 口吻自然,像人在寫,不使用制式的「非常傑出」「令人印象深刻」等套語
- 若低分有客觀原因(如操作失誤、麥克風問題),在報告中如實說明,避免家長誤解
- 若某學生無課堂互動紀錄,報告內容以成績趨勢為主,不憑空捏造互動
- 建議內容要具體(說明是哪個概念需要補強,而不只是「需要加強」)
成績趨勢判斷
| 趨勢 | 描述方式 |
|---|---|
| 逐步上升 | 說明在課堂中持續吸收,越學越上手 |
| 起伏不定 | 指出哪個單元相對弱,建議針對該單元複習 |
| 整體偏低 | 說明第一堂課內容量大,消化需要時間,鼓勵課後補練 |
---
筆記命名規範
| 筆記 | 日期變數 | 命名格式 | 範例(第二堂課) |
|---|---|---|---|
| 梯次資訊 | {開課日期} | {開課日期}梯次資訊 | 0322梯次資訊 |
| 原始逐字稿 | {上課日期} | {上課日期}原始逐字稿 | 0329原始逐字稿 |
| 修復逐字稿 | {上課日期} | {上課日期}修復逐字稿 | 0329修復逐字稿 |
| 課堂測驗 | {上課日期} | {上課日期}課堂測驗 | 0329課堂測驗 |
| 學習表現 | {上課日期} | {上課日期}學習表現 | 0329學習表現 |
第一堂課:{開課日期}與{上課日期}相同,例如都是0322。
後續堂課:梯次資訊筆記不重新建立(已存在),只需建立當天的逐字稿、測驗、學習表現三份筆記,並從現有的 {開課日期}梯次資訊 讀取學生名單。---
寫入 Obsidian 的方式
由於筆記內容通常包含 Markdown 表格(含 | 符號),不建議用 `obsidian create content=` 直接傳遞內容(特殊字元易出錯)。
正確做法: 1. 直接用 Write 工具將 .md 檔案寫入 vault 路徑 2. 再用 obsidian open "file={筆記名稱}" newtab 開啟確認
Vault 路徑查詢:
obsidian vault info=path