🔒

หน้านี้ต้องใส่รหัสผ่าน

คอร์ส n8n · ต่อ Chatbot เข้ากับ LINE OA

← กลับหน้าแรก

ต่อ Chatbot เข้ากับ LINE OA

💬

ต่อ Chatbot เข้ากับ LINE OA

คู่มือทีละขั้นตอนแบบละเอียด — คำสั่งครบทั้ง macOS และ Windows พร้อมเส้นทาง n8n Cloud ที่ไม่ต้องใช้ tunnel เลย

n8nLINE OAwebhook macOS/Windows9 บท~90 นาที

บทนี้ต่อยอดจาก คอร์สหลัก (แชทบนหน้าเว็บ) ↗ เปลี่ยนจากหน้าแชทมาเป็น LINE Official Account ซึ่งเป็นช่องทางที่คนไทยใช้จริงมากที่สุด พนักงานไม่ต้องจำ URL ไม่ต้องล็อกอิน แค่แอดเพื่อนแล้วพิมพ์ถามได้เลย

ฝั่งนำเข้าไฟล์ความรู้ (Excel, PDF, Word, TXT, MD, HTML) ยังเหมือนเดิมทุกอย่าง เปลี่ยนเฉพาะฝั่งรับ-ส่งข้อความ

🧭 โครงสร้างที่จะได้
ผังการทำงาน
Line_Webhook → Parse_Line_Event ─┬─ Show_Typing (กิ่งขนาน)
                                 └─ Find_Answer → IF_Use_AI ─┬─ AI_Answer ────┐
                                                             └─ Direct_Reply ─┴→ Send_Line_Reply
🧩 เลือกเส้นทางก่อนเริ่ม
เส้นทาง A: localhostเส้นทาง B: n8n Cloud
ค่าใช้จ่ายฟรีมีค่าบริการรายเดือน
ต้องใช้ tunnelต้องใช้ไม่ต้อง มี URL สาธารณะให้เลย
URL เปลี่ยนบ่อยเปลี่ยนทุกครั้งที่รีสตาร์ท tunnelคงที่ตลอด
ต้องเปิดเครื่องค้างไว้ต้อง ปิดเครื่องบอทตายไม่ต้อง ทำงาน 24 ชม.
อ่านไฟล์ .docxได้ (ตั้ง env var เอง)ไม่ได้ ต้องแปลงเป็น PDF ก่อน
เหมาะกับเรียนรู้ ทดลอง พัฒนาใช้งานจริงในองค์กร

สำหรับการอบรม แนะนำให้ผู้เรียนทำเส้นทาง A ก่อนเพื่อเข้าใจกลไก แล้วค่อยสาธิตเส้นทาง B ให้ดูว่าตอนขึ้นใช้จริงต่างกันอย่างไร

🖼️ ระบบที่จะได้ตอนจบคอร์ส
หน้าจอ n8n แสดง workflow LINE OA ครบทั้ง 23 โหนด แถวบนเป็นการนำเข้าความรู้จากไฟล์หลายสกุล แถวล่างเป็นการรับข้อความจาก LINE แล้วให้ AI ตอบ
หน้าจอจริงหลัง import n8n_Thai_QA_Chatbot_LineOA.json — แถวบนคือฝั่งนำเข้าความรู้ (เหมือนคอร์สหลัก) แถวล่างคือฝั่งใหม่ที่ต่อกับ LINE (Line_Webhook → Parse_Line_Event → Find_Answer → IF_Use_AI → Send_Line_Reply) ตรงกับผังในหัวข้อ “โครงสร้างที่จะได้” ด้านบน
💡 สังเกต: Show_Typing แยกเป็นกิ่งขนานออกจาก Parse_Line_Event ไม่ได้ต่อเรียงตามเส้นหลัก — เหตุผลอยู่ในบทที่ 6 (ถ้าต่อเรียงตามเส้นหลัก บอทจะโชว์ “กำลังพิมพ์...” ช้าเกินไปจนไม่มีประโยชน์)
📦 ไฟล์ประกอบคอร์ส

ไฟล์ความรู้ 6 สกุลเป็นชุดเดียวกับ คอร์สหลัก ↗ — ข้อมูลสมมติของ “บริษัท ตัวอย่าง จำกัด” เอาไปทดลองอัปโหลดผ่าน Production URL ของ workflow ตัว LINE ได้เลย

