🐥
LINE Chatbot · LIFF Forms · Group Chat

ลูกเจี๊ยบ · Chicken Farm Bot
เตือนคนงาน — บันทึกการให้อาหาร — ทุกอย่างจบใน LINE

LINE chatbot สำหรับฟาร์มไก่สาว ช่วยเจ้าของวางแผนอาหาร 3 มื้อต่อวัน บอทเข้ากลุ่มเตือนคนงานตรงเวลา คนงานกรอกรายงานผ่าน LIFF form ทุกอย่างถูกเก็บลง Google Sheets อัตโนมัติ

Next.js 16 React 19 TypeScript LINE Messaging API LIFF Google Sheets API Vercel cron-job.org

ปัญหาที่เจอ

ทำไมการดูแลให้อาหารฟาร์มไก่สาวถึงต้องการระบบ?

ฟาร์มไก่สาวต้องให้อาหารตรงเวลาวันละ 3 มื้อทุกวัน — ถ้าคนงานลืม ไก่ไม่ได้กิน เจ้าของไม่รู้จนกว่าจะเข้าฟาร์ม ส่วนรายงาน "วันนี้ให้ไปกี่กระสอบ ตายกี่ตัว ป่วยกี่ตัว" จดบนกระดาษบ้าง LINE chat บ้าง สุดท้ายหาย รวมข้อมูลไม่ได้

— Insight จากเจ้าของฟาร์มจริง ก่อนเริ่มทำลูกเจี๊ยบ

เวลาให้อาหารต้องตรงเป๊ะ — แต่ลืมง่าย

ไก่สาวต้องกินตรงเวลา 06:00 / 10:00 / 16:00 ทุกวัน — ถ้าเลื่อนเป็นชั่วโมง production lay ตก ไก่เครียด คนงานจำเองยาก โดยเฉพาะวันหยุดหรือเพิ่งจ้างใหม่

📝

รายงานกระจาย จดมือ-แชต-กระดาษ

"วันนี้ใช้กี่กระสอบ" "ไก่ตายโรงไหนกี่ตัว" — บางคนพิมพ์ในแชต บางคนจดสมุด พอจะรวมรายเดือนหาไม่เจอ เปรียบเทียบมื้อต่อมื้อไม่ได้

📊

เจ้าของไม่รู้ realtime ว่าเกิดอะไรขึ้น

คนงานอาจยังไม่ได้ให้อาหารแต่บอกว่าให้แล้ว — หรือมื้อนี้กินไม่หมดแต่ไม่ได้แจ้ง เจ้าของรู้ตอนเข้าฟาร์มหรือพรุ่งนี้ ซึ่งสายแล้ว

🧐

คนงานไม่อยากใช้แอปใหม่

คนงานฟาร์มคุ้น LINE มาก แต่ไม่อยากโหลดแอปเฉพาะทาง โหลดเสร็จลืม password ลืมว่าใช้ยังไง — UX ต้องอยู่ในที่ที่เขาใช้อยู่แล้ว

📋

เจ้าของอยากดูข้อมูลแบบสเปรดชีต ไม่ใช่ dashboard ลึกๆ

เจ้าของฟาร์มต้องการดูข้อมูลดิบ แก้เองได้ ส่งให้บัญชี/สัตวแพทย์ได้ทันที — ไม่ต้องการ admin panel ที่ซับซ้อน


วิธีแก้ปัญหา

เอาบอทเข้ากลุ่ม LINE ที่คนงานอยู่อยู่แล้ว — เตือนตามเวลา กรอกผ่านฟอร์ม เก็บใน Sheet

🔔

บอทเตือนเข้ากลุ่ม LINE ทุกมื้อ

เพิ่มบอท "ลูกเจี๊ยบ" เข้ากลุ่มฟาร์มที่คนงานอยู่อยู่แล้ว — 05:45 ส่ง bubble พร้อมจำนวนกระสอบที่เจ้าของวางแผน 08:00 ส่ง bubble ให้กรอกรายงาน ครบ 3 มื้อ/วัน

