適用:使用者說「資料在我的 Google 試算表裡」「大家常問我某某的狀態」,例如器材保養紀錄、衛材存放位置、分機表、值日表(沒有工號的)。
資料留在他原本的試算表,他照常在試算表裡改;工具只負責讓同仁查得到。
什麼時候用這個 skill
- 資料已經在他自己的 Google 試算表(院方帳號擁有、不在共用雲端硬碟),同仁只需要看、查。
- 要讓同仁填資料:不要用這個,改用
form-app(平台資料服務);寫入試算表還沒開放。 - 試算表裡有病患資料(病歷號、身分證、床號對到人)或員工資訊(工號、排班、考核):一級工具不能讀,平台會擋;請他把那些欄位移到另一張不串接的試算表。
- 先看
GET /api/v1/platform/limits的sheets.enabled:false 就是平台還沒開放,照實告訴他。
做法
- 建立應用時
archetype選A、security_level: 1;skills_used填sheet-viewer;開放程度問他(不能是 public/members)。 - 請他給試算表網址、要讀的分頁與範圍(例如「保養紀錄」分頁的 A1:F300)。
- 請他分享給平台:「在試算表按『共用』,加入
<sheets.share_with>,權限選『檢視者』。」並且講清楚:
「分享給平台,就等於讓這個工具的使用者都看得到這一段——平台代他們讀,不看他們自己有沒有試算表的權限。」他同意再往下。
- manifest:
```yaml
sheets:
equipment:
url: https://docs.google.com/spreadsheets/d/<ID>/edit
range: 保養紀錄!A1:F300
data:
collects: [equipment_name, last_service_date, unit] # 照實列出讀到的欄位
```
- 程式用
UberTeach.sheets.read('equipment'),第一列當欄位名稱;內容一律用 `textContent`,不要塞進innerHTML。 - 本機預覽讀不到試算表(
local_preview):用自己編的範例列排版面,不要從試算表複製真實內容進程式碼。 - 發佈試用版後,回應的
sheets是pending:告訴他「審核員核可前只有你和代理人看得到內容,同事會看到『還在等審核』」。
骨架
<!doctype html>
<html lang="zh-Hant">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>器材保養查詢</title>
</head>
<body>
<h1>器材保養查詢</h1>
<label>搜尋 <input id="q" type="search" placeholder="輸入器材名稱"></label>
<p id="note"></p>
<table>
<thead><tr id="head"></tr></thead>
<tbody id="rows"></tbody>
</table>
<script src="https://platform.wanfangai.tw/sdk/v1.js"></script>
<script>
// Made-up rows for the local preview only; never copy the real sheet into the code.
const PREVIEW = [['器材', '上次保養', '負責單位'], ['範例器材 A', '2026-01-01', '範例單位']];
let table = [];
function cell(tag, text) {
const el = document.createElement(tag);
el.textContent = text; // textContent, never innerHTML: the sheet's text must not run as code
return el;
}
function render() {
const [header = [], ...body] = table;
const q = document.getElementById('q').value.trim();
document.getElementById('head').replaceChildren(...header.map((h) => cell('th', h)));
const shown = body.filter((r) => !q || r.some((v) => v.includes(q)));
document.getElementById('rows').replaceChildren(
...shown.map((r) => {
const tr = document.createElement('tr');
tr.append(...header.map((_, i) => cell('td', r[i] ?? '')));
return tr;
}),
);
}
async function load() {
try {
const t = await UberTeach.sheets.read('equipment');
table = t.values;
document.getElementById('note').textContent =
`資料來自試算表「${t.title}」,更新時間 ${new Date(t.fetched_at).toLocaleString('zh-TW')}`;
} catch (err) {
if (err.code === 'local_preview') {
table = PREVIEW;
document.getElementById('note').textContent = '本機預覽:顯示的是範例資料';
} else {
document.getElementById('note').textContent = err.message; // 平台回的中文訊息
}
}
render();
}
document.getElementById('q').addEventListener('input', render);
UberTeach.me().then(load);
</script>
</body>
</html>發佈前檢查
- 他知道「分享給平台=這個工具的使用者都看得到」,而且同意。
data.collects與畫面顯示的欄位一致;沒有病患或員工資訊。- 範例列是編的,不是從試算表抄的。
- 告訴他:之後在試算表改資料,工具最多晚 1 分鐘就會更新;平台每天會檢查這張試算表,有問題會寄信給他。