📚 ไฟล์ทั้งหมด — workflow + ไฟล์ความรู้ตัวอย่าง 6 สกุล

🔎 ตรวจไฟล์ก่อนแจกแล้ว: ไม่มี credential หรือคีย์ใด ๆ ฝังอยู่ใน workflow JSON ทุกจุดที่ต้องใช้โทเคน (Show_Typing, Send_Line_Reply) อ้างอิงผ่านชื่อ credential เท่านั้น ผู้เรียนแต่ละคนต้องสร้าง credential ของตัวเองตามบทที่ 4.1
📎 ไฟล์ .docx ใช้ได้เฉพาะเส้นทาง A (รันบนเครื่อง) — ถ้าทำเส้นทาง B (n8n Cloud) ให้แปลง ระเบียบการลาพนักงาน.docx เป็น PDF ก่อนอัปโหลด ตามที่อธิบายไว้ในบทที่ 3.3

💡 ไฟล์ .docx .pdf .xlsx เป็นไฟล์ไบนารี กดดาวน์โหลดแล้วเปิดด้วยโปรแกรมของตัวเองได้เลย ส่วนไฟล์ข้อความกด ดูเนื้อหา อ่านบนเว็บได้ก่อนโหลด

📚 บทเรียนทั้ง 9 บท

เรียนไปแล้ว 0 จาก 9 บท

เตรียม LINE OA

1.1 สร้าง Channel

  1. เข้า LINE Developers Console แล้วล็อกอินด้วยบัญชี LINE
  2. สร้าง Provider ใหม่ (ชื่อองค์กรหรือชื่อทีม) ถ้ายังไม่มี
  3. ในโปรไวเดอร์นั้น กด Create a new channel → เลือก Messaging API
  4. กรอกข้อมูล: ชื่อ OA, คำอธิบาย, หมวดหมู่, อีเมล แล้วยอมรับเงื่อนไข

1.2 เอา Channel access token

  1. เปิด Channel ที่เพิ่งสร้าง → แท็บ Messaging API
  2. เลื่อนลงล่างสุดหาหัวข้อ Channel access token (long-lived)
  3. กด Issue แล้วคัดลอกเก็บไว้ — token นี้ยาวมากและจะแสดงเต็มครั้งเดียว
🔑 โทเคนนี้คือกุญแจส่งข้อความในนาม OA ของคุณ ห้ามใส่ลงในไฟล์ที่แชร์ต่อ ห้าม commit ขึ้น git

ในแท็บเดียวกันจะมี Channel secret อยู่ด้วย เก็บไว้ก่อน จะได้ใช้ตอนทำระบบจริงในบท 9

1.3 ปิดการตอบกลับอัตโนมัติ

ข้อนี้ลืมกันบ่อยที่สุด และทำให้บอทของเราถูกตอบทับจนงงว่าทำไมไม่ทำงาน

  1. เข้า LINE Official Account Manager (คนละเว็บกับ Developers Console)
  2. เลือก OA ของคุณ → ตั้งค่าการตอบกลับ
  3. ตั้งค่าดังนี้
    • โหมดตอบกลับ: Chat หรือเปิด Webhook
    • การตอบกลับอัตโนมัติ: ปิด
    • ข้อความทักทายเมื่อเพิ่มเพื่อน: ปิด (workflow ของเราทักทายเองแล้ว)

เส้นทาง A: รันบนเครื่อง

2.1 ติดตั้ง n8n

Terminal (macOS)
# ต้องมี Node.js ก่อน ถ้ายังไม่มี
brew install node

npm install -g n8n
PowerShell (Windows)
# ต้องมี Node.js ก่อน ถ้ายังไม่มี
winget install OpenJS.NodeJS.LTS

npm install -g n8n

2.2 เปิดสิทธิ์โมดูล zlib (จำเป็นเฉพาะถ้าจะอ่านไฟล์ .docx)

Terminal (macOS / Linux)
NODE_FUNCTION_ALLOW_BUILTIN=zlib n8n start
PowerShell (Windows)
$env:NODE_FUNCTION_ALLOW_BUILTIN="zlib"
n8n start
Command Prompt (Windows)
set NODE_FUNCTION_ALLOW_BUILTIN=zlib
n8n start