📱

กรอกฟอร์มใน LINE ตรงๆ — ไม่ต้องโหลดแอป

ใช้ LIFF (LINE Front-end Framework) — กดปุ่มใน bubble แล้วเปิดฟอร์มในแอป LINE เลย ไม่ต้องสมัคร ไม่ต้อง login ไม่ต้องโหลดอะไรเพิ่ม

📊

Google Sheet เป็น source of truth

ทุกแผน ทุกรายงาน ทุก log ถูก append ลง Google Sheet — เจ้าของเปิดดูเองได้ แก้ filter sort export เป็น Excel ก็ได้ ไม่ต้องเรียนรู้ระบบใหม่

Confirmation dialog กันกรอกผิด

ก่อน submit ทุกฟอร์ม → modal สรุปข้อมูลทั้งหมด (6 ค่า + วันที่ + รวม) ให้กดยืนยันอีกครั้ง — เพราะคนงานกรอกบนมือถือพลาดง่าย แก้ทีหลังใน Sheet ก็ลำบาก

🎯

เมนูเรียกเฉพาะคำว่า "เมนูหลัก"

บอทอยู่ในกลุ่มที่คนงานคุยกันปกติ — ถ้าตอบทุกข้อความจะรบกวน ใช้ keyword "เมนูหลัก" เป็น trigger เดียว ทำให้บอทเงียบเป็นธรรมชาติเหมือนสมาชิกในกลุ่ม


User Flow

1 วันของลูกเจี๊ยบ — Owner วางแผนตอนกลางคืน บอททำงานเองตลอดวัน

1
🌙

Owner วางแผน

กลางคืน Owner กรอก 3 มื้อ × 2 โรง สำหรับวันรุ่งขึ้น

2
🔔

Bot เตือนคนงาน

05:45 ส่ง bubble จำนวนกระสอบ พร้อมปุ่ม "เริ่มให้อาหาร"

3
📝

คนงานกรอกรายงาน

08:00 bot ส่ง bubble กรอก → คนงานกด → กรอก 6 ช่อง

4
📊

เก็บใน Sheet

ข้อมูลเข้า Sheet ทันที + คำนวณ duration/delay อัตโนมัติ


Tech Stack & Architecture

Stack ที่เลือกเพื่อให้คนเดียวดูแลได้ทั้งระบบ — ไม่มี DB ที่ต้องบริหาร ไม่มี admin UI ที่ต้องสร้าง

คนงาน & Owner — LINE App
Group Chat 1-on-1 Chat LIFF Forms Flex Carousel
LINE Messaging API + Webhook
follow / join message postback pushMessage
Next.js 16 (App Router) — Vercel
/api/webhook /api/scheduler /api/feeding-plan /api/worker-report /api/feed-mixing
Google Sheets (Source of Truth) + cron-job.org
users groups schedules feeding_plan feeding_report reminder_log
ทำไมเลือก stack นี้?

LINE LIFF ทำให้ฟอร์มเปิดในแอป LINE เลย — ไม่ต้องโหลดแอป ไม่ต้อง login เพิ่ม · Google Sheets API เป็น database ที่ Owner เปิดดูเองได้แบบ native — ไม่ต้องสร้าง admin UI แยก · Vercel Hobby ฟรี + auto deploy จาก git push · cron-job.org ฟรี ยิงทุก 1 นาที (Vercel Hobby cron จำกัด 2 jobs/day ไม่พอ) — endpoint ตรวจเวลาเอง ครบ 6 trigger times/day


สิ่งที่สร้าง — 8 ฟีเจอร์หลัก

ครบ loop ตั้งแต่วางแผนถึงเก็บข้อมูล

🍚

กำหนดอาหาร 3 มื้อ (Owner)

Grid table 3 มื้อ × 2 โรง — เห็นพร้อมกันใน 1 viewport พร้อมรวมยอด + confirm dialog ก่อน save 6 rows

📝

กรอกรายงาน (คนงาน)

