報名進度報告程式 (tools/view_signup_number/index.php) 說明文件
此程式主要用於彙整並展示台灣人工智慧學校各項課程與活動的報名進度。它會從多個來源抓取數據,計算統計資訊,並產生網頁報表或發送電子郵件通知。
主要功能
- 數據彙整:
* 從本地 MySQL 資料庫(
view_signup_number與view_signup_number_xlass表)讀取 netiCRM 的報名資料。 * 從 Google Spreadsheets (TSV 格式) 讀取特定活動或較舊的報名資料。 - 統計計算: * 計算總報名人數。 * 計算近 24 小時與近 7 天內的報名人數。 * 根據報名開始與結束時間,預估報名截止時的最終人數。
- 分類展示: * 將活動分為「課程」、「認證」與「活動」三大類。 * 區分進行中與已截止的報名表單。
- 過濾機制: * 自動排除內部工作人員(Staff)的報名記錄,以確保數據準確性。
- 通知功能: * 支援透過電子郵件發送報表(通常由系統排程觸發)。
關聯程式與組件詳細說明
1. 設定與核心檔案
-
wp-config.php* 功能: WordPress 的核心設定檔,同時也被此專案用作全域設定檔。 * 關鍵定義: *TBL_VIEW_SIGNUP_NUMBER: 定義儲存個別報名資料的資料表名稱 (預設為view_signup_number)。 *TBL_VIEW_SIGNUP_NUMBER_XLASS: 定義儲存課程/活動資訊 (如 netiCRM event ID, 開課日期等) 的資料表名稱 (預設為view_signup_number_xlass)。 * 資料庫連線資訊 (DB_HOST, DB_USER, DB_PASSWORD 等)。 -
datasci_helpers.php* 功能: 提供專案共用的輔助函式庫。 * 關鍵函式: *send_mail_base($email_to, $email_subject, $email_content, ...): 負責發送電子郵件的核心函式。它優先使用 Mailgun API 發送郵件,若失敗則嘗試使用 PHPMailer 透過 SMTP 發送。此函式還會將發信紀錄寫入send_mail.log.php。 *post_request: 發送 HTTP POST 請求的輔助函式。 *encoding: 處理郵件標題編碼,避免亂碼。
2. 數據更新機制
-
tools/view_signup_number/insert_data.php* 功能: 接收外部傳入的報名資料並寫入資料庫的 API 端點。 * 運作方式: * 接收 POST 參數:xlass_id(課程ID),user_id(使用者ID),signuptime(報名時間),status(狀態)。 * 檢查資料庫中是否已存在該筆記錄。 * 若存在則更新 (UPDATE),若不存在則新增 (INSERT)。 * 會記錄row_update_time以便後續追蹤資料新鮮度。 -
__crontab__/crontab__update_signup_result.py* 功能: 系統排程腳本 (Crontab),負責自動化抓取 netiCRM 的報名資料。 * 運作流程: 1. 讀取 netiCRM 登入 Cookie (通常由fetch_neticrm_cookie.py產生)。 2. 連線至資料庫讀取需要更新的課程列表 (view_signup_number_xlass)。 3. 模擬瀏覽器行為,使用 Cookie 訪問 netiCRM 後台頁面。 4. 解析頁面 HTML 提取報名者資訊。 5. 呼叫或直接執行資料庫寫入操作 (類似insert_data.php的邏輯)。 -
__crontab__/fetch_neticrm_cookie.py* 功能: 負責登入 netiCRM 並取得 Session Cookie。 * 運作方式: * 接收命令列參數傳入的帳號與密碼。 * 發送 POST 請求至 netiCRM 登入頁面 (https://sted.neticrm.tw/user/login). * 登入成功後,將取得的 Cookies 以 JSON 格式輸出到標準輸出 (stdout),供其他 Python 腳本 (如crontab__update_signup_result.py) 使用。 -
tools/view_signup_number/tampermonkey.js* 功能: 一個使用者腳本 (UserScript),通常安裝在瀏覽器擴充功能 (如 Tampermonkey) 中。 * 用途: 當自動化爬蟲失效或需要即時更新時,工作人員可登入 netiCRM 後台並開啟此腳本。 * 運作方式: * 在 netiCRM 報名搜尋頁面自動執行。 * 遍歷頁面上的報名表格 (tr元素)。 * 擷取user_id,signup_time,status等資訊。 * 透過隱藏的iframe和form自動將數據 POST 到https://edm.aiacademy.tw/tools/view_signup_number/insert_data.php,實現數據同步。
3. 資料清理與維護
-
tools/view_signup_number/mark_dead_data.php* 功能: 清理無效或過期的報名資料。 * 邏輯: * 檢查特定xlass_id的資料。 * 找出該課程最新一筆資料的更新時間 (last_live_data_insert_time)。 * 設定一個容許時間差 (例如 90 分鐘)。 * 如果某筆資料的row_update_time遠早於最新更新時間 (超過容許時間差),則判定該筆資料可能已被刪除或狀態異常,將其標記為is_dead_data=1。 * 這確保了報表不會顯示已經在 CRM 中被刪除的報名記錄。
4. 外部來源與快取
-
tools/view_signup_number/gid/目錄 * 功能: 存放 Google Spreadsheets 數據的快取檔案。 * 內容: 檔案名稱通常對應 Google Sheet 的gid(工作表 ID),內容為 TSV 格式的報名數據。 * 機制:index.php在讀取 Google Sheet 資料時,會判斷是否為「已截止」的活動。如果是已截止活動,會將數據寫入此目錄作為快取,避免重複發送網路請求,加快報表載入速度。
資料儲存與快取規則
1. 資料庫結構 (MySQL)
本系統主要使用兩個資料表來儲存 netiCRM 的相關數據:
-
view_signup_number_xlass(課程/活動主表) * 用途: 定義課程或活動的基本資訊。 * 主要欄位: *xlass_id: 系統內部的唯一識別碼 (對應index.php中的xlass前綴後的數字)。 *neticrm_event_id: 對應 netiCRM 系統中的 Event ID。 *xlass_name: 課程名稱。 *signup_sdate: 報名開始日期。 *signup_edate: 報名結束日期。 -
view_signup_number(報名明細表) * 用途: 儲存個別報名者的狀態。 * 主要欄位: *xlass_id: 關聯到主表的 ID。 *user_id: 報名者的 netiCRM Contact ID (CID)。 *signup_time: 報名時間。 *status: 報名狀態 (如:已報名、取消、候補等)。 *row_update_time: 資料最後更新時間。 *is_dead_data: 標記是否為無效/已刪除資料 (1 為無效)。
2. Google Spreadsheets 快取機制 (gid/ 目錄)
對於非 netiCRM 的歷史資料或特定活動,系統會讀取 Google Spreadsheets。
-
識別方式: * 在
index.php的$ARY陣列中,若項目不包含xlass字串 (例如純數字'1277389115'),則視為 Google Sheet 的 Worksheet ID (gid)。 -
檔案命名規則: * 路徑:
tools/view_signup_number/gid/{gid}.txt* 範例:tools/view_signup_number/gid/1277389115.txt -
快取邏輯: 1. 讀取: 程式優先檢查
gid/目錄下是否存在對應的.txt檔案。若存在,直接讀取內容 (TSV 格式)。 2. 下載: 若檔案不存在,則透過 Google Sheets URL 下載 TSV 資料。 3. 寫入快取: * 若該gid存在於$ary_closed_signup_gid(已截止報名的活動列表) 中,下載後會將內容寫入gid/{gid}.txt,永久快取。 * 若該活動尚未截止,則寫入暫存檔{gid}.temp.txt(位於根目錄),不會存入gid/目錄,確保下次執行時能取得最新數據。
流程圖 (詳細版)
-
前置認證: *
fetch_neticrm_cookie.py→ 取得 Cookie → 存檔/傳遞。 -
數據採集 (兩條路徑): * 路徑 A (自動):
crontab__update_signup_result.py使用 Cookie → 爬取 netiCRM → 寫入 DB。 * 路徑 B (手動): 工作人員瀏覽器 +tampermonkey.js→ 爬取當前頁面 → POSTinsert_data.php→ 寫入 DB。 -
數據清理: *
mark_dead_data.php定期或觸發執行 → 標記 DB 中過時的is_dead_data。 -
報表產生: * 使用者/排程訪問
index.php。 *index.php讀取wp-config.php設定。 * 查詢 MySQL (view_signup_number+view_signup_number_xlass) 取得 CRM 數據。 * 讀取gid/快取或即時抓取 Google Sheets TSV 取得外部數據。 * 過濾 Staff ID (定義於index.php內)。 * 計算統計 (總數, 24h, 7days, 預估值)。 * 生成 HTML 表格。 -
郵件通知: * 若
index.php偵測到特定參數或來源 IP → 呼叫datasci_helpers.php的send_mail_base。 * 透過 Mailgun API 發送 HTML 報表給指定收件人。
查看寄信內容方式:
- 到
edm.aiacademy.tw先登入 wp-admin 後台 - 到
https://edm.aiacademy.tw/tools/view_signup_number/可以看到即時 html 生成結果 - 用
docker exec -it python2.7 python /data/www/edm.aiacademy.tw/__crontab__/crontab__send_signup_result.py可以測試寄送信件功能
另外,要用 Curl 取得 html 回傳資料,可到 debugger 面板,取得 wordpress 登入的 cookie ,然後用這個 command
curl -i --cookie 'wordpress_logged_in_exampleda08c1=cshuai%7C1769653255%7CQ00Vi9bexample' \
'https://edm.aiacademy.tw/tools/view_signup_number/'
相關說明-1.png)