ตั้งแบบถาวรไม่ต้องพิมพ์ทุกครั้ง

Terminal (macOS zsh)
echo 'export NODE_FUNCTION_ALLOW_BUILTIN=zlib' >> ~/.zshrc
source ~/.zshrc
PowerShell (Windows — รันครั้งเดียว)
[Environment]::SetEnvironmentVariable("NODE_FUNCTION_ALLOW_BUILTIN", "zlib", "User")

ตรวจว่าได้ผล สร้าง Code node วางโค้ดนี้แล้วกด Test step ต้องได้ "function"

JavaScript
return [{ json: { ok: typeof require('zlib').inflateRawSync } }];

ถ้ายังไม่ได้ทั้งที่ตั้งค่าแล้ว ให้ลองปิด Task Runner ซึ่งรันโค้ดในโปรเซสแยกและอาจไม่รับตัวแปรนี้ต่อ

Terminal
N8N_RUNNERS_ENABLED=false NODE_FUNCTION_ALLOW_BUILTIN=zlib n8n start

2.3 แก้ปัญหาพอร์ตชนกัน

ตัวแปร environment อ่านตอนโปรเซสเริ่มเท่านั้น ทุกครั้งที่เปลี่ยนค่าต้องปิด n8n ก่อน ถ้าเจอข้อความ port 5678 is already in use

Terminal (macOS / Linux)
kill -9 $(lsof -ti :5678)
PowerShell (Windows)
Get-NetTCPConnection -LocalPort 5678 | Select-Object -ExpandProperty OwningProcess | ForEach-Object { Stop-Process -Id $_ -Force }

2.4 เปิด tunnel

LINE ต้องยิง webhook เข้ามาหาเครื่องเราได้จากอินเทอร์เน็ต และต้องเป็น https ซึ่ง http://localhost:5678 ทำไม่ได้

⚠️ หมายเหตุสำคัญ คำสั่ง n8n start --tunnel ที่เห็นในบทความเก่า ใช้ไม่ได้แล้ว n8n ถอดออกตั้งแต่เวอร์ชัน 2.0 และปิดบริการ tunnel ของตัวเองไปแล้ว ถ้าสั่งไปจะไม่มีอะไรเกิดขึ้นและไม่มี error ให้เห็นด้วย

ใช้ Cloudflare Tunnel แทน ฟรีและไม่ต้องสมัครบัญชี

ติดตั้ง

Terminal (macOS)
brew install cloudflared
PowerShell (Windows)
winget install --id Cloudflare.cloudflared

เปิด tunnel (ใช้ terminal หน้าต่างใหม่ ปล่อย n8n รันค้างในหน้าต่างเดิม)

Terminal
cloudflared tunnel --url http://localhost:5678

รอสักครู่จะได้กล่องข้อความแบบนี้

ผลลัพธ์
+-------------------------------------------------------------+
|  Your quick Tunnel has been created! Visit it at:           |
|  https://colour-context-expectations-gaps.trycloudflare.com |
+-------------------------------------------------------------+
คัดลอก URL เก็บไว้ ห้ามปิดหน้าต่างนี้ ปิดเมื่อไร URL ตายทันที

2.5 บอก n8n ว่า URL จริงคืออะไร

⚠️ ขั้นตอนนี้ห้ามข้าม ถ้าข้ามจะอัปโหลดไฟล์ผ่านฟอร์มไม่ได้ หน้าเว็บจะหมุนค้างแล้วขึ้น error CORS ในคอนโซล

สาเหตุคือ n8n ยังคิดว่าตัวเองอยู่ที่ localhost จึงฝัง URL localhost ลงในหน้าฟอร์มที่ส่งออกไป พอเบราว์เซอร์เปิดหน้าจากโดเมน trycloudflare แล้วยิงกลับไปหา localhost ก็โดนบล็อก

ปิด n8n แล้วสั่งใหม่พร้อมตัวแปรสองตัวนี้

Terminal (macOS / Linux)
kill -9 $(lsof -ti :5678)