6 ช่อง (กระสอบ/ตาย/ป่วย × 2 โรง) + note — คำนวณ duration/delay เทียบกับเวลา target อัตโนมัติ

🧪

บันทึกการผสมอาหาร

สูตร + จำนวนที่ผสมได้ + หมายเหตุ — เก็บ log แยก tab เพื่อ track stock

📊

ดูรายงาน (Owner)

การ์ดเปิด Google Sheet ตรงๆ — Owner ดูข้อมูลดิบ filter sort export ได้ทันที

📮

Carousel Menu

Flex carousel 4 cards เรียงตามมุมมอง Owner-first (กำหนด → ผสม → ดูรายงาน → กรอก) — trigger ด้วยคำว่า "เมนูหลัก"

🔔

Instruction & Report Bubble

Flex bubble 2 ชนิด — instruction (พร้อมจำนวนกระสอบ + ปุ่มเริ่ม) และ report reminder (ปุ่มเปิด LIFF กรอก)

🕔

Scheduler + Dedup

endpoint ตรวจเวลา Bangkok ทุกนาที ยิง bubble ตาม schedule + ใช้ reminder_log กัน double-send

👥

Group Chat Support

บอทเข้ากลุ่ม LINE ได้ — register groupId อัตโนมัติตอน join + push ไป group แทน loop users


หน้าตาในกลุ่ม LINE

ตัวอย่าง flow ตอนเช้า — bot ส่ง instruction → คนงานกดเริ่ม

ลูกเจี๊ยบ · 05:45

ใกล้เวลาให้อาหารมื้อเช้า

โรง 1: 3.5 กระสอบ
โรง 2: 3.0 กระสอบ
เริ่มให้อาหารมื้อเช้า

กดปุ่ม "เริ่มให้อาหาร" >

ลูกเจี๊ยบ · 05:48

บันทึกเวลาเริ่มมื้อเช้าแล้ว — เริ่มให้อาหารได้เลยครับ
เมื่อให้เสร็จ กดปุ่ม "กรอกรายงาน" ใน bubble ที่จะส่งมาให้

ลูกเจี๊ยบ · 08:00

ถึงเวลาบันทึกรายงานมื้อเช้า

กรอกจำนวนอาหารจริงและไก่ตาย/ป่วยของแต่ละโรง

กรอกรายงาน

หน้าตาฟอร์ม LIFF

กำหนดอาหาร 3 มื้อ ในหน้าจอเดียว (LIFF Tall size — viewport จำกัด)

🐥 ลูกเจี๊ยบ

กำหนดอาหารแต่ละมื้อ
วันที่ต้องการให้แจ้งเตือน
📅 25 พฤษภาคม 2026 (พรุ่งนี้)
มื้อโรง 1โรง 2
เช้า3.53.0
กลางวัน2.52.0
เย็น3.02.5
รวมทั้งวัน 16.5 กระสอบ
บันทึกแผน

Hack กับปัญหา

6 โจทย์ที่ต้องคิดทางแก้เอง — design constraint + LINE platform limit + serverless quirk

🔽

LIFF Tall size — 6 fields ใน 1 viewport

เลือก LIFF size = Tall (~675px ใช้งานได้) แต่ Owner ต้องกรอก 3 มื้อ × 2 โรง = 6 ช่อง พร้อมกัน ถ้า scroll เยอะ keyboard ขึ้นบัง row ล่าง

แก้: Grid table layout (3 rows × 2 cols) แทน 6 input field แยก — ใช้ vertical space น้อยกว่าครึ่ง + เห็น overview ทั้งวันในที่เดียว + total cell คำนวณ realtime ที่ด้านล่าง
🎯

Bot ในกลุ่ม — ตอบทุกข้อความ = รบกวน

บอทอยู่ในกลุ่มที่คนงานคุยกันปกติ — ถ้าตอบทุก text message (คำสั่ง "สวัสดี" "เมื่อไหร่" ฯลฯ) จะกลายเป็น spam ทันที

