← บทความทั้งหมด
บันทึกการเปลี่ยนแปลง

UnifyPort v1 API พร้อมใช้งานจริงแล้ว: ทุกอย่างในรีลีสเสถียรตัวแรก — UnifyPort

UnifyPort v1 API พร้อมใช้งานจริง (production) แล้ว นี่คือรีลีสเสถียรตัวแรก: หนึ่ง endpoint สำหรับส่ง, เลเยอร์อีเวนต์ Webhook ที่ถูกทำให้เป็นมาตรฐาน และโฟลว์การเชื่อมต่อบัญชีสำหรับทั้งหกช่องทาง — WhatsApp, Telegram, LINE, TikTok, Zalo และ X — ภายใต้ API พื้นผิวเดียว

บทความนี้คือ changelog ของรีลีสนั้น หากคุณรอเวอร์ชันที่สร้างต่อยอดได้โดยไม่ต้องกังวลว่าฐานข้างใต้จะเปลี่ยนแบบ breaking โดยไม่ทันตั้งตัว — นี่แหละคือมัน ด้านล่างคือสิ่งที่ออกมาในรีลีส ไล่ทีละ endpoint พร้อมชื่ออีเวนต์จริง โฟลว์การยืนยันตัวตน และพฤติกรรมด้านความน่าเชื่อถือที่คุณจะได้ทำงานด้วย

หนึ่ง API สำหรับส่ง ครอบคลุมหกช่องทาง

แกนของ v1 คือ endpoint เดียว POST /v1/messages ส่งข้อความตัวอักษรที่ถูกทำให้เป็นมาตรฐานผ่านบัญชี provider ที่คุณเลือก คุณไม่ต้องเรียนรู้ SDK หกชุดหรือรูปแบบ payload หกแบบ — เรียนรู้แค่ชุดเดียว

พฤติกรรมเฉพาะแพลตฟอร์มไม่ได้หายไป แต่ย้ายไปอยู่ในฟิลด์ที่มีโครงสร้างชื่อ provider_data ต้องการตอบกลับข้อความใดข้อความหนึ่ง หรือตั้งค่า parse mode ของ Telegram? สิ่งเหล่านั้นอยู่ใน provider_data (เช่น reply_to และ parse_mode) โดยไม่เปลี่ยนรูปร่างของ request ระดับบนสุด เคสทั่วไปยังคงเรียบง่าย เคสเฉพาะแพลตฟอร์มยังคงทำได้

หกช่องทางที่รองรับคือ WhatsApp, Telegram, LINE, TikTok, Zalo และ X ใน API บัญชี provider ถูกสร้างด้วยชื่ออย่าง telegram, whatsapp, twitter, line และ zalo

ในประเทศไทยที่ LINE เป็นช่องทางหลัก นี่คือจุดสำคัญ: v1 รวมการล็อกอินด้วย QR ของ LINE (URL และ PIN) เข้ากับเลเยอร์อีเวนต์มาตรฐานเดียวกันกับช่องทางอื่น ดังนั้นแม้เริ่มจาก LINE โค้ดประมวลผลหลังจากนั้นก็ใช้ร่วมกับช่องทางอื่นได้

11 อีเวนต์ Webhook มาตรฐาน

อีกครึ่งหนึ่งของ v1 คือเลเยอร์อีเวนต์มาตรฐาน ทุกข้อความจาก provider ทุกการอัปเดตสถานะการส่ง และทุกอีเวนต์วงจรชีวิตของบัญชี จะถูกแปลงเป็นรูปทรง JSON ที่เสถียรแบบเดียว รีลีสนี้มี 11 อีเวนต์มาตรฐาน และ backend ของคุณรับมือทั้งหมดผ่าน handler เดียว

สองตัวที่คุณจะใช้บ่อยที่สุด:

  • message.received — มีข้อความขาเข้ามาถึงบัญชีที่เชื่อมต่ออยู่
  • message.status.updated — สถานะการส่งของข้อความที่คุณส่งไปเปลี่ยนแปลง

อีเวนต์วงจรชีวิตของบัญชีทำให้สถานะการเชื่อมต่อสังเกตได้ แทนที่จะเป็นกล่องดำ:

  • account.auth.required — บัญชีต้องการการล็อกอิน (สแกน QR หรือรหัสยืนยัน)
  • account.auth.succeeded — ล็อกอินสำเร็จ; provider_account_ref ถูกเติมแล้ว และอีเวนต์พกฟิลด์โปรไฟล์มาตรฐานมาด้วย (display_name, picture_url, region, status_message)
  • account.started — รันไทม์ของบัญชีออนไลน์แล้ว
  • account.status.updated — สถานะบัญชีเปลี่ยนแปลง

