尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證正在載入完整 README。 以下為已儲存的摘錄。
1. เปิดลิงก์ expense-tracker-seven-red-52.vercel.app 2. กด "สมัครสมาชิก" แล้วกรอกชื่อ อีเมล และรหัสผ่าน (อย่างน้อย 6 ตัว) 3. เข้าหน้าหลักได้ทันที ไม่ต้องรอยืนยันอีเมลก่อน บนมือถือ: ลองติดตั้งเป็นแอป (วิธีอยู่ที่หัวข้อ 10) แล้วเปิดโหมดเครื่องบิน แอปจะยังเปิดและจดรายการได้ พอกลับมาออนไลน์ ข้อมูลจะซิงค์ขึ้นไปเอง • ข้อมูลเป็นของคุณคนเดียว รายการที่จดจะเห็นได้เฉพาะคนที่ login บัญชีนั้น ผู้ใช้คนอื่นมองไม่เห็น • เก็บบนคลาวด์ (Google Firebase) เปลี่ยนเครื่องหรือล้างเบราว์เซอร์ ข้อมูลก็ไม่หาย แค่ login บัญชีเดิม • ลบได้ทั้งหมด ทดลองเสร็จแล้วถ้าไม่ใช้ต่อ ไปที่ **⚙️ ตั้งค่า → ลบบั檢視完整 README ↗
เว็บแอปจดเงินเข้าออกรายเดือน ใช้ตั้งงบรวมและงบรายหมวด ลงรายการประจำให้อัตโนมัติ จดผ่านแชท LINE ได้ และใช้ได้ตอนไม่มีเน็ต
เปิดใช้: expense-tracker-seven-red-52.vercel.app (ฟรี ไม่มีโฆษณา ใช้ได้ทั้งมือถือและคอม)
ถ้า login ด้วย LINE ระบบจะเปิดหน้าเพิ่มเพื่อนบอทให้ด้วย พอเพิ่มเพื่อนแล้วก็จดผ่านแชทได้เลย ส่วนคนที่สมัครด้วยอีเมล ควรใช้อีเมลจริง เพราะลิงก์รีเซ็ตรหัสผ่านจะส่งไปที่อีเมลนั้น
พิมพ์รายการกับจำนวนเงินในแชทบอท ข้อความเดียวใส่ได้หลายรายการ (ไม่เกิน 10)
ค่าข้าวตอนกลางวัน 50 บาท ค่าน้ำ 100 บาท ค่าเน็ต 20 บาท
บอทจะตอบเป็นการ์ดที่แยกรายการพร้อมหมวดที่เดาได้ แล้วถามว่าเป็นของวันไหน ให้กด วันนี้, เมื่อวาน หรือ เลือกวัน… รายการที่บันทึกแล้วจะขึ้นในหน้าเว็บทันที
ระบุวันในข้อความ: ถ้าพิมพ์วันไว้ต้นข้อความ บอทจะบันทึกทันทีโดยไม่ถาม
| พิมพ์ | ได้วันที่ |
|---|---|
เมื่อวาน ค่าแท็กซี่ 120 | เมื่อวาน (ใช้ วันนี้ และ เมื่อวานซืน ได้ด้วย) |
12/10 ค่าข้าว 50 | 12 ต.ค. ปีนี้ ถ้าวันนั้นยังไม่ถึง จะนับเป็นปีที่แล้ว |
12 ต.ค. ค่าข้าว 50 | เดือนพิมพ์แบบ ต.ค., ตค หรือ ตุลาคม ก็ได้ |
12/10/2569 ค่าข้าว 50 | ใส่ปีเป็น พ.ศ. หรือ ค.ศ. ก็ได้ |
วันในอนาคตจะบันทึกไม่ได้
จำนวนเงิน: เขียนได้หลายแบบ เช่น 50, 50บ., 50.-, ฿50, 1,200, 1.5k (เท่ากับ 1,500) และเลขไทย ๕๐
รายรับ: บอทนับเป็นรายรับเมื่อคำบอกหมวดรายรับ เช่น เงินเดือน 25000 หรือ โบนัส 5000 หรือเมื่อขึ้นต้นด้วย ได้ / รับ เช่น ได้ค่าจ้าง 3000 หรือเมื่อมี + หน้าตัวเลข เช่น +500 ขายของ
คำที่บอทไม่รู้จัก: เช่น ค่าแมว 300 บอทจะให้คุณเลือกหมวดเอง แล้วจำคำนั้นไว้ ครั้งหน้าพิมพ์คำเดิมจะเข้าหมวดเดิมโดยไม่ถาม ถ้าบอทเดาหมวดผิด กด แก้หมวด บนการ์ด บอทก็จะจำหมวดที่แก้ไว้เหมือนกัน (แต่ละคนมีคำที่สอนบอทแยกกัน)
ย้อนรายการ: กด เลิกทำ บนการ์ด รายการทั้งหมดจากข้อความนั้นจะถูกลบ ปุ่มบนการ์ดกดได้ภายใน 7 วัน
คำสั่ง:
สรุป หรือ เดือนนี้ ดูรายรับ รายจ่าย ยอดคงเหลือ และงบที่เหลือของเดือนนี้วิธีใช้ ดูตัวอย่างการพิมพ์บอทรับข้อความได้คนละ 20 ครั้งต่อนาทีและ 300 ครั้งต่อวัน (นับรวมการกดปุ่ม) ถ้าเกิน บอทจะเตือนครั้งเดียวแล้วไม่ตอบจนกว่าจะเริ่มนับรอบใหม่ บอทตอบเฉพาะแชทส่วนตัว ถ้าส่งในกลุ่มบอทจะไม่ตอบ
มีบัญชีอีเมลอยู่แล้ว: อย่ากด login ด้วย LINE เพราะระบบจะสร้างบัญชีใหม่ที่ว่างเปล่า ให้ login ด้วยอีเมล แล้วไปที่ ตั้งค่า → LINE ใส่รหัสผ่านแล้วกด เชื่อมบัญชี LINE หลังจากนั้นรายการที่จดในแชทจะเข้าบัญชีเดิม
ทำตามลำดับนี้แล้วจะเห็นฟีเจอร์หลักครบ
| # | ทำ | จะเห็น |
|---|---|---|
| 1 | ส่วน งบประมาณ → กด ตั้งงบ → ใส่ 15000 → ติ๊ก "ใช้เป็นงบเริ่มต้นทุกเดือน" → บันทึก | แถบงบ และ "ใช้ได้อีกวันละ ... ฿" นับเป็นใบแบงก์ |
| 2 | กด จดรายการ (มือถือ: ปุ่มเขียวล่างจอ / คอม: ปุ่มเขียวท้ายคอลัมน์ซ้าย) → รายจ่าย 60 หมวด อาหาร บันทึก กาแฟ → กด เพิ่มรายการ แล้วทำซ้ำอีกครั้ง | ปุ่มจดด่วน กาแฟ 60 ฿ ขึ้นข้างปุ่มจดรายการ |
| 3 | แตะรายการใดก็ได้ → กด ลบ แล้วกด "เลิกทำ" ที่ด้านล่างจอ | รายการกลับมา |
| 4 | เปลี่ยนวันที่ในฟอร์มเป็นเดือนที่แล้ว แล้วเพิ่มรายจ่ายสัก 2–3 รายการ | ส่วน เทียบกับเดือนก่อน และกราฟ 6 เดือน |
| 5 | ส่วน หมวดหมู่ → กด ตั้งงบหมวด → ใส่ อาหาร 3000 | แถบคืบหน้าของหมวด แตะหมวดเพื่อดูเฉพาะรายการในหมวดนั้น |
| 6 | ส่วน รายการประจำ (กดเพื่อเปิด) → เพิ่มรายการประจำ "ค่าเน็ต" 599 ทุกวันที่ 1 | แอปลงรายการเดือนนี้ให้เอง มีไอคอนลูกศรวนต่อท้าย |
| 7 | พิมพ์ ค่าข้าว 50 ค่าน้ำ 100 ในแชทบอท LINE แล้วกด วันนี้ | สองรายการขึ้นในหน้าเว็บ |
| 8 | กดไอคอนพระจันทร์ มุมขวาบน | โหมดมืด |
บนมือถือ ลองติดตั้งเป็นแอป (วิธีติดตั้ง) แล้วเปิดโหมดเครื่องบิน แอปยังเปิดและจดรายการได้ พอกลับมาออนไลน์ ข้อมูลจะซิงค์ขึ้นไปเอง
ใช้ LINE หรืออีเมลก็ได้ ถ้าสมัครด้วยอีเมล แอปจะส่งอีเมลยืนยันไปให้ ระหว่างนั้นใช้แอปได้ตามปกติ ถ้าลืมรหัสผ่าน ให้กด "ลืมรหัสผ่าน?" ที่หน้าเข้าสู่ระบบ
ปุ่ม ‹ › ด้านบนเลื่อนไปเดือนก่อนหรือเดือนถัดไป ยอดคงเหลือ งบ กราฟ และรายการจะแสดงเฉพาะเดือนที่เลือก กด "กลับไปเดือนปัจจุบัน" เพื่อกลับมาเดือนนี้
ในส่วน งบประมาณ กด "ตั้งงบ" แล้วใส่จำนวนเงิน ติ๊ก "ใช้เป็นงบเริ่มต้นทุกเดือน" ถ้าอยากให้ทุกเดือนใช้งบเท่ากัน ถ้าไม่ติ๊ก งบนั้นจะใช้เฉพาะเดือนที่เลือก
แถบงบบอกสถานะทั้งสีและข้อความ คือ อยู่ในงบ (เขียว), ใกล้เต็มงบ เมื่อใช้เกิน 80% (ทอง) และ เกินงบแล้ว (แดง) ในเดือนปัจจุบัน ขีดดำบนแถบคือวันนี้ ใช้ดูว่าเงินออกเร็วกว่าวันที่ผ่านไปหรือเปล่า แอปบอกด้วยว่าเหลือใช้ได้อีกวันละเท่าไหร่
กด จดรายการ เลือก รายจ่าย หรือ รายรับ ใส่จำนวนเงิน (ทศนิยมได้ เช่น 45.50) แตะเลือกหมวด เปลี่ยนวันที่ถ้าเป็นรายการย้อนหลัง จะใส่บันทึกหรือไม่ใส่ก็ได้ แล้วกด เพิ่มรายการ แอปจำประเภท หมวด และวันที่ไว้ให้ จดหลายรายการติดกันจึงเร็วขึ้น
รายการที่หมวด จำนวนเงิน และบันทึกตรงกัน ถ้าจดซ้ำตั้งแต่ 2 ครั้งใน 60 วัน จะกลายเป็นปุ่ม จดด่วน ข้างปุ่มจดรายการ กดครั้งเดียวลงรายการของวันนี้
แตะรายการเพื่อแก้ไขหรือลบ ช่องวันที่มีปุ่ม วันนี้ / เมื่อวาน ให้กดเร็ว ทุกครั้งที่เพิ่มหรือลบรายการ ปุ่ม "เลิกทำ" จะขึ้นที่ล่างจอประมาณ 5 วินาที
ในส่วน หมวดหมู่ กด "ตั้งงบหมวด" แล้วใส่งบเฉพาะหมวดที่อยากคุม หมวดที่เว้นว่างไว้จะไม่จำกัดงบ งบรายหมวดใช้ค่าเดียวทุกเดือน หมวดที่ใกล้เต็มหรือเกินงบจะขึ้นบนสุด
ใช้กับรายการที่เกิดทุกเดือน เช่น ค่าห้อง ค่าโทรศัพท์ หรือเงินเดือน กดหัวข้อ รายการประจำ แล้วกด "เพิ่มรายการประจำ" ใส่ชื่อ จำนวนเงิน หมวด และวันที่ของทุกเดือน ถ้าเดือนนี้จดรายการนั้นไปแล้ว ให้ติ๊ก "เริ่มเดือนหน้า" จะได้ไม่ลงซ้ำ
พอถึงวันที่ตั้งไว้ แอปจะลงรายการให้ตอนคุณเปิดแอป
ในส่วน รายการ กรองดูทั้งหมด เฉพาะรายจ่าย หรือเฉพาะรายรับได้ และค้นจากชื่อหมวด บันทึก หรือจำนวนเงินได้ กด CSV เพื่อดาวน์โหลดรายการของเดือนนั้น ส่วนการดาวน์โหลดทุกเดือนอยู่ที่หน้าตั้งค่า
คุณจดรายการได้ตามปกติ แอปจะขึ้นแถบ ออฟไลน์อยู่ แล้วซิงค์ให้เมื่อกลับมาออนไลน์ เครื่องนั้นต้องเคยเปิดแอปตอนออนไลน์มาก่อนอย่างน้อยครั้งหนึ่ง การจดผ่านแชท LINE ต้องใช้เน็ต
ปุ่มพระจันทร์ / พระอาทิตย์ มุมขวาบนใช้สลับโหมดมืดกับสว่าง แอปจำค่าที่เลือกไว้
กดปุ่มเฟืองมุมขวาบน
นี่เป็นโปรเจกต์ส่วนตัว ไม่ใช่บริการเชิงพาณิชย์ อย่าใส่ข้อมูลอ่อนไหว เช่น เลขบัญชีธนาคารหรือเลขบัตร ในช่องบันทึก
LINE ที่คุณใช้แชทยังไม่ได้ผูกกับบัญชีในแอป ถ้าคุณใช้บัญชีอีเมล ให้ไปที่ ตั้งค่า → LINE → เชื่อมบัญชี LINE ถ้ายังไม่มีบัญชี ให้กด เข้าสู่ระบบด้วย LINE ที่หน้าเว็บ
LINE หนึ่งบัญชีผูกกับบัญชีแอปได้บัญชีเดียว ส่วนใหญ่เกิดจากเคยกด login ด้วย LINE จนได้บัญชีแยกมาอีกบัญชี ให้ login ด้วย LINE เข้าบัญชีนั้น แล้วลบบัญชีนั้นทิ้งที่หน้าตั้งค่า จากนั้นกลับมาเชื่อม LINE กับบัญชีอีเมลใหม่
ดูในโฟลเดอร์ Spam ก่อน ถ้าไม่เจอ ไปที่ ตั้งค่า → ส่งอีเมลยืนยัน ระหว่างนั้นแอปใช้ได้ทุกฟีเจอร์
ได้ login บัญชีเดียวกันบนมือถือและคอมได้ ข้อมูลอัปเดตตรงกันทันที
ตอนนี้รองรับเฉพาะเงินบาท
เปิด Issue ใน repo นี้ได้ บอกด้วยว่าใช้มือถือหรือคอม และเบราว์เซอร์อะไร
หน้าเว็บใช้ React 19, React Router 7, Bootstrap 5, Chart.js, Firebase Auth กับ Firestore ไอคอนจาก Lucide และฟอนต์ Anuphan กับ Trirong ผ่าน Fontsource
ฝั่ง server (LINE Login และบอท) อยู่ในโฟลเดอร์ api/ เป็น Vercel Functions แบบ ESM (.mjs) ใช้ firebase-admin ออก custom token และเขียน Firestore บอทตอบด้วย reply message ของ LINE อย่างเดียว ไม่ใช้ push จึงไม่กินโควตาข้อความ ตัวแยกข้อความใช้กฎกับพจนานุกรมคำ (api/_lib/parse.mjs, dictionary.mjs) ไม่ได้ใช้ AI
ต้องใช้ Node.js 24 (repo ตรึงไว้ใน .nvmrc และ engines ถ้าใช้ nvm หรือ fnm ให้รัน nvm use หรือ fnm use)
npm install
npm start # หน้าเว็บที่ http://localhost:3000 (ไม่มี /api)
npx vercel dev # หน้าเว็บพร้อม /api (ใส่ค่าลับไว้ใน .env.local)
npm test # เทสต์หน้าเว็บ (Jest)
npm run test:server # เทสต์ฝั่ง server (node --test)
npm run build # build สำหรับขึ้นเว็บจริง
ถ้าจะลอง webhook บนเครื่อง ต้องเปิด tunnel เช่น cloudflared tunnel --url http://localhost:3000 แล้วชี้ Webhook URL ไปที่ tunnel
Vercel build ด้วย CI=true ESLint warning จะทำให้ build พัง ให้รัน npm run build ก่อน push ทุกครั้ง
src/firebase/config.jsfirestore.rules ไปวางที่ Firestore → Rules แล้วกด Publish ถ้าข้ามขั้นนี้ ข้อมูลของผู้ใช้แต่ละคนจะไม่ถูกแยกจากกัน และการลบบัญชีจะพังtransactions (userId ↑, date ↑) และ lineDrafts (userId ↑, expiresAt ↑)https://<โดเมน>/api/auth/line/callback ของทุกโดเมนที่ใช้ (production, URL ของ branch preview และ http://localhost:3000) LINE ไม่รับ wildcard จึงต้องใส่ทีละ URL ให้ตรงทุกตัวอักษรhttps://<โดเมน>/api/line/webhook กด Verify แล้วเปิด Use webhook และออก Channel access token (long-lived)| ชื่อ | ค่า |
|---|---|
LINE_LOGIN_CHANNEL_ID / LINE_LOGIN_CHANNEL_SECRET | จาก LINE Login channel |
LINE_CHANNEL_SECRET / LINE_CHANNEL_ACCESS_TOKEN | จาก Messaging API channel |
FIREBASE_SERVICE_ACCOUNT | เนื้อหาไฟล์ JSON ของ service account ทั้งไฟล์ |
AUTH_COOKIE_SECRET | สุ่มด้วย node -e "console.log(require('crypto').randomBytes(32).toString('base64url'))" |
REACT_APP_LINE_ADD_FRIEND_URL | ลิงก์เพิ่มเพื่อนบอท เช่น https://line.me/R/ti/p/@xxxx |
LINE_LIMIT_PER_MINUTE / LINE_LIMIT_PER_DAY | ไม่ใส่ก็ได้ ค่าเริ่มต้น 20 และ 300 |
ค่า REACT_APP_* ถูกฝังตอน build ถ้าแก้ env ต้อง redeploy ใหม่
ถ้าอยากปรับเกณฑ์จำกัดของผู้ใช้คนเดียว ให้เพิ่ม field limitPerDay หรือ limitPerMinute (ตัวเลข) ในเอกสาร lineUsage/{uid} ใน Firestore ถ้าใส่ 0 คนนั้นจะใช้บอทไม่ได้
main Vercel จะ deploy production ให้เอง ส่วน branch อื่นจะได้ previewทุกโดเมนที่ใช้ LINE Login ต้องเพิ่มไว้ 3 ที่ ไม่อย่างนั้น login จะพัง:
| ที่ | ถ้าลืม |
|---|---|
| Callback URL ของ LINE Login channel | LINE ขึ้น Invalid redirect_uri |
| Google Cloud → APIs & Services → Credentials → browser API key → Website restrictions | หน้าเว็บขึ้น auth/requests-from-referer-...-are-blocked |
| Google Cloud → reCAPTCHA → key ของ App Check → Domains | App Check ขึ้น recaptcha-error |
ใช้ URL ที่ไม่เปลี่ยน คือโดเมน production หรือ URL ของ branch (<โปรเจกต์>-git-<branch>-<ทีม>.vercel.app) ส่วน URL ของ deploy แต่ละครั้งที่มีรหัสสุ่มจะใช้ LINE Login ไม่ได้ ถ้าเปิด Vercel Authentication ไว้ใน Deployment Protection ระบบจะกัน webhook ของ LINE ด้วย ต้องปิดก่อนทดสอบบน preview
vercel.json ส่งทุก path ยกเว้น /api ไปที่ index.html ไม่ cache service-worker.js และตั้ง header ความปลอดภัยรวมถึง CSP
ค่า apiKey ใน src/firebase/config.js เปิดเผยได้ตามปกติของ Firebase ถ้า GitHub แจ้งเตือนเรื่องนี้ไม่ต้องตกใจ ข้อมูลได้รับการป้องกันจาก:
ใช้ firebase-admin เวอร์ชัน 13 ไว้ก่อน เพราะเวอร์ชัน 14 ดึง jose@6 ที่เป็น ESM อย่างเดียว และตัวโหลดของ Vercel Functions require() ไม่ได้ ทุก endpoint ใน /api จะพัง api/_lib/deps.test.mjs เทสต์เรื่องนี้ไว้
src/
├── pages/ Login, Register, Dashboard, Settings, LineCallback (/auth/line)
├── components/ ส่วนประกอบของหน้าเว็บ เช่น BudgetCard, TransactionForm, LineButton, LineSection
├── utils/ โหลดข้อมูล, รายการประจำ, เทียบเดือน, CSV, จัดรูปแบบ, ตัวช่วย LINE Login
├── constants/ รายชื่อหมวดหมู่ (ต้องตรงกับ api/_lib/categories.mjs มีเทสต์คุม)
├── context/ สถานะ login และ toast
└── firebase/ config, ข้อความ error, เพิ่ม/ลบรายการ, เริ่ม LINE Login
api/
├── auth/line/ start.mjs และ callback.mjs ของ LINE Login
├── line/webhook.mjs รับข้อความจากบอท
└── _lib/ ตรรกะทั้งหมด (parse, bot, messages, store, rateLimit ฯลฯ) และเทสต์ *.test.mjs
public/service-worker.js
firestore.rules
| Collection | เก็บอะไร |
|---|---|
transactions/{id} | userId, type (income/expense), amount, category, date, note, recurringId (ถ้ามาจากรายการประจำ) |
budgets/{uid} | budget (งบเริ่มต้น), monthly (งบเฉพาะเดือน เช่น {"2026-10": 15000}), categories (งบรายหมวด) |
recurring/{id} | userId, type, amount, category, note, day, startMonth, lastPosted, active |
lineLinks/{lineUserId} | การผูก LINE กับบัญชี: userId, displayName, linkedAt |
lineDicts/{uid} | คำที่ผู้ใช้สอนบอท: words เช่น {"ค่าแมว": "other"} |
lineDrafts/{messageId} | ข้อความจากแชทที่รอเลือกวันหรือหมวด และ id ของรายการที่บันทึกแล้ว (หมดอายุ 7 วัน) |
lineUsage/{uid} | ตัวนับจำกัดการใช้บอท (หน้าเว็บอ่านไม่ได้) |