export WEBHOOK_URL=https://ใส่-tunnel-url-ของคุณ.trycloudflare.com
export N8N_EDITOR_BASE_URL=https://ใส่-tunnel-url-ของคุณ.trycloudflare.com
NODE_FUNCTION_ALLOW_BUILTIN=zlib n8n start
PowerShell (Windows)
$env:WEBHOOK_URL="https://ใส่-tunnel-url-ของคุณ.trycloudflare.com"
$env:N8N_EDITOR_BASE_URL="https://ใส่-tunnel-url-ของคุณ.trycloudflare.com"
$env:NODE_FUNCTION_ALLOW_BUILTIN="zlib"
n8n start

ตัวแปรสองตัวนี้จำเป็นเสมอเมื่อรัน n8n หลัง tunnel หรือ reverse proxy ไม่ใช่แค่กรณี LINE เพราะทุกฟีเจอร์ที่ n8n ต้องสร้าง URL ให้ตัวเอง — หน้าฟอร์ม หน้าแชท URL ของ webhook — จะยังบอกเป็น localhost อยู่จนกว่าจะตั้งค่านี้

เส้นทาง B: n8n Cloud

เส้นทางนี้สั้นกว่ามาก เพราะไม่ต้องยุ่งกับ tunnel และตัวแปร environment เลย

3.1 สมัครและเข้าใช้งาน

  1. สมัครที่ n8n.io แล้วเลือกแพ็กเกจ (มีช่วงทดลองใช้ฟรี)
  2. จะได้ URL ประจำตัวหน้าตาแบบ https://ชื่อของคุณ.app.n8n.cloud
  3. URL นี้เป็นสาธารณะและใช้ https อยู่แล้ว จึงข้ามหัวข้อ 2.4 และ 2.5 ไปได้เลย

3.2 Import workflow

เมนู WorkflowsImport from File → เลือกไฟล์ n8n_Thai_QA_Chatbot_LineOA.json

3.3 ข้อจำกัดที่ต้องรู้: อ่านไฟล์ .docx ไม่ได้

n8n Cloud ไม่เปิดให้ผู้ใช้ตั้ง environment variable เอง (เอกสารการตั้งค่า NODE_FUNCTION_ALLOW_BUILTIN อยู่ในหมวด self-host เท่านั้น) โหนด Docx_To_Text ที่ต้องใช้โมดูล zlib จึงทำงานไม่ได้

ทางแก้มีสองทาง

ในคอร์ส แนะนำให้บอกผู้เรียนตรง ๆ ว่านี่คือราคาที่จ่ายเพื่อความสะดวกของ managed service — เราแลกอิสระในการตั้งค่าระดับระบบไปกับการไม่ต้องดูแลเซิร์ฟเวอร์

ส่วนสกุลอื่นทั้ง Excel, PDF, TXT, Markdown, HTML ทำงานได้ปกติทุกอย่างบน Cloud

3.4 ข้อดีที่เห็นชัดตอนใช้จริง

ตั้งค่าใน n8n

4.1 สร้าง credential สำหรับ LINE

ออกแบบให้ใช้ credential แทนการฝังโทเคนใน workflow เพราะไฟล์ JSON ต้องแจกให้ผู้เรียน ถ้าฝังไว้ในไฟล์ โทเคนจะรั่วทันทีที่แชร์

  1. เมนู CredentialsAdd credential → ค้นหา Header Auth
  2. กรอก
    • Name (ชื่อ header): Authorization
    • Value: Bearer <วาง channel access token ตรงนี้>
  3. ตั้งชื่อ credential ว่า LINE Channel Access Token แล้วบันทึก
คำว่า Bearer ต้องมี และต้องเว้นวรรคหนึ่งครั้งก่อนโทเคน ถ้าลืมจะได้ 401 ตอนส่งข้อความ

จากนั้นเปิดโหนด Show_Typing และ Send_Line_Reply แล้วเลือก credential นี้ให้ทั้งสองโหนด

4.2 ใส่ OpenAI API key

เปิดโหนด OpenAI_Model → Create new credential → วาง API key → เลือกโมเดล gpt-4o-mini

4.3 Publish และ Activate

n8n เวอร์ชัน 2.0 แยก Save กับ Publish ออกจากกัน ต่างจาก 1.x ที่กด Save แล้วขึ้นใช้งานทันที

  1. กด Save
  2. กด Publish (ปุ่มมุมขวาบน)
  3. เปิดสวิตช์ Active