อีเวนต์ message.received มีหน้าตาเหมือนกันไม่ว่ามาจากช่องทางใดในหกช่องทาง:

{
  "event": "message.received",
  "account_id": "acct_8Q2vK",
  "provider": "line",
  "from": "U4af4980629...",
  "text": "อยากสอบถามสถานะคำสั่งซื้อค่ะ",
  "timestamp": 1749254400,
  "message_id": "line_msg_8f3a2c"
}

เปลี่ยน line เป็น whatsapp หรือ zalo ตรรกะการกำหนดเส้นทางของคุณไม่ต้องแก้แม้แต่บรรทัดเดียว นี่คือเหตุผลทั้งหมดที่เลเยอร์มาตรฐานมีอยู่

การเชื่อมต่อบัญชี: โฟลว์ QR และรหัส

การเชื่อมต่อบัญชีเป็นโฟลว์ของตัวเองใน v1 ออกแบบมาให้สถานะการยืนยันตัวตนเป็นสิ่งที่ Webhook ของคุณเฝ้าดูได้ ไม่ใช่สิ่งที่คุณต้องคอยประคบประหงมเอง

คุณสร้างบัญชีด้วยการ POST ไปที่ endpoint บัญชี โดยเลือก auth_mode ให้ตรงกับรูปแบบการเชื่อมต่อ:

{
  "provider": "whatsapp",
  "auth_mode": "code",
  "provider_data": { "phone": "+66812345678" }
}

สำหรับโฟลว์แบบใช้รหัส หมายเลขโทรศัพท์รูปแบบ E.164 ส่งผ่าน provider_data.phone ค่านี้จะถูกเก็บถาวรไว้บนบัญชีและเล่นซ้ำอัตโนมัติสำหรับการยืนยันตัวตนครั้งถัดไป คุณจึงไม่ต้องส่งซ้ำทุกขั้นตอน การสร้างตัวตน provider ซ้ำจะคืนค่า 409 duplicate_provider_account อย่างชัดเจน แทนที่จะแอบสร้างบัญชีที่สองเงียบ ๆ

สำหรับโฟลว์แบบ QR ข้อมูลรับรองมาถึงแบบอะซิงโครนัสผ่าน Webhook ของคุณ:

  • WhatsApp — เรียก /auth/qr/start เพื่อเริ่มเซสชันอุปกรณ์ โทเค็น QR จะมาถึง Webhook เป็นอีเวนต์ account.auth.required (auth_payload.qr_code คือโทเค็นดิบที่ UI ของคุณต้องเรนเดอร์เป็นภาพ QR) และยังเปิดให้ดึงแบบซิงโครนัสผ่าน /auth/qr/check ได้ด้วย หลังสแกน account.auth.succeeded จะมาถึงพร้อม provider_account_ref ที่ถูกเติม ตามด้วย account.started
  • LINE — URL ของ QR และ PIN มาถึงแบบอะซิงโครนัส ฟังอีเวนต์ account.auth.required หรือ poll /auth/session เพื่ออ่าน auth_payload.url (ภาพ QR) และ auth_payload.pin

URL ของ Webhook ถูกฉีดเข้าโดยอัตโนมัติเมื่อกำหนดค่าบัญชี — การเปลี่ยนสถานะการยืนยันตัวตนและอีเวนต์การล็อกอินมาถึง endpoint เดียวกับข้อความขาเข้า หนึ่ง Webhook ทุกอีเวนต์

เมื่อ account.auth.succeeded มาถึง POST /v1/accounts/{account_id}/runtime/start จะนำบัญชีขึ้นออนไลน์ (เป็น no-op หากรันไทม์ทำงานอยู่แล้ว)

เลเยอร์ควบคุม Webhook

endpoint ของ Webhook ใน v1 เป็นอ็อบเจกต์ระดับเฟิร์สคลาสที่กำหนดค่าได้ ไม่ใช่ฟิลด์ URL เดี่ยวที่ฝังอยู่ในหน้าตั้งค่า