แก้: ใน webhook handler — เช็ค event.message.text.trim() === "เมนูหลัก" เป็น trigger เดียว ข้อความอื่น bot เงียบ 100% ผลคือบอทเงียบเป็นธรรมชาติเหมือนสมาชิกในกลุ่ม แค่เรียกตอนจะใช้
👥

Push ไป group ไม่ใช่ loop users

คนงานในกลุ่มไม่ได้ add bot 1-on-1 → LINE block การ pushMessage หา userId ตรงๆ → scheduler ส่ง bubble ให้ทุกคนไม่ได้

แก้: เปลี่ยน design — webhook handle join event บันทึก groupId ลง sheet tab groups → scheduler push ไป groupId (ส่งครั้งเดียว ทุกคนในกลุ่มเห็น) ใน postback ยังจับ userId ของคนกดได้ปกติ — ได้ทั้ง broadcast efficiency + member identification
📅

Timestamp อ่านยาก ใน Sheet

ครั้งแรกเก็บเป็น ISO UTC (2026-05-24T06:55:38.824Z) — Owner เปิด Sheet อ่านไม่รู้เรื่อง ต้องคำนวณ +7 ทุกครั้ง

แก้: formatBangkokTimestamp() ใช้ Intl.DateTimeFormat("sv-SE", { timeZone: "Asia/Bangkok" }) ให้ format YYYY-MM-DD HH:mm:ss ตรงตามเวลาไทยที่ Owner เข้าใจทันที + parseBangkokTimestamp() สำหรับคำนวณ duration/delay กลับเป็น Date + migration script update ข้อมูลเก่าให้เป็น format ใหม่ (idempotent)

Vercel Hobby cron จำกัด 2 jobs/day

ต้องการ trigger 6 ครั้ง/วัน (5:45 / 8:00 / 9:45 / 11:00 / 15:45 / 18:00) — Vercel Hobby plan ให้แค่ 2 cron jobs/day ไม่พอ

แก้: ออกแบบ scheduler endpoint ให้ตรวจเวลาเองภายใน (bangkokNow().time) → ใช้ cron-job.org (ฟรี ยิงทุก 1 นาทีได้) ยิง 1,440 ครั้ง/วัน → endpoint ตอบ due=0 เฉพาะตอนไม่ตรงเวลา (95% ของเวลา) — ไม่เปลือง LINE quota เลย รองรับการเพิ่ม schedule ในอนาคตได้โดยไม่ต้องแก้ cron config
🤯

Next.js 16 Turbopack + bun ทำเครื่องค้าง

ตอน dev — bun dev (Turbopack default) + ngrok + traffic เข้า → MacBook ค้าง kernel panic ต้อง force reboot 2 ครั้งติด

แก้: สลับเป็น next dev --webpack (Next.js 16 ยัง support) — RSS 2.3GB ใช้งานได้ stable + เก็บ Turbopack ไว้ใน script สำรอง dev:turbo สำหรับลองใหม่ตอน upgrade Next.js version ภายหลัง บทเรียน: tech stack ใหม่ๆ ต้องมี fallback path เสมอ

Design Decision ที่ต้องคุยกับลูกค้า

UX trade-off ที่ไม่ได้อยู่ใน playbook — ต้อง explain + decide ร่วมกัน

ในการทำ MVP ทุกตัว trade-off จะเยอะ — ส่ง message ทุกข้อความหรือเฉพาะ keyword? Native date picker หรือ custom? Owner mark group manually หรือ auto-detect? คำตอบที่ "ถูกต้อง" มีหลายแบบ ต้องวางทางเลือกให้ลูกค้าเห็น แล้ว explain trade-off ของแต่ละทาง ไม่ใช่เลือกแทนลูกค้า

🎧
Confirm Dialog

Reusable component ใช้ครบทั้ง 3 ฟอร์ม — สรุปข้อมูลก่อน save

🎯
Keyword Trigger

"เมนูหลัก" เท่านั้น — เงียบในกลุ่ม ไม่รบกวน

