Skip to main content

API สาธารณะสำหรับผู้ใช้ปลายทาง

ภาพรวม

โมดูล publicmod รวม endpoint ที่ผู้ใช้ LINE ทั่วไปเรียกได้โดยไม่ต้องล็อกอินเข้า CMS ผู้บริโภคหลักคือ client-web ซึ่งใช้ตอน render หน้าคอนเทนต์และเมนูที่ถูกแชร์ผ่าน LINE

เนื่องจากเปิดให้เข้าถึงแบบสาธารณะ endpoint กลุ่มที่คืนรายการคอนเทนต์จึงถูกครอบด้วย rate limit ที่ 10 ครั้งต่อ 60 วินาที ส่วน endpoint ที่เข้าถึงด้วย token ไม่ถูกจำกัด เพราะตัว token เองเดาไม่ได้อยู่แล้ว

โมดูลนี้ยังรองรับ LIFF โดยคืน config ให้ client-web ใช้ initialize LIFF และรับ header x-liff-token เพื่อระบุตัวผู้ใช้ LINE ที่กำลังเปิดหน้าอยู่

Business Flow

เรียกดูรายการคอนเทนต์

  1. GET /api/public/contents พร้อม query ตาม PublicContentQueryDto คืนรายการคอนเทนต์ที่เผยแพร่แล้ว ในรูปแบบที่มี field data, total, page, limit และ totalPages โดยถูก throttle ที่ 10 ครั้งต่อ 60 วินาที
  2. GET /api/public/contents/categories พร้อม query lineOaId คืนรายการหมวดหมู่ที่มีคอนเทนต์อยู่ ถูก throttle เช่นเดียวกัน

เปิดด้วย token

  1. GET /api/public/menu/:token เปิดเมนูที่สร้างจาก Menu Builder
  2. GET /api/public/content/:token/liff-config คืน LIFF config ของหน้านั้น เพื่อให้ client-web เรียก liff.init() ก่อนโหลดเนื้อหา
  3. GET /api/public/content/:token พร้อม query password เปิดหน้าคอนเทนต์
    • หากส่ง header x-liff-token มาด้วย ระบบจะใช้ระบุตัวผู้ใช้ LINE เพื่อบันทึกการเข้าชมแบบระบุตัวตนได้
    • หน้าที่ตั้งรหัสผ่านไว้ต้องส่ง password ให้ถูกต้อง
    • หากไม่พบหน้าหรือหน้ายังไม่เผยแพร่จะได้ error APP_007

ข้อควรรู้เรื่อง soft delete

  1. ตาราง content_page, content_category และ content_subcategory ใช้คอลัมน์ deleted_date ธรรมดา service จึงต้องใส่ predicate กรองแถวที่ถูกลบเอง เพราะ TypeORM ไม่ได้กรองให้อัตโนมัติ
  2. ตาราง line_oa มี @DeleteDateColumn จริง GORM จึงกรองให้อัตโนมัติ ส่วนเงื่อนไข deletedAt: IsNull() ที่ปรากฏใน where ของโค้ด TypeScript เดิมชี้ไปยัง property ที่ไม่มีอยู่จริง จึงเป็น no-op

ไฟล์และฟังก์ชันหลัก

โค้ดอยู่ที่ internal/modules/publicmod/ ประกอบด้วย controller.go, service.go, liff.go และ dto.go

MethodRouteHandlerGuard
GET/api/public/contentsct.listPublicContentspublic + Throttle(10, 60000)
GET/api/public/contents/categoriesct.listPublicCategoriespublic + Throttle(10, 60000)
GET/api/public/menu/:tokenct.getMenuByTokenpublic
GET/api/public/content/:token/liff-configct.getContentLiffConfigpublic
GET/api/public/content/:tokenct.getContentByTokenpublic

route แบบ static ถูก register ก่อน route ที่มี :token เพื่อให้ gin resolve ไปยัง handler ที่ถูกต้อง และ RegisterRoutes ใช้เฉพาะ group public โดยมีบรรทัด _ = authed ยืนยันว่าไม่ได้ใช้ group authed

นอกจากนี้ยังมี endpoint สาธารณะที่อยู่ในโมดูลอื่นเป็นเส้นทางคู่ขนาน

Routeโมดูล
GET /api/public/content-pages/:tokenContent Page
POST /api/public/content-pages/:token/trackContent Page
GET /api/menu-builder/public/:tokenMenu Builder

จุดเชื่อมต่อกับ Service อื่น

  • สิทธิ์การเข้าถึง — ไม่มีการตรวจสิทธิ์ เพราะเป็น public ทั้งหมด ป้องกันด้วยกลไก token ที่เดาไม่ได้ร่วมกับ throttle แทน
  • ตารางที่เกี่ยวข้องcontent_page, content_page_translation, content_category, content_subcategory, content_link, menu_builder และ line_oa
  • Middlewaremiddleware.Throttle(10, 60000) (ดู Core HTTP Platform)
  • LIFF — ไฟล์ liff.go ตรวจสอบ x-liff-token และคืน config ให้ client-web
  • ผู้บริโภค — client-web-2026
  • โมดูลที่เกี่ยวข้องContent Page, Content Link, Menu Builder และ Content Category