iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
Build on Google AI

零預算 NGO 數位轉型挑戰:30 天打造智慧訂房系統系列 第 15 篇

【Day 15】通知機制切換(Email / Telegram Bot)、資安強化與系統階段性部署

  • 分享至 

  • xImage
  •  

來到 30 天實作挑戰的中場里程碑(Day 15)!在過去 14 天裡,我們完成了核心預約邏輯、Google Calendar 行程同步、雙模拖拉選取介面,以及 Google Sheets 審計日誌。

今天我們將進行:將原本的通知機制完整切換為 Email(MailApp / Gmail API)與 Telegram Bot,同時進行 環境變數資安防護強化、端到端整合測試(E2E Testing),並示範如何將 Google Apps Script (GAS) 後端與 React 前端 正式部署上線(Production Deployment),為後半程的進階業務邏輯奠定穩固基礎。


一、 全系統架構總覽

經過 15 天的開發,我們的架構實現了無伺服器(Serverless)與完全免費的託管方案:

+---------------------------------------------------------------------+
|                    React 前端應用 (Vercel / Netlify)                 |
|   - 五大場地切換 (A1, A2, B1, B2, 洽談室)                              |
|   - 橫向 7 天 × 縱向時段週日曆 (08:00 - 22:00)                         |
|   - 桌面滑鼠 & 行動裝置觸控雙模 Drag-to-Select 選取                     |
|   - 數據看板 (Admin Dashboard - 使用率視覺化)                          |
+---------------------------------------------------------------------+
                         JSON POST │ (doPost)
                                   ▼
+---------------------------------------------------------------------+
|                   Google Apps Script (GAS) Web API                  |
|   - 業務邏輯與規則驗證 (ValidationService.gs)                          |
|   - 審計日誌模組 (AuditLogService.gs)                                 |
|   - 數據分析引擎 (AnalyticsService.gs)                                |
|   - 雙管道通知模組 (Email & Telegram Bot Notification)                |
|   - 週期性維護與自動清理 (MaintenanceService.gs)                       |
+---------------------------------------------------------------------+
        │                      │                        │
        ▼                      ▼                        ▼
┌───────────────┐    ┌──────────────────┐    ┌──────────────────────┐
│Google Calendar│    │  Google Sheets   │    │ Email / Telegram Bot │
│ (預約行程同步)  │    │ (Audit_Logs 歸檔) │    │  (多管道即時異動通知)   │
└───────────────┘    └──────────────────┘    └──────────────────────┘


二、 Telegram Bot 與 Google Mail API 設定教學