📅
Tomorrow Prefill

Date default = today+1 เพราะ Owner วางแผนกลางคืน

🔗
Sheet Card

"ดูรายงาน" = เปิด Google Sheet ตรง ไม่สร้าง dashboard


เราได้อะไรจากโปรเจกต์นี้

5 บทเรียนจากการทำลูกเจี๊ยบ ตั้งแต่ requirement ถึง production

1. ออกแบบให้ "อยู่ในที่ที่ user อยู่อยู่แล้ว" — ไม่ใช่ดึง user มาที่ระบบเรา:

คนงานฟาร์มใช้ LINE อยู่แล้ว เลือก LIFF แทนสร้าง mobile app แยก = ไม่มี friction ในการ adopt — ไม่ต้องโหลดอะไร ไม่ต้องสมัคร ไม่ต้องเรียนรู้ UI ใหม่ บทเรียน: เลือก platform ที่ user คุ้นเคย สำคัญกว่าเลือก stack ที่ developer คุ้นเคย

2. Source of truth ไม่จำเป็นต้องเป็น database:

Google Sheets เป็น "database ที่ Owner เปิดดูเองได้ filter export ส่งให้คนอื่นได้" — สำหรับ MVP ที่มี traffic ต่ำ + Owner เป็น power user spreadsheet อยู่แล้ว Sheets ดีกว่า PostgreSQL ทุกทาง (no admin UI ต้องสร้าง, no migration ต้องคิด, no hosting ต้องจ่าย) บทเรียน: เลือก storage ตาม Owner ไม่ใช่ตาม convention

3. Confirmation dialog เป็น UX safety net ที่ undervalued:

ฟอร์มที่ส่ง 6 rows ทีเดียวลง Sheet → ถ้ากรอกผิดต้องไปแก้ใน Sheet เอง (ลำบาก) ทุกฟอร์มของลูกเจี๊ยบมี ConfirmDialog ที่สรุปทุกค่าก่อน save — เพิ่มเวลากรอก 2 วินาที แต่ลด error rate ลงเยอะ บทเรียน: friction ที่ใส่ในที่ถูกที่ = feature ไม่ใช่ bug

4. Platform constraint บางที force ให้ design ดีขึ้น:

LIFF Tall size จำกัด viewport → บังคับให้ออกแบบ Grid 3×2 แทน 6 stacked inputs → ผลคือ overview ดีกว่ามาก ถ้ามี space เยอะอาจจะ default ไปทำ stacked layout ที่ scroll ยาว บทเรียน: constraint คือ design partner ไม่ใช่ obstacle

5. ทำแล้ว rotate decision ได้ — ไม่ต้อง perfect ครั้งแรก:

ตลอด session: เปลี่ยน ISO timestamp → Bangkok format (พร้อม migration), เปลี่ยน Turbopack → webpack หลังเครื่องค้าง, เปลี่ยน menu trigger จาก always-respond → keyword, เพิ่ม group support หลัง MVP — ทุกการเปลี่ยน document + commit เป็น checkpoint บทเรียน: ทำเร็ว ลอง iterate เร็ว ดีกว่าวางแผนนาน

6
Google Sheet tabs — source of truth
3
LIFF Forms — Owner + Worker
เวลาเตือน/วัน — instruction + report
0
App ที่ user ต้องโหลด
Aw mascot

ลูกเจี๊ยบ · Chicken Farm Bot

LINE chatbot สำหรับฟาร์มไก่สาว ที่จบครบ loop — Owner วางแผน, บอทเตือนคนงานในกลุ่ม LINE, คนงานกรอกรายงานผ่าน LIFF, ทุกอย่างเก็บลง Google Sheet สร้างด้วย Next.js 16 + LINE Messaging API + LIFF + Vercel ใน 1 session

Next.js 16 React 19 TypeScript Tailwind CSS LINE Messaging API LIFF Flex Messages Google Sheets API Vercel cron-job.org bun
Projects