การเรียก API ภายนอกจาก Workflow
ภาพรวม
Action ประเภท web_request เปิดให้ลูกค้าเชื่อม workflow เข้ากับระบบภายนอกได้ ตัวอย่างการใช้งาน
ที่พบบ่อยคือ เช็คแต้มสะสมจาก CRM ของลูกค้าเอง แล้วนำค่าที่ได้กลับมาเก็บเป็น attribute ของผู้ใช้
จากนั้นจึงส่งข้อความที่มีค่านั้นออกไป
งานนี้ถูกแยกออกมาเป็น profile ของตัวเอง (SVC=web-request-worker) เพราะปลายทางเป็น API
ของลูกค้าที่อาจตอบช้าหรือล่มได้ จึงไม่ควรปล่อยให้มาถ่วง action queue หลัก
Business Flow
- รับ
ActionExecutePayloadแบบเดียวกับ action_execute แต่มีactionType = web_request - อ่าน
WebRequestActionConfigจากactionConfigซึ่งประกอบด้วย method, url, headers, body,responseMappings,postActionและ config ของ retry กับ timeout - Resolve merge tag ใน url, headers และ body โดยรองรับรูปแบบ
{{...}}จาก 3 แหล่ง- system attribute ผ่าน
systemattribute.Serviceซึ่ง cache ไว้ใน Redis - ฟิลด์ของ
line_userและcustom_attribute - ค่า
userIdโดยตรง
- system attribute ผ่าน
- ยิง HTTP request พร้อม retry
- timeout ค่า default 30,000 มิลลิวินาที (
defaultTimeoutMs) - retry ได้สูงสุด 3 ครั้ง (
defaultRetryMaxAttempts) โดยเริ่ม backoff ที่ 1,000 มิลลิวินาที - แยกชนิดของ error ชัดเจน —
clientError(กลุ่ม 4xx ไม่ retry) และserverError(กลุ่ม 5xx retry ได้ และ exposeStatusCode()ให้ชั้น mq จำแนกเป็น transient error)
- timeout ค่า default 30,000 มิลลิวินาที (
- Map ผลลัพธ์กลับ ผ่าน
processResponseMappingsโดยแต่ละ mapping ใช้ JSONPath ดึงค่าออกจาก response แล้วเขียนลงปลายทาง- ปลายทางเป็นได้ทั้ง system attribute และ user attribute (
line_user.custom_attribute) - รองรับ template
{{value}}สำหรับประกอบค่าใหม่ - หาก mapping ตัวใดตัวหนึ่งล้มเหลว จะไม่ทำให้ทั้งงานพัง
- ปลายทางเป็นได้ทั้ง system attribute และ user attribute (
- postAction — หากมีการกำหนดไว้ ระบบจะประกอบ
ActionExecutePayloadตัวใหม่แล้ว publish เข้าaction_executeเพื่อทำ action ต่อ เช่น ส่งข้อความที่มีแต้มที่เพิ่งดึงมา ถือเป็นการต่อ workflow ให้เป็นสาย onError— หากใน config มี branch สำหรับ error ระบบจะเดินเส้นทาง error แทน
ไฟล์และฟังก์ชันหลัก
internal/webrequest/service.goService.Execute(ctx, payload)— entry point และexecute()ที่เป็น flow จริงexecuteWithRetry(),doRequest(),onError()processResponseMappings(),processOneMapping()resolveMergeTags(),resolveHeaderMergeTags(),getLineUser()- error type ได้แก่
clientError,serverError(มีเมธอดStatusCode()) และstatusError - ค่าคงที่
defaultTimeoutMs = 30000,defaultRetryMaxAttempts = 3,defaultRetryBackoffMs = 1000
internal/webrequest/consumer.go—Consumer.HandleWebRequestinternal/webrequest/config.go— structWebRequestActionConfigและResponseMappinginternal/webrequest/jsonpath.go— implementation ของ JSONPath ซึ่งเทียบเคียงกับjsonpath-plusที่ระบบเดิมใช้internal/systemattribute/systemattribute.go— อ่านและเขียน system attribute พร้อม cache ใน Rediscmd/worker/main.go—runWebRequestWorker()- Queue: consume
web_request_executeและ publishaction_execute(profileweb-request-worker)
จุดเชื่อมต่อกับ Service อื่น
- รับ job จาก: เครื่องยนต์ Trigger / Workflow Automation โดย
executeActionจะเลือก queue นี้เมื่อrule.actionTypeเท่ากับweb_request - ตารางที่เกี่ยวข้อง:
line_user(ใช้ทั้ง merge tag และเขียนค่ากลับลงcustom_attribute) รวมถึงsystem_attributeและattribute_master - Redis: cache ของ system attribute
- HTTP ภายนอก: API ของลูกค้า ตาม method, url และ headers ที่กำหนดใน config
- RabbitMQ: publish เข้า
action_executeสำหรับ postAction - งานนี้ไม่เรียก LINE API โดยตรง การส่งข้อความจะเกิดขึ้นที่ postAction ผ่าน action executor