เมื่อสร้างตัวรับ Webhook คุณเลือกได้แม่นยำว่าจะรับอีเวนต์ใด subscribed_events รับชื่ออีเวนต์มาตรฐาน (เช่น message.received, account.status.updated) หรือใช้ ["*"] เพื่อสมัครรับทั้งหมด ชื่ออีเวนต์ที่ไม่รู้จักจะถูกปฏิเสธตั้งแต่ตอนเขียน ไม่ใช่ล้มเหลวเงียบ ๆ ภายหลัง

การลงลายเซ็นมีมาให้ในตัว ใส่ signing_secret แล้วทุกการส่งจะถูกเซ็นด้วย HMAC-SHA256 เพื่อให้ endpoint ของคุณตรวจสอบความถูกต้องได้ ปล่อยว่างไว้ก็เท่ากับปิดการลงลายเซ็นอย่างชัดแจ้ง — เป็นทางเลือกที่จงใจ ไม่ใช่อุบัติเหตุ

พฤติกรรมการลองใหม่เป็นของคุณกำหนด retry_policy.max_attempts เป็นจำนวนเต็มไม่ติดลบ; 0 ปิดการลองใหม่ทั้งหมด ค่าที่ไม่ใช่จำนวนเต็มจะถูกปฏิเสธ แพลตฟอร์มจัดการการส่งซ้ำ endpoint ของคุณเพียงแค่ตอบกลับ

ความน่าเชื่อถือที่กักความปั่นป่วนไว้ในเลเยอร์แพลตฟอร์ม

รีลีสสำหรับ production ต้องมีค่าเริ่มต้นระดับ production และ v1 มาพร้อมสิ่งนั้น การส่งขาเข้าวิ่งผ่านคิวที่มีการจำกัดอัตรา การลองใหม่ idempotency และการแยกความล้มเหลว ดังนั้นความปั่นป่วนฝั่ง provider จึงถูกกักไว้ภายในเลเยอร์แพลตฟอร์ม ไม่ลามไปยังแอปของคุณ

สถานะรันไทม์ของบัญชีก็ถูกทำให้เป็นมาตรฐานเช่นกัน runtime_status รับค่ามาตรฐานของแพลตฟอร์มหนึ่งในแปดค่า — unknown, starting, running, stopping, stopped, reconnecting, disconnected, error — โดยป้ายกำกับเฉพาะ provider จะถูกแมปเข้าชุดนี้ก่อนที่คุณจะเห็น คุณเขียน state machine เดียว ไม่ใช่หกอัน

สำหรับบัญชีที่ต้องการการกำหนดเส้นทางตามภูมิศาสตร์ อ็อบเจกต์ proxy_config (ไม่บังคับ) จะถูกเก็บถาวรพร้อมบัญชีและนำมาใช้โดยอัตโนมัติ

รีลีสนี้มีความหมายอย่างไร

การที่ v1 พร้อมใช้งานจริงคือคำมั่น ไม่ใช่แค่เลขเวอร์ชัน endpoint สำหรับส่ง, 11 อีเวนต์มาตรฐาน, โฟลว์การยืนยันตัวตน และเลเยอร์ควบคุม Webhook คือพื้นผิวเสถียรที่คุณสร้างผลิตภัณฑ์ทับลงไปได้ จุดประสงค์ของ UnifyPort คือทำให้ทีมไม่ต้องสร้างการเชื่อมต่อเดิมซ้ำหกครั้งเสมอมา; v1 คือเวอร์ชันที่พื้นผิวนั้นหยุดขยับ

หากคุณได้อ่านบทความอื่นของเราเรื่องการรับข้อความโดยไม่ต้องเจอแรงเสียดทานของ API ทางการ — รับ WhatsApp ขาเข้าโดยไม่ต้องใช้ API ทางการ, รับข้อความ LINE โดยไม่ต้องมี Official Account, หรือ เปรียบเทียบต้นทุน WhatsApp กับ Telegram — นี่แหละคือ API ที่เส้นทางเหล่านั้นทำงานอยู่บน

เริ่มต้น: สร้าง API key, เชื่อมบัญชีแรกด้วย auth_mode ที่เหมาะกับช่องทาง, ลงทะเบียน endpoint Webhook พร้อม signing_secret, และสมัครรับ message.received ภายในช่วงการทำงานเดียวกัน อีเวนต์ขาเข้าที่ถูกทำให้เป็นมาตรฐานจะเข้ามาถึง backend ของคุณ จากนั้นทุกช่องทางที่เพิ่มเข้ามาก็เป็นโฟลว์เดียวกัน — ไม่ใช่โปรเจกต์การเชื่อมต่อใหม่อีกโปรเจกต์