1. Telegram Bot 申請與 Chat ID 取得教學

  • 申請 Telegram Bot(透過 @BotFather):
  1. 在 Telegram 搜尋 @BotFather 並開啟對話。
  2. 輸入 /newbot,依提示設定 Bot 名稱與用戶名(須以 bot 結尾,如 MyRoomBooking_bot)。
  3. 建立成功後,@BotFather 會提供一組 HTTP API Token(如 123456789:ABCdefGHIjklMNO...),請妥善保存。
  • 取得 Telegram Chat ID:
  • 個人 Chat ID: 在 Telegram 搜尋 @userinfobot 並發送訊息即可取得。
  • 群組/頻道 Chat ID: 將 Bot 拉入目標群組並隨意發送訊息,接著訪問 [https://api.telegram.org/bot](https://api.telegram.org/bot)<YOUR_BOT_TOKEN>/getUpdates,在 JSON 中找到 "chat":{"id": -100xxxxxxxxxx},該負數即為群組 Chat ID。

2. Google Mail API / MailApp 設定教學

在 GAS 中寄送 Email 主要有兩種管道:

  • 原生 MailApp(預設推薦): 無需額外設定,授權後即可直接發送(每日免費額度:個人帳號 100 封,Workspace 帳號 1,500 封)。
  • Gmail API(進階擴充服務): 若需自訂發件身分或搭配 GCP 專案,可在 GAS 編輯器左側點擊 「擴充服務 (Services)」 旁的 + 號,新增 Gmail API 並在首次執行時完成授權即可。

三、 環境變數與通知模組改版 (NotificationService.gs)

為避免敏感資訊(如 CALENDAR_ID、SPREADSHEET_ID、TELEGRAM_BOT_TOKEN)硬編碼於原始碼中,我們採用 GAS 的 PropertiesService.getScriptProperties() 進行加密儲存,並全面改用 MailApp 與 Telegram API 處理異動通知。

1. 安全設定環境變數 (EnvSetup.gs)

/**
 * 一次性設定指令碼屬性 (環境變數)
 * 請在 GAS 編輯器中執行一次此函式,設定完成後即可刪除程式碼中的敏感數值
 */
function setupScriptProperties() {
  const scriptProperties = PropertiesService.getScriptProperties();
  
  scriptProperties.setProperties({
    'CALENDAR_ID': 'c_xxxxxxxxxxxxxx@group.calendar.google.com',
    'SPREADSHEET_ID': '1A2b3C4d5E6f7G8h9I0jKLMnOpQrStUvWxYz',
    'ADMIN_EMAILS': 'admin@company.org,manager@company.org',
    'TELEGRAM_BOT_TOKEN': '123456789:ABCdefGHIjklMNOpqrsTUVwxyZ',
    'TELEGRAM_CHAT_ID': '-1001234567890'
  });

  console.log('環境變數設定完畢!');
}

/**
 * 取得環境變數輔助函式
 */
function getEnvConfig() {
  const props = PropertiesService.getScriptProperties().getProperties();
  return {
    CALENDAR_ID: props.CALENDAR_ID,
    SPREADSHEET_ID: props.SPREADSHEET_ID,
    ADMIN_EMAILS: props.ADMIN_EMAILS ? props.ADMIN_EMAILS.split(',') : [],
    TELEGRAM_BOT_TOKEN: props.TELEGRAM_BOT_TOKEN,
    TELEGRAM_CHAT_ID: props.TELEGRAM_CHAT_ID
  };
}

2. 雙管道通知核心邏輯 (NotificationService.gs)

/**
 * 系統通知發送函式 (Email + Telegram Bot)
 * @param {string} subject 通知標題
 * @param {string} contentText 通知內文
 * @param {string} recipientEmail 預約者 Email (選填)
 */
function sendSystemNotification(subject, contentText, recipientEmail = null) {
  const config = getEnvConfig();

  // 1. 發送 Email 給預約者 (使用 GAS 內建 MailApp)
  if (recipientEmail) {
    try {
      MailApp.sendEmail({
        to: recipientEmail,
        subject: `【場地預約系統】${subject}`,
        body: contentText
      });
    } catch (err) {
      console.error('Email 發送失敗:', err);
    }
  }

  // 2. 發送 Telegram 廣播至指定群組/頻道
  if (config.TELEGRAM_BOT_TOKEN && config.TELEGRAM_CHAT_ID) {
    try {
      const url = `https://api.telegram.org/bot${config.TELEGRAM_BOT_TOKEN}/sendMessage`;
      UrlFetchApp.fetch(url, {
        method: 'post',
        contentType: 'application/json',
        payload: JSON.stringify({
          chat_id: config.TELEGRAM_CHAT_ID,
          text: `📢 *${subject}*\n\n${contentText}`,
          parse_mode: 'Markdown'
        }),
        muteHttpExceptions: true
      });
    } catch (err) {
      console.error('Telegram 通知發送失敗:', err);
    }
  }
}


四、 端到端整合測試矩陣 (E2E Testing Checklist)

部署前,需依照下表完成 6 大核心情境驗證,確保系統防呆、通知管道與業務邏輯無誤:

測試編號 測試情境 操作步驟 預期結果 狀態
TC-01 正常預約 選擇會議室 A1,選取 09:00~11:00 提交預約。 1. API 回傳 SUCCESS2. Google Calendar 產生行程3. Audit_Logs 紀錄 CREATE4. 寄出 Email 確認信與 Telegram 群組通知 🟩 PASS
TC-02 時段重疊攔截 另一使用者嘗試預約 A1 的 10:00~12:00。 1. 前端該時段顯示已被佔用2. 若由 API 提交,後端退回 CONFLICT 🟩 PASS
TC-03 每日上限防護 同一 Email 嘗試單日預約累計超過 14 小時。 後端觸發 validateBookingRules 並拒絕預約 🟩 PASS
TC-04 自主取消 預約者發起預約取消請求。 1. Calendar 行程刪除2. Audit_Logs 寫入 CANCEL3. 寄送 Email 與 Telegram 取消通知 🟩 PASS
TC-05 跨邊界選取截斷 拖拉 08:00~12:00,但中間 10:00~10:30 已被佔用。 系統自動截斷,僅保留 08:00~10:00 🟩 PASS
TC-06 使用率分析 管理員調用分析報表 API。 正確輸出各場地之預約總時數與使用率 (%) 🟩 PASS

五、 階段性正式部署 (Production Deployment Step-by-Step)

步驟 1:發布 GAS 後端 Web API

  1. 開啟 GAS 專案編輯器,點擊右上角 「部署 (Deploy)」 $\rightarrow$ 「新增部署作業 (New deployment)」。
  2. 點擊齒輪圖示,選擇 「網頁應用程式 (Web App)」。
  3. 填寫部署設定:
  • 說明: v1.0.0 Production (Email/Telegram Bot Integration)
  • 執行身份: 我 (Me)(確保 GAS 能存取 Calendar、Sheets 與 MailApp)
  • 誰有存取權限: 任何人 (Anyone)
  1. 點擊 「部署」 完成授權,並複製獲得的 Web App URL。

步驟 2:建置與託管 React 前端

  1. 配置環境變數 (.env.production):
VITE_GAS_API_URL=https://script.google.com/macros/s/YOUR_DEPLOYMENT_ID/exec

  1. 打包與部署至託管平台(以 Vercel 為例):
npm run build
npx vercel --prod


六、 半程回顧

至今我們已建構出具備預約衝突防護、雙模 UI、審計日誌與 Email/Telegram 通知的穩定系統。接下來的 15 天,我們將引入更複雜的企業級管理機制。


上一篇
【Day 14】資料留痕與審計日誌:實作 Google Sheets 審計日誌 (Audit Log) 與場地使用率統計分析
下一篇
【Day 16】Google OAuth / SSO 身分驗證、Google Cloud 設定與全功能角色權限控制(RBAC)
系列文
零預算 NGO 數位轉型挑戰:30 天打造智慧訂房系統 共 17 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言