Skip to main content

Trigger จากเหตุการณ์การจอง

ภาพรวม

เหตุการณ์ที่เกี่ยวข้องกับการจอง ไม่ว่าจะเป็นการสร้าง การยกเลิก การเปลี่ยนสถานะ หรือการถึงเวลาเตือน ควรกระตุ้น workflow ได้ ตัวอย่างเช่น เมื่อลูกค้าจองบริการหนึ่งให้ส่งข้อความแนะนำวิธีเตรียมตัว หรือเมื่อลูกค้ายกเลิกให้เพิ่มเข้ากลุ่มผู้ใช้ "ลูกค้าที่ยกเลิก" เพื่อยิงโปรโมชันในภายหลัง

งานนี้ทำหน้าที่เป็นสะพานระหว่างโดเมน appointment กับ Trigger Engine โดยจับคู่กฎ เติมข้อมูลให้ครบ แล้ว publish งานเข้าคิว action_execute

Business Flow

  1. รับ BookingEventPayload ซึ่งมีทั้งข้อมูลระบุตัวการจอง เช่น bookingId, userId, lineOaId, organizationId และข้อมูลเสริมที่อาจว่างได้ เช่น journeyId, serviceId, staffId, locationId, สถานะ, วันเวลา และชื่อบริการ พนักงาน สาขา ลูกค้า

  2. เติมข้อมูลให้ครบ — ฟิลด์ที่ผู้ส่งงานไม่ได้ระบุมาจะถูกเติมจากฐานข้อมูล ทั้งชื่อบริการ ชื่อพนักงาน ชื่อสาขา และวันเวลา โดยเติมเฉพาะกรณีที่ค่าเดิมว่างจริงเท่านั้น

  3. หาชนิดของ source type ที่ต้องจับคู่ ตามประเภทของเหตุการณ์

    ประเภทเหตุการณ์source type ที่นำไปค้นกฎ
    booking_createdbooking_created
    booking_cancelledbooking_cancelled และ booking_status_changed
    booking_reminderbooking_reminder
    booking_status_changedbooking_status_changed
  4. Query ตาราง trigger_rule โดยกรองด้วย source type ที่ได้ ให้ตรงกับ OA และองค์กรเดียวกัน มีสถานะเปิดใช้งาน และยังไม่ถูกลบ

  5. สำหรับแต่ละกฎ ระบบจะกรองเพิ่มอีกชั้นด้วยเงื่อนไขใน source config เช่น ต้องตรงกับ journey, บริการ, สาขา หรือพนักงานที่กำหนด หากไม่ตรงจะข้ามกฎนั้นไป

  6. ประกอบ payload ของ action โดย merge ข้อมูลการจองที่เติมครบแล้วเข้าไปใน action config ทำให้ action ปลายทางสามารถใช้ข้อมูลการจองเป็น merge tag ได้ เช่น การส่งลิงก์การจอง

  7. Publish งานเข้าคิว action_execute

  8. merge ข้อมูลชุด appt_* เช่น appt_service และ appt_date ลง line_user.custom_attribute เพื่อให้นำไปใช้แบ่งกลุ่มผู้ใช้ได้

  9. Service จะดักจับข้อผิดพลาดของตัวเองทั้งหมดโดยไม่ส่งต่อขึ้นไป ทำให้ handler ack ข้อความเสมอ

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

ไฟล์หน้าที่
internal/appointment/booking_event.goBookingEventService.ProcessEvent ครอบคลุม flow ทั้งหมด โดยมีฟังก์ชันย่อย getSourceTypes, matchesSourceConfig, enrichPayload, updateCustomAttributes และโครงสร้าง BookingEventPayload ที่ใช้ pointer สำหรับฟิลด์ optional เพื่อแยกกรณี "ส่งมาเป็นค่าว่าง" ออกจาก "ไม่ได้ส่งมา"
internal/appointment/consumer.goConsumer.HandleBookingEvent
internal/appointment/helpers.gocollectRows, asMap, nullableAny
cmd/worker/main.gorunCronScheduler — จุดที่สร้าง service พร้อมกำหนดคิวปลายทางเป็น action_execute

คิวที่เกี่ยวข้อง: consume booking_event_trigger และ publish action_execute ทั้งหมดอยู่บน profile cron-scheduler

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

  • รับงานจาก pg-listener ผ่าน pg_notify('booking_event') ที่ยิงจาก trigger บนตาราง appointment.booking ซึ่งต้นทางจริงคือ client-api-go หรือ cms-api-go ที่แก้ไขข้อมูลการจอง
  • ตารางฐานข้อมูลtrigger_rule (กฎที่นำมาจับคู่), ตารางในโดเมน appointment ได้แก่ booking, journey, service, staff, location (ใช้เติมข้อมูล) และ line_user (custom attribute ชุด appt_*)
  • RabbitMQ — publish เข้าคิว action_execute เพื่อส่งต่อให้ ตัวประมวลผล Action
  • ไม่มีการเรียก LINE API โดยตรง เพราะการส่งข้อความเกิดขึ้นที่ action executor หรือที่ การแจ้งเตือนการนัดหมาย