Skip to main content

รายการเนื้อหาตามลิงก์ที่แชร์ (Content Link)

ภาพรวม

Content Link คือลิงก์ที่แอดมินสร้างขึ้นใน CMS โดยฝังตัวกรองไว้ล่วงหน้า ได้แก่ หมวดหมู่ หมวดหมู่ย่อย ช่วงวันที่ และ audience จากนั้นนำไปแปะใน rich menu หรือส่งในแชท เมื่อผู้ใช้เปิดลิงก์ ระบบจะแสดงหน้ารายการบทความที่ถูกกรองไว้เรียบร้อยแล้ว โดยฝั่ง client ไม่ต้องส่งพารามิเตอร์ตัวกรองใด ๆ มาเลย

นอกจากนี้ endpoint ยังทำหน้าที่นับ click_count ของลิงก์ เพื่อให้ CMS นำไปแสดงเป็นสถิติ

Business Flow

GET /api/public-content/links/:token/contents (rate limit 10/60s)

Query parameter ที่รับ ได้แก่ search (sanitize + ตรวจ pattern + ยาวไม่เกิน 100 ตัวอักษร เช่นเดียวกับหน้ารายการทั่วไป), page ค่าระหว่าง 1–100 และ limit ค่าระหว่าง 1–50

  1. ค้นหาแถว content_link ที่ active ด้วย token — ไม่พบตอบ 404 Content link not found or inactive
  2. validateLineOa(link.lineOaId) — OA ต้อง active มิฉะนั้นตอบ 404 Invalid or inactive channel
  3. หา audience ของผู้ใช้แบบ best-effort — หากมี header x-liff-token จะ verify แต่ความล้มเหลวทุกกรณีจะถูกกลืนไว้แล้วทำงานต่อโดยไม่กรอง audience ซึ่งเป็น graceful degrade ไม่ใช่การปฏิเสธ
  4. เรียก IncrementClickCount(link.id) เพื่อนับคลิกก่อนดึงข้อมูล
  5. ค่าเริ่มต้นคือ page=1 และ limit=10 โดย skip ที่เกิน 500 จะตอบ 400 Page number exceeds maximum allowed
  6. ประกอบตัวกรองจาก ค่าที่ฝังอยู่ในลิงก์ ไม่ใช่จาก query ได้แก่ categoryId, subcategoryId (ขยายเป็นลูกหลานทั้งหมด) และ publishedDateFrom / publishedDateTo ซึ่ง format เป็นรูปแบบ 2006-01-02T15:04:05.000Z
  7. บันได audience 3 ชั้น ตัดสินตามลำดับนี้
    • หากลิงก์มี audience_ids ที่ไม่ว่าง จะกรองด้วย audience ของลิงก์
    • มิฉะนั้น หากผู้ใช้มี audience จะกรองด้วย audience ของผู้ใช้
    • มิฉะนั้นใช้ ApplyPublicOnly คือแสดงเฉพาะบทความที่ไม่จำกัด audience
  8. ค่า search จาก query ยังใช้ได้ โดยทำงานร่วมกับตัวกรองของลิงก์
  9. Hydrate translations และข้อมูลอ้างอิงหมวดหมู่ด้วย helper ชุดเดียวกับหน้ารายการทั่วไป
  10. ตอบกลับ {linkInfo, data, total, page, limit, totalPages} โดย linkInfo ประกอบด้วย name, description และข้อมูลหมวดหมู่/หมวดหมู่ย่อยซึ่ง resolve จาก id แบบไม่กรองเงื่อนไขเพิ่ม

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

รายการค่า
RouteGET /api/public-content/links/:token/contents (rate limit 10/60s)
Handlerinternal/publiccontent/handler.go(*Handler).GetContentsByLinkToken
Serviceinternal/publiccontent/service.go(*Service).GetContentsByLinkToken
DTObyLinkDTO รับ search, page, limit
Repositoryinternal/contentlink/repository.goFindActiveByToken, IncrementClickCount
Entityinternal/contentlink/entity.goContentLink (audience_ids, category_id, subcategory_id, published_date_from, published_date_to, click_count)
Filterinternal/contentpage.ListFilter (LinkAudienceIDs, UserAudienceIDs, ApplyPublicOnly, SubcategoryIDs)
ResponseByLinkResponse และ linkInfo

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

  • ฐานข้อมูล — ตาราง content_link, content_page, content_page_translation, content_category, content_subcategory, line_oa และ line_user (สำหรับ audience)
  • LIFF authentication — เรียก VerifyAndGetLineUser แบบ best-effort
  • ฟีเจอร์ที่เกี่ยวข้อง — ใช้ repository และ helper ร่วมกับ public content listing และเป็นปลายทางของ menu item ชนิด content link ผ่านค่า contentLinkToken, contentLinkBehavior และ contentLinkDisplayStyle ในเมนูสาธารณะ
  • client-web — ตรงกับฟีเจอร์ content-link-listing