ถ้าลืม Publish จะเจออาการเปิด URL ฟอร์มแล้วขึ้นว่า Problem loading form และ webhook จะไม่ทำงาน สังเกตได้จากล็อกตอนสตาร์ทที่บอกว่า Processed N draft workflows, 0 published workflows

4.4 นำเข้าไฟล์ความรู้

เปิดโหนด Upload_Knowledge → คัดลอก Production URL จากในโหนด (อย่าพิมพ์เอง เพราะถ้า path ซ้ำกับ workflow อื่น n8n อาจเปลี่ยน path ให้อัตโนมัติ)

เปิด URL นั้นในเบราว์เซอร์ อัปโหลดไฟล์ทีละไฟล์ ครั้งแรกเลือกโหมด "ล้างของเดิมแล้วนำเข้าใหม่" ครั้งต่อไปเลือก "เพิ่มต่อจากของเดิม"

ฐานความรู้ผูกกับ workflow แต่ละตัว ถ้าเคยอัปโหลดใน workflow เวอร์ชันเว็บแล้ว ข้อมูลจะไม่ตามมาที่ workflow ตัว LINE ต้องอัปโหลดใหม่

4.5 ตั้ง Webhook URL ใน LINE

เปิดโหนด Line_Webhook → คัดลอก Production URL

เส้นทางรูปแบบ URL
A (localhost)https://xxxxx.trycloudflare.com/webhook/line-qa-bot
B (n8n Cloud)https://ชื่อของคุณ.app.n8n.cloud/webhook/line-qa-bot
ต้องเป็น /webhook/ ไม่ใช่ /webhook-test/ เพราะตัวหลังใช้ได้เฉพาะตอนกด Test workflow และหมดอายุทันทีที่รับ request แรก

จากนั้นไปที่ LINE Developers Console → Messaging API → Webhook URL → วาง → Update → กด Verify ควรขึ้น Success

อย่าลืมเปิดสวิตช์ Use webhook ให้เป็น Enabled

ทดสอบระบบ

5.1 เช็กลิสต์ก่อนทดสอบ

5.2 กรณีทดสอบ

สแกน QR จากแท็บ Messaging API เพื่อแอด OA เป็นเพื่อน แล้วทดสอบตามนี้

ทดสอบผลที่ควรได้
แอดเพื่อนครั้งแรกข้อความทักทายพร้อมตัวอย่างคำถาม
พิมพ์ /statsจำนวน Q&A และจำนวนท่อนเอกสาร (ไม่เรียก AI)
พิมพ์ /sourcesรายชื่อไฟล์ที่นำเข้าแล้ว
ถาม "ลาคลอดได้กี่วัน"ตอบ 98 วัน (จาก docx หรือ pdf)
ถาม "รหัสผ่านต้องยาวกี่ตัว"ตอบ 12 ตัวอักษร (จาก txt)
ถามต่อว่า "แล้วต้องเปลี่ยนบ่อยแค่ไหน"ตอบ 90 วัน โดยเข้าใจว่ายังพูดเรื่องรหัสผ่าน
ส่งสติกเกอร์บอกว่ารองรับเฉพาะข้อความ
ถาม "ราคาทองวันนี้"บอกว่าไม่มีข้อมูลเรื่องนี้

กรณีที่ 6 คือจุดที่ผู้เรียนมักตื่นเต้นที่สุด เพราะเห็นชัดว่าบอทจำบริบทได้

5.3 ตัวอย่างการสนทนาจริง

