Skip to content

Repository files navigation

逢甲大學福星宿舍網路報修 Chatbot

🔧 @chinglin-k 專屬逢甲大學福星宿舍網路智慧客服系統

GitHub Pages Run Validation Unit Tests Version License: MIT

版本 / Version:v1.4.6

最後更新 / Last Updated:2026-09-05


功能特色

  • 📚 網路教學:提供 Windows / Mac 宿舍網路設定 PDF 教學,另有站內 Wi-Fi 機設定教學 Modal(4 步驟圖文說明,v1.4.4 新增)
  • ⚙️ 常見問題:轉接器驅動程式、WiFi 帳號密碼、寢室 WiFi 訊號、冷氣電費儲值等常見問題解答
    • 🎯 支援「子主題精準回覆」:問轉接器只顯示轉接器卡片、問帳密只顯示帳密卡片
  • 🔧 線上報修通報:填寫報修表單自動寫入 Google 試算表(前後端雙重格式驗證:學號 1 字母+7 數字、手機 10 位數字、床號 1 位數字、房號 H/I/G/FA~FF 開頭+1–4 位數字);120 秒內偵測到相同學號+房號+問題描述的重複送出會自動攔截,避免試算表出現重複案件
  • 🔍 報修案件查詢:學生輸入學號即可查詢自己的報修案件狀態(僅顯示安全欄位,不含手機號碼等敏感資訊)
  • 🤖 LLM 語意分析:透過 Gemini API 三層 RPM 分級、共 6 個模型自動備援機制判斷使用者意圖
    • 支援「理解失敗」 vs 「系統錯誤」兩層 fallback 訊息區分
    • Gemini 全部失敗時,降級至內建 19 語系 Rule-based 關鍵字備援分類器,確保國際學生在 LLM 服務中斷時仍能取得基本可用的回覆
  • 🌐 中英雙語介面:前端所有文字均提供中英對照
  • 📊 累積使用人數:顯示系統累積服務人數
  • 📱 手機友善:防止 iOS 打字自動放大;動態 Viewport Height (100dvh) 相容
  • 🛡️ 多層安全防護:
    • 個資與使用者輸入一律透過 POST Body 傳送,不暴露於瀏覽器網址列或伺服器 Log
    • 一次性 Session Token(120 秒有效、用一次即失效)防止偽造請求
    • 裝置級 Client ID (localStorage) + 全域級雙層流量限制(CacheService,涵蓋 classify / report / query / counter_get / counter_increment 五個端點)
    • reCAPTCHA v3 隱形驗證,防止 GAS Web App URL 外洩後遭腳本大量濫用
    • Prompt Injection 防護(長度截斷 500 字、控制字元 / Zero-Width 字元清除、引號隔離)
    • 學號 / 手機 / 床號 / 房號前後端雙重格式驗證,後端一律先必填、後格式
    • XSS 防禦(使用者輸入以 _escapeHTML 轉義 & < > " ',Bot 訊息來自內部常數)
    • 後端例外一律回傳固定錯誤代碼,不外洩原始例外訊息(CWE-209 防護)

🌐 多國語言備援分類器支援 (Multilingual Fallback Classifier)

當 Gemini API 達到配額限制或網路異常時,系統會自動切換至 GAS 本地 Rule-based 關鍵字備援分類器。該分類器支援多達 19 種語言與地區語言 的精準意圖辨識:

編號 語言 / 地區 程式碼標記 / Code 支援範例關鍵字 (Sample Keywords)
1 台灣繁體中文 (Traditional Chinese - Taiwan) zh-TW 報修, 網路孔, 轉接器, WiFi密碼, 教學
2 香港繁體中文 / 粵語 (Traditional Chinese - Hong Kong) zh-HK 報修, 網線插口, 轉接頭, 密碼, 點樣設
3 澳門繁體中文 / 粵語 (Traditional Chinese - Macau) zh-MO 報修, 網絡插座, 轉接器, 密碼, 教學
4 簡體中文 (Simplified Chinese) zh-CN 报修, 网络孔, 转换器, 密码, 教程
5 英文 (English) en repair, broken port, adapter, wifi password, tutorial
6 日文 (Japanese) ja 報修, 壁のポート, 変換アダプタ, パスワード, マニュアル
7 馬來文 (Malay) ms baiki, port dinding, penyesuai, kata laluan, panduan
8 韓文 (Korean) ko 수리, 랜선 포트, 어댑터, 비밀번호, 매뉴얼
9 印尼文 (Indonesian) id perbaiki, port dinding, adaptor, kata sandi, panduan
10 菲律賓文 / 他加祿文 (Filipino / Tagalog) tl ayusin, port sa pader, converter, password, gabay
11 泰文 (Thai) th ซ่อม, พอร์ตผนัง, อะแดปเตอร์, รหัสผ่าน, คู่มือ
12 南非荷蘭文 (Afrikaans) af (南非) herstel, muurpoort, drywer, wagwoord, gids
13 法文 (French) fr (法國 / 布吉納法索) réparer, prise murale, adaptateur, mot de passe, manuel
14 史瓦帝尼文 (siSwati / Swati) ss (史瓦帝尼) kulungisa, libhothi, adaptha, iphasiwedi, sihlahlo
15 越南文 (Vietnamese) vi sửa, cổng mạng, bộ chuyển đổi, mật khẩu, hướng dẫn
16 墨西哥西班牙文 (Spanish - Mexico) es-MX (墨西哥) reparar, puerto de pared, adaptador, contraseña, manual
17 摩西文 / 法文 (Mooré / French) mos (布吉納法索) maane, prise murale, adaptateur, compte, manuel
18 蒙古文 (Mongolian) mn засвар, ханын порт, адаптер, нууц үг, заавар
19 埃及阿拉伯文 (Egyptian Arabic) & 厄瓜多西班牙文 (Spanish - Ecuador) ¹ ar-EG / es-EC تصليح, منفذ حائط, محول, كلمة السر, دليل/reparar, avería, contraseña

¹ 埃及阿拉伯文與厄瓜多西班牙文合併列於同一編號:埃及阿拉伯文有專屬關鍵字(如「مش شغال」), 厄瓜多西班牙文則與第 16 項墨西哥西班牙文共用同一組通用西班牙語關鍵字(西班牙語各地區用詞差異極小), 未另外建置地區專屬詞彙,故合併計為 1 項、不獨立計數。


技術架構

層次 技術 說明
前端 HTML5 + Vanilla CSS + Vanilla JS 無依賴框架,高效原生效能
部署 GitHub Pages 自動部署至 gh-pages 服務
LLM Gemini API 六模型三層 RPM 分級自動備援 透過 GAS 代理,Key 不外露;429 時自動重試切換下一個模型
備援 19 語系 Rule-based 關鍵字分類器 Gemini 全部失敗時降級使用
反濫用 reCAPTCHA v3 + 一次性 Token + 雙層限流 隱形驗證(門檻 0.5),防範 GAS_URL 外洩遭腳本大量發送假報修單
資料 Google 試算表 + Script Properties 案件儲存於試算表,機密與人數儲存於 Script Properties
測試 Node.js node --test + ESLint 純 Node 原生測試框架,透過 gas-mocks.js 單元測試 GAS 邏輯

快速開始

1. Clone 並本地預覽

git clone https://github.com/chinglin-k/FCU_NE_Chat_Bot.git
cd FCU_NE_Chat_Bot
npm install          # 安裝開發依賴(僅供測試 / lint 使用)
npm test             # 執行單元測試套件(含 gas/Code.gs 純函式 Mock 測試)
npm run lint         # 執行 ESLint 檢查(含 gas/**/*.gs)
# 直接用瀏覽器開啟 index.html,或使用 VS Code Live Server 預覽前端

2. 部署 Google Apps Script

  1. 前往 script.google.com,建立新專案
  2. 複製 gas/Code.gs 全部內容貼入
  3. 「專案設定」→「指令稿屬性」→ 新增以下屬性:
    • GEMINI_API_KEY:你的 Gemini API Key
    • SPREADSHEET_ID:你的 Google 試算表 ID
    • RECAPTCHA_SECRET_KEY:你的 reCAPTCHA v3 Secret Key(對應 js/config.js 的 RECAPTCHA_SITE_KEY)
  4. 部署 → 新的部署 → 類型:網頁應用程式
    • 執行身分:我自己
    • 誰可以存取:所有人
  5. 複製 Web App URL

3. 設定前端 GAS URL 與 reCAPTCHA

編輯 js/config.js:

GAS_URL: 'https://script.google.com/macros/s/YOUR_ID/exec',
RECAPTCHA_SITE_KEY: 'YOUR_RECAPTCHA_V3_SITE_KEY',

RECAPTCHA_SITE_KEY 是公開金鑰,設計上就是要放在前端程式碼中,可安全提交至 Git。 對應的 Secret Key 絕對不可放在前端,必須只存在 GAS Script Properties。

4. 啟用 GitHub Pages

GitHub → Settings → Pages → Source: main / (root)


試算表格式

報修案件自動寫入以下欄位:

日期 時間 學號 姓名 房號 床號 手機 可維修時間 問題描述 是否派人 是否完成 備註

文件


已知安全性說明

項目 說明
Gemini API Key 僅儲存於 GAS Script Properties,不寫入程式碼
reCAPTCHA Secret 僅儲存於 GAS Script Properties,不寫入程式碼;前端僅持有公開的 Site Key
報修個資傳輸 全面採 POST Body (text/plain) 傳送,不暴露於瀏覽器網址列或伺服器 Access Log
請求授權 一次性 Session Token(120 秒有效、用一次即失效),配合裝置級 Client ID 做流量限制
流量防護 五組雙層(使用者級+全域級)CacheService 限流:classify 使用者 12/分鐘、全域 60/分鐘;report 使用者 5/分鐘、全域 20/分鐘;query 使用者 10/分鐘、全域 40/分鐘;counter_get 使用者 30/分鐘、全域 120/分鐘;counter_increment 使用者 3/分鐘、全域 500/分鐘(v1.3.1:修復原本使用者級上限 999999 形同不限制的缺陷,並將全域上限由 30 調升為 500,避免新生入住等尖峰時段誤擋合法計數)
濫用防護(報修表單) reCAPTCHA v3 隱形驗證(風險分數門檻 0.5),防止 GAS_URL 外洩後遭腳本大量送出假報修單
學號 / 手機 / 床號 / 房號格式 前端與 GAS 端雙重驗證,且後端一律「先必填、後格式」(學號:1 字母+7 數字;手機:10 位數字;床號:1 位數字;房號:須以 H、I、G、FA~FF 開頭,後接 1–4 位數字,可選一個連字號再接數字)。v1.3.1 修復:舊版後端寫法在欄位為空字串時會整段跳過驗證,等同必填形同虛設,現已修正。v1.4.6:床號/房號後端格式已收緊為與前端完全一致(BUG-BED-01、BUG-ROOM-01),修復前後端寬鬆度不一致、可被繞過前端直接送出不合規格資料的問題
重複送出防護(報修表單) 120 秒內偵測到相同「學號+房號+問題描述前 50 字」的請求(MD5 雜湊比對)直接拒絕並回傳 DUPLICATE_REPORT,防止使用者手滑或腳本在短時間內重複寫入相同案件(v1.4.6 / BUG-DUP-01)
Prompt Injection 輸入截斷 500 字、移除控制字元、Zero-Width 字元、引號隔離輸入
XSS 使用者輸入經 _escapeHTML 處理(含 " ' 轉義);Bot 訊息來自內部常數,僅供內部常數使用 Markdown 渲染
後端欄位驗證 GAS writeReport() 先檢查必填(trim 後不得為空)、再檢查格式、最後截斷長度,三階段皆通過才寫入試算表(v1.3.1 修復必填繞過問題)
錯誤訊息資訊揭露 所有後端例外一律回傳固定代碼 INTERNAL_ERROR,不回傳原始例外內容給前端,避免內部實作細節外洩(CWE-209,v1.3.1 修復)
Git 歷史機密殘留 ✅ 已解除:舊版 commit 曾寫死真實 Spreadsheet ID。main/tag 歷史已用 git-filter-repo 於獨立沙盒環境清除並驗證,已由專案擁有者 force push 完成。該 ID 目前仍可透過 GitHub refs/pull/*/head(已關閉/已合併 PR 的參照)查得——這是 git-filter-repo + force push 的已知限制,無法觸及 PR ref——但專案擁有者已確認完成 Spreadsheet ID 輪替,舊 ID 已失效,故該殘留參照已無實質風險。建議仍可洽 GitHub Support 清除 PR ref 快取以求乾淨,但非急迫項目

授權

@chinglin-k © 2026 — MIT License

About

逢甲大學福星宿舍網路報修 Chatbot (FCU Fuxing Dormitory Network Repair Assistant) — 雙語支援/多國語言備援/GAS後端

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages