# 自動打卡程式規劃 (web_jobcheck)

## 1. 目標與範圍
- 使用者提供打卡網頁的帳號密碼,程式自動完成「登入 → 點擊打卡按鈕」。
- 提供兩個明確操作:**上班卡**與**下班卡**(各一顆按鈕 / 各一個指令)。
- 手動觸發(不做自動排程),但每次執行後回報**成功 / 失敗通知**。
- 打卡系統類型:一般網頁登入(輸入帳密後點按鈕),**無圖形驗證碼、無 2FA**。

## 1.1 實勘結果(2026-07-08 已於瀏覽器確認)
- 系統:**360dHR 才庫事業群管理系統(femascloud)**,網址 `https://femascloud.com/360dhr/`,公司代碼(slug)= `360dhr`。
- 登入後主頁 `https://femascloud.com/360dhr/users/main` 右上角時鐘下方有兩顆打卡按鈕:
  - **上班卡**:`<input type="button" class="clock_enabled" data-type="S" data-shift="21" data-period="1" value="9:00">`
  - **下班卡**:`<input type="button" class="clock_enabled" data-type="E" data-shift="21" data-period="1" value="18:00">`
  - 差異在 `data-type`:**S = 上班(Start)**、**E = 下班(End)**。
- 打卡機制:按鈕無 `onclick`/`href`,由 jQuery 綁定事件,透過表單 `#UserClockListingForm`(action `/360dhr/users/clock_listing`)以 `$form.serialize()` 送 **AJAX**。
- 技術棧:老式 **jQuery 1.8.3 + Prototype/Scriptaculous**,屬「**重度 JS**」→ 用 Playwright 直接點按鈕最穩;純 PHP cURL 需自行重現 session/序列化參數,較脆弱。
- 登入表單(已實勘確認):表單 `#loginForm`(action `/360dhr/Accounts/login`);帳號 `#user_username`(`data[Account][username]`)、密碼 `#user_passwd`(`data[Account][passwd]`);於密碼欄按 Enter 觸發 `key_login` 送出。
- 注意:登入頁有 `#mfaCodeInput`(MFA 驗證碼欄位),若你的帳號啟用 MFA 則無法全自動,程式會偵測並回報。

## 2. 技術選型
| 項目 | 選擇 | 說明 |
| --- | --- | --- |
| 執行環境 | Node.js (建議 LTS 18/20+) | 你目前是 Windows 環境 |
| 瀏覽器自動化 | Playwright | 內建等待機制,穩定、好維護 |
| 觸發方式 | 本機小型網頁 (兩顆按鈕) + Express | 符合「要有按鈕」的需求 |
| 通知 | 可設定 (Telegram / Email) | 見第 8 節 |
| 設定管理 | `.env` + `config` | 帳密與網址不寫死在程式碼 |

> 註:Playwright 會需要下載瀏覽器核心(`npx playwright install chromium`)。

## 3. 專案結構(預計)
```
web_jobcheck/
├─ .env                 # 帳號密碼、網址、通知金鑰 (不進 git)
├─ .env.example         # 範例設定
├─ .gitignore
├─ package.json
├─ config/
│   └─ selectors.js     # 登入欄位、上班/下班按鈕的 CSS 選擇器
├─ src/
│   ├─ punch.js         # 核心:登入 + 點擊打卡 (吃參數 in/out)
│   ├─ notify.js        # 通知模組 (Telegram / Email)
│   ├─ logger.js        # 記錄執行結果
│   └─ server.js        # 本機網頁 (兩顆按鈕:上班 / 下班)
├─ public/
│   └─ index.html       # 「上班卡」「下班卡」兩顆按鈕的頁面
└─ md/
    └─ plan.md          # 本文件
```

## 4. 運作流程
1. 使用者在瀏覽器打開本機頁面(例如 `http://localhost:3000`),看到兩顆按鈕。
2. 按「上班卡」→ 前端呼叫後端 `POST /punch?type=in`;按「下班卡」→ `POST /punch?type=out`。
3. 後端執行 `src/punch.js`:
   - 用 Playwright 開啟打卡網址。
   - 填入 `.env` 的帳號密碼,送出登入。
   - 依 `type` 點擊「上班」或「下班」按鈕。
   - 擷取頁面上打卡結果文字(或截圖)確認成功。
4. 依結果送出通知(成功 / 失敗),並寫入 log。
5. 前端顯示這次結果。

```mermaid
flowchart LR
  A[本機網頁\n上班/下班按鈕] -->|POST /punch| B[server.js]
  B --> C[punch.js\nPlaywright 登入+點按鈕]
  C --> D{成功?}
  D -->|是| E[notify 成功 + log]
  D -->|否| F[notify 失敗 + log/截圖]
  E --> A
  F --> A
```

## 5. 設定檔 (`.env.example`)
```
PUNCH_URL=https://你的打卡網址
PUNCH_USER=你的帳號
PUNCH_PASS=你的密碼

# 通知方式擇一或多個
NOTIFY_CHANNEL=telegram            # telegram | email | none
TELEGRAM_BOT_TOKEN=
TELEGRAM_CHAT_ID=

# Email (若用 email)
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASS=
MAIL_TO=

# 執行選項
HEADLESS=true                      # 除錯時可設 false 看瀏覽器動作
SERVER_PORT=3000
```

## 6. 核心模組說明
- `config/selectors.js`:集中管理選擇器,方便打卡網頁改版時只改這裡。
  ```js
  module.exports = {
    loginUrl:  'https://femascloud.com/360dhr/',
    mainUrl:   'https://femascloud.com/360dhr/users/main',
    // 登入欄位待實際在登出頁確認後補上
    userInput: 'input[name="data[User][account]"]',   // 帳號(暫定,需確認)
    passInput: 'input[name="data[User][passwd]"]',     // 密碼(暫定,需確認)
    loginBtn:  'input[type=submit], button[type=submit]',
    // 打卡按鈕(已實勘確認)
    punchInBtn:  'input.clock_enabled[data-type="S"]',  // 上班卡
    punchOutBtn: 'input.clock_enabled[data-type="E"]',  // 下班卡
  };
  ```
- `src/punch.js`:接受 `type = 'in' | 'out'`,回傳 `{ success, message, screenshotPath }`。
- `src/notify.js`:依 `NOTIFY_CHANNEL` 送出訊息。
- `src/server.js`:提供 `public/index.html` 與 `POST /punch`。

## 7. 兩顆按鈕的頁面 (`public/index.html`)
- 一顆綠色「上班卡」、一顆橘色「下班卡」。
- 點擊後顯示 loading,完成後顯示「✅ 上班打卡成功 09:01」或「❌ 失敗:原因」。

## 8. 通知功能(你選了要通知)
建議 **Telegram Bot**(免費、設定簡單、即時):
1. 用 @BotFather 建立 bot 取得 `TELEGRAM_BOT_TOKEN`。
2. 取得自己的 `TELEGRAM_CHAT_ID`。
3. 打卡完成後推播結果(含時間、成功/失敗、失敗時附截圖)。

> 備註:Line Notify 已於 2025 年停止服務,不建議使用;若你想用 Email,我改用 SMTP(Nodemailer)。

## 9. 需要你提供 / 我協助取得的資訊
1. **打卡網頁網址(URL)**。
2. 登入欄位與兩顆打卡按鈕的**選擇器**——若你不確定,我可以用 `npx playwright codegen <網址>` 帶你錄製一次操作,自動抓出選擇器。
3. 打卡成功時頁面上會出現的**文字或標記**(用來判斷成功)。
4. 通知方式的金鑰(Telegram token / chat id,或 SMTP 設定)。

## 10. 開發步驟(里程碑)
- [ ] M1 建立專案骨架:`package.json`、安裝 Playwright、`.env.example`。
- [ ] M2 完成 `punch.js` 登入 + 上班/下班點擊(先用 `HEADLESS=false` 驗證)。
- [ ] M3 加上成功判斷與截圖存證。
- [ ] M4 完成 `server.js` + 兩顆按鈕頁面。
- [ ] M5 加上通知模組(Telegram / Email)。
- [ ] M6 加上 log 與錯誤處理,整體測試。

## 11. 風險與注意事項
- **帳密安全**:放在 `.env` 且加入 `.gitignore`,不要提交到版本庫。
- **合規**:自動打卡是否符合公司規定請自行評估;本程式僅用你自己的帳號執行你本可手動完成的操作。
- **網頁改版**:選擇器可能失效,已集中在 `selectors.js` 便於維護。
- **驗證機制變更**:若日後打卡系統加上驗證碼 / 2FA,需另行調整方案。