แชท LINE จริงกับบอท ถามเวลาเปิดทำการ สวัสดิการ และเรื่องลากิจ
บทสนทนาจริงจากบอทที่เชื่อมกับ LINE OA แล้ว ถ่ายจากเครื่องผู้เรียนคนหนึ่งที่ทำตามคอร์สนี้จนจบ
💡 สังเกต 3 คำถามในภาพ
  • “เปิดกี่โมง” — ตรงกับคำถาม “บริษัทเปิดทำการกี่โมง” ในไฟล์ Excel แค่ระดับคำสำคัญ ไม่ใช่คำต่อคำ แต่บอทก็หาเจอและตอบได้ตรง
  • “มีสสัสดิการอะไรบ้าง” (พิมพ์ตกหล่นด้วย) — ไม่มีแถวไหนในไฟล์ Excel ถามคำถามนี้ตรง ๆ บอทจึงรวมคำตอบจากหลายแถวในหมวด HR และสวัสดิการเข้าด้วยกันเอง นี่คือขั้นตอน AI สังเคราะห์คำตอบ (RAG) ที่อธิบายไว้ในบทที่ 6 ไม่ใช่การหาแถวที่ตรงที่สุดแถวเดียว
  • “ลากิจได้กี่วัน ได้เงินไหม” — ส่วน “3 วันทำการ” มาจากไฟล์ Excel ตรง ๆ แต่ส่วน “ไม่ได้รับค่าจ้าง” เป็นสิ่งที่ AI อนุมานเอง เพราะไฟล์ความรู้ตัวอย่างชุดนี้ (ทั้ง Excel และ .docx) ไม่มีข้อความไหนระบุเรื่องนี้ตรง ๆ — เอกสารบอกแค่ว่าลาป่วย ลาคลอด และลาทหารได้รับค่าจ้าง แต่ไม่ได้พูดถึงลากิจเลย นี่คือตัวอย่างจริงว่า AI สังเคราะห์คำตอบได้ไกลกว่าที่ข้อมูลมีจริง — ถ้าจะเอาไปตอบเรื่องที่มีผลทางกฎหมายหรือการเงิน ควรเขียนคำตอบนั้นให้ชัดเจนในไฟล์ความรู้เอง อย่าปล่อยให้ AI อนุมานเอง

5.4 ถ้าไม่มีอะไรเกิดขึ้น

เปิดเมนู Executions ใน n8n แล้วดูว่ามี execution เข้ามาไหม

เข้าใจโค้ดสำคัญ

6.1 แกะ event ของ LINE

LINE ส่ง webhook มาเป็น array ของ event ไม่ใช่ event เดียว และมีหลายประเภทที่ไม่ต้องตอบ

JavaScript (Parse_Line_Event)
const body = $json.body ?? $json ?? {};
const events = Array.isArray(body.events) ? body.events : [];

const out = [];
for (const ev of events) {
  const replyToken = ev.replyToken || '';
  const userId = ev.source?.userId || ev.source?.groupId || ev.source?.roomId || 'unknown';

  if (ev.type === 'follow') {                    // เพิ่มเพื่อน → ทักทาย
    out.push({ json: { replyToken, userId, question: '', messageType: 'none' } });
    continue;
  }
  if (ev.type !== 'message') continue;            // ข้าม unfollow, join, postback
  if (!replyToken) continue;

  const msg = ev.message || {};
  const question = msg.type === 'text' ? String(msg.text || '').trim() : '';
  out.push({ json: { replyToken, userId, question, messageType: msg.type } });
}
return out;

สามเรื่องที่โค้ดนี้จัดการให้

6.2 กฎของ replyToken ที่ต้องรู้

เอกสารทางการของ LINE ระบุเพิ่มว่า ถ้า LINE ส่ง webhook ซ้ำ (redelivery) token ใหม่จะได้เวลาอีก 1 นาที แต่นับรวมแล้วไม่เกิน 20 นาทีจาก event แรก — และ LINE เตือนไว้เองว่าตัวเลขเวลานี้ไม่ใช่สัญญาที่ตายตัว อาจเปลี่ยนได้ในอนาคต

ถ้าต้องการส่งข้อความหลังจากนั้น ต้องใช้ Push API แทน ซึ่งนับโควตาข้อความ ต่างจาก Reply API ที่ไม่นับ นี่คือเหตุผลที่ระบบนี้ตอบด้วย reply เสมอ

6.3 กับดัก: HTTP Request ลบข้อมูลเดิมทิ้ง

ตอนแรกวาง Show_Typing คั่นระหว่าง Parse_Line_Event กับ Find_Answer ผลคือบอทตอบข้อความทักทายทุกครั้งไม่ว่าจะถามอะไร

สาเหตุคือ โหนด HTTP Request แทนที่ json ของ item ด้วย response ที่ API ตอบกลับมา พอ LINE ตอบ {} ว่าง ๆ กลับมา ข้อมูล question replyToken userId ที่แกะไว้ก็หายหมด Find_Answer เลยเห็นคำถามเป็นค่าว่าง

วิธีแก้คือให้ Show_Typing เป็น กิ่งขนาน แยกออกจากเส้นทางหลัก

ผังการทำงาน
Parse_Line_Event ─┬─ Show_Typing   (จบในตัว)
                  └─ Find_Answer → ...

n8n จะรันกิ่งที่อยู่ลำดับแรกก่อน จุดสามจุดจึงยังขึ้นก่อนที่ AI จะเริ่มคิดเหมือนเดิม

💡 บทเรียนที่ใช้ได้กับทุกโปรเจกต์ ทุกครั้งที่แทรกโหนด HTTP Request กลางเส้นทาง ให้ถามว่าโหนดถัดไปยังต้องใช้ข้อมูลเดิมหรือเปล่า ถ้าใช่ ต้องแยกเป็นกิ่งขนาน หรืออ้างย้อนกลับด้วย $('ชื่อโหนด').item.json แทน $json

6.4 ความจำแยกรายบุคคล

Chat_Memory ใช้ userId ของ LINE เป็นคีย์ แต่ละคนจึงมีบทสนทนาของตัวเอง ไม่ปนกัน ต่างจากเวอร์ชันหน้าเว็บที่ใช้ sessionId ของเบราว์เซอร์

JavaScript
const sessionId = $json.userId ?? $json.sessionId ?? 'default';

userId ของ LINE เป็นค่าคงที่ต่อหนึ่งผู้ใช้ต่อหนึ่ง OA จึงจำข้ามวันได้ด้วย ไม่ใช่แค่ในเซสชันเดียว

ปัญหาที่เจอบ่อย

อาการสาเหตุวิธีแก้
port 5678 is already in usen8n ตัวเดิมยังรันอยู่kill -9 $(lsof -ti :5678)
สั่ง --tunnel แล้วไม่มี URL ขึ้นn8n 2.0 ถอดออกแล้วใช้ cloudflared
ฟอร์มหมุนค้าง + CORS error ในคอนโซลไม่ได้ตั้ง WEBHOOK_URLตั้งตามหัวข้อ 2.5 แล้วรีสตาร์ท
Problem loading formยังไม่ได้ Publishกด Publish
Verify ใน LINE ไม่ผ่านURL ผิด หรือ workflow ไม่ Activeใช้ Production URL จากในโหนด
Verify ผ่านแต่บอทเงียบยังไม่เปิด Use webhookเปิดสวิตช์ใน Messaging API
บอทตอบข้อความสำเร็จรูปของ LINEยังไม่ปิดการตอบกลับอัตโนมัติปิดใน OA Manager
Send_Line_Reply ขึ้น 401โทเคนผิด หรือลืมคำว่า Bearerแก้ที่ credential
Send_Line_Reply ขึ้น 400replyToken หมดอายุหรือถูกใช้ไปแล้วดูว่า AI ใช้เวลานานเกิน 1 นาทีไหม
ถามอะไรก็ตอบข้อความทักทายShow_Typing คั่นเส้นทางหลักแยกเป็นกิ่งขนาน (บท 6.3)
บอทบอกว่ายังไม่มีข้อมูลยังไม่ได้อัปโหลดไฟล์เข้า workflow ตัวนี้อัปโหลดผ่าน Production URL
อ่าน .docx ไม่ได้ไม่ได้ตั้ง zlib หรืออยู่บน Cloudตั้ง env var หรือแปลงเป็น PDF
ข้อความขึ้นสัญลักษณ์ขึ้นบรรทัดใหม่ในตารางของ n8nเป็นแค่วิธีแสดงผลของ n8nไม่ต้องแก้ ใน LINE ขึ้นบรรทัดใหม่ถูกต้อง

ต้นทุนต่อคำถาม

วัดจากระบบจริง คำถามแรกของแต่ละคนใช้ 467 input tokens เมื่อคุยต่อเนื่องจะไต่ขึ้นไปนิ่งที่ประมาณ 750 โทเคนตั้งแต่รอบที่ 6

ใช้ค่าเฉลี่ย 600 โทเคนเป็นตัวเลขวางแผน

ปริมาณค่าใช้จ่ายโดยประมาณ
1 คำถาม0.0042 บาท
1,000 คำถาม~5 บาท
10,000 คำถาม~50 บาท
🏢 องค์กรที่มีพนักงาน 200 คน ถามเฉลี่ยคนละ 3 คำถามต่อเดือน ตกเดือนละประมาณ 3 บาท

คำสั่งพิเศษ (/stats, /sources) และกรณีที่ค้นไม่เจอไม่เรียก AI จึงไม่เสียเงิน ส่วน LINE Messaging API ใช้ Reply API ซึ่งไม่นับโควตาข้อความ ตราบใดที่ไม่ได้ส่ง Push

💵 ตัวเลขบาทคิดที่อัตราแลกเปลี่ยน ณ ตอนเขียน และราคา gpt-4o-mini อยู่ที่ $0.15 / $0.60 ต่อล้านโทเค็น (input/output) — ตรวจกับหน้าราคาทางการก่อนอ้างอิงซ้ำ เพราะทั้งค่าเงินและราคาโมเดลเปลี่ยนได้เสมอ

ก่อนขึ้นจริง

9.1 ตรวจลายเซ็นของ LINE

🔓 ตอนนี้ใครก็ยิง webhook ปลอมเข้ามาได้ ซึ่งหมายถึงคนอื่นใช้โควตา AI ของคุณได้ฟรี ควรตรวจ X-Line-Signature ก่อนขึ้นใช้งานจริง

เปิดโมดูล crypto เพิ่ม

Terminal
NODE_FUNCTION_ALLOW_BUILTIN=zlib,crypto n8n start

แล้วเพิ่ม Code node ต่อจาก Line_Webhook

JavaScript
const crypto = require('crypto');
const sig = $json.headers['x-line-signature'];
const expected = crypto
  .createHmac('SHA256', $env.LINE_CHANNEL_SECRET)
  .update(JSON.stringify($json.body))
  .digest('base64');
if (sig !== expected) throw new Error('ลายเซ็นไม่ถูกต้อง');
return $input.all();

เก็บ Channel secret ไว้ใน environment variable ไม่ใช่ในโค้ด

9.2 ย้ายออกจาก tunnel

Quick tunnel ของ Cloudflare เหมาะกับการทดสอบเท่านั้น URL เปลี่ยนทุกครั้งที่รีสตาร์ท ทางเลือกสำหรับใช้จริงเรียงตามความง่าย

  1. n8n Cloud — ไม่ต้องดูแลอะไรเลย แลกกับข้อจำกัดเรื่อง .docx
  2. VPS + Cloudflare Tunnel แบบ named tunnel — ผูกโดเมนตัวเอง URL คงที่ ตั้ง env var ได้ครบ
  3. VPS + reverse proxy (nginx/Caddy) + SSL — คุมได้ทุกอย่าง แต่ต้องดูแลเอง

9.3 เรื่องที่ควรคิดต่อ

✏️ แบบฝึกหัด
🎯 สรุป

การต่อ LINE OA ไม่ได้ยากที่ตัวโค้ด แต่ยากที่ การตั้งค่ารอบนอก ทั้งเรื่อง tunnel, URL ของ n8n, การ Publish, สวิตช์ใน LINE สองหน้าเว็บ และการปิดการตอบกลับอัตโนมัติ ทุกจุดที่ลืมจะให้อาการ "บอทเงียบ" เหมือนกันหมด ซึ่งเป็นอาการที่หาสาเหตุยากที่สุด

เช็กลิสต์ในบทที่ 5.1 กับตารางในบทที่ 7 จึงเป็นสองส่วนที่ควรพิมพ์แจกผู้เรียนไว้ข้างตัว

ส่วนที่เหลือ — การค้นหาภาษาไทย การตัดท่อนเอกสาร การให้ AI เรียบเรียง — ยกมาจากคอร์สหลักได้ทั้งหมดโดยไม่ต้องแก้อะไรเลย นั่นคือข้อดีของการแยกฝั่งรับข้อความออกจากฝั่งประมวลผลตั้งแต่แรก อยากเปลี่ยนไปใช้ Facebook Messenger, Discord หรือ Telegram ก็เปลี่ยนแค่สามโหนดหัวท้าย

🔗 แหล่งอ้างอิง

ตรวจกับเอกสารทางการเมื่อ กันยายน 2569 — ราคา ฟีเจอร์ และเงื่อนไขบริการภายนอก เปลี่ยนแปลงได้ตลอด ก่อนนำไปสอนควรเปิดเช็กซ้ำจากลิงก์ด้านล่าง

🔗 บทเรียนที่เกี่ยวข้อง