# อ็อบเจกต์ Journey

เมธอด [lifecycle](/th/developer/api-reference/customer-journey-api/lifecycle/), [create และ update](/th/developer/api-reference/customer-journey-api/create-update/) ทั้งหมดจะส่งคืนอ็อบเจกต์ journey ที่มีโครงสร้างระดับบนสุดเหมือนกัน:

```json title="Shape"
{
  "info": { ... },        // read-only metadata (responses only)
  "params": { ... },      // journey-wide configuration (create / update)
  "points": [ ... ],      // canvas nodes and their connections
  "comments": [ ... ]     // canvas comments
}
```

เมื่อคุณ **สร้าง** หรือ **อัปเดต** journey คุณจะส่ง `title`, `params`, `points` และ `comments` การตอบกลับจะส่งคืน `info` (ซึ่งมี `params`) พร้อมด้วย `points` และ `comments`

## Info

ข้อมูลเมตาดาต้าของ journey แบบอ่านอย่างเดียว ส่งคืนโดยทุกเมธอด v3 ไม่ใช่ส่วนหนึ่งของ request body

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `uuid` | string | [Journey ID](/th/developer/api-reference/api-identifiers/#journey-id) |
| `title` | string | ชื่อของ Journey |
| `status` | [`JourneyStatus`](#journeystatus-enum) | สถานะปัจจุบัน |
| `created_at` | string | การประทับเวลาที่สร้าง (ISO 8601) |
| `updated_at` | string | การประทับเวลาที่อัปเดตล่าสุด (ISO 8601) |
| `is_first_activated` | bool | ระบุว่า journey ได้เริ่มทำงานแล้วอย่างน้อยหนึ่งครั้งหรือไม่ |
| `params` | [`JourneyParams`](#journeyparams) | การกำหนดค่าทั่วทั้ง journey |
| `category_uuid` | string | UUID ของหมวดหมู่ หรือว่างเปล่าหากไม่มีหมวดหมู่ |
| `pointCounts` | map&lt;string, uint32&gt; | จำนวนของ point ตามประเภท |
| `campaign_type` | [`CampaignType`](#campaigntype-enum) | วิธีที่ผู้ใช้เข้าสู่ journey |
| `stop_reason` | string | เหตุผลที่ journey หยุดทำงาน (ถ้ามี) |
| `last_edited_by` | `User` | ผู้ใช้ที่แก้ไข journey ล่าสุด |
| `dynamic_entry` | bool | ระบุว่าเปิดใช้งาน dynamic entry หรือไม่ |

## JourneyParams

การกำหนดค่าทั่วทั้ง journey ส่งเมื่อสร้าง/อัปเดต และส่งคืนภายใน `info.params`

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `application_code` | string | [Application code](/th/developer/api-reference/api-identifiers/#application-code) ที่ journey เป็นส่วนหนึ่ง จำเป็นต้องมีเมื่อสร้าง |
| `silent_hours` | [`SilentHours`](#silenthours) | ชั่วโมงที่จะไม่ส่งข้อความ แยกตามช่องทาง |
| `capping` | [`EntryCapping`](#entrycapping) | ข้อจำกัดเกี่ยวกับความถี่ที่ผู้ใช้สามารถเข้าสู่ journey ซ้ำได้ |
| `conversion_window` | [`ConversionWindow`](#conversionwindow) | กรอบเวลาสำหรับการระบุ conversion ของเป้าหมาย |
| `user_id_track_change_policy` | [`UserIDTrackChangePolicy`](#useridtrackchangepolicy-enum) | วิธีจัดการเมื่อ ID ของผู้ใช้เปลี่ยนแปลงกลาง journey |

### SilentHours

ระงับการส่งในช่วงเวลาที่เงียบ กำหนดค่า **ต่อช่องทาง**: แต่ละช่องทางใช้ `SilentHoursParams` ของตัวเอง:

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `push_params` | `SilentHoursParams` | ช่วงเวลาห้ามส่งสำหรับ push notifications |
| `inapp_params` | `SilentHoursParams` | ช่วงเวลาห้ามส่งสำหรับ in-app messages |
| `email_params` | `SilentHoursParams` | ช่วงเวลาห้ามส่งสำหรับอีเมล |
| `sms_params` | `SilentHoursParams` | ช่วงเวลาห้ามส่งสำหรับ SMS |
| `whatsapp_params` | `SilentHoursParams` | ช่วงเวลาห้ามส่งสำหรับ WhatsApp |
| `line_params` | `SilentHoursParams` | ช่วงเวลาห้ามส่งสำหรับ LINE |

แต่ละ `SilentHoursParams` คือ:

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `enabled` | bool | ระบุว่าช่วงเวลาห้ามส่งมีผลกับช่องทางนี้หรือไม่ |
| `from_time` | `Time` | เวลาเริ่มต้นของช่วงเวลาที่เงียบ: `{ "hour": 0–23, "minute": 0–59 }` |
| `to_time` | `Time` | เวลาสิ้นสุดของช่วงเวลาที่เงียบ |
| `week_days` | bool[] | ค่าบูลีนเจ็ดค่าสำหรับวันที่ช่วงเวลานี้มีผล (วันจันทร์ = index 0) |
| `behavior` | enum | สิ่งที่ต้องทำเมื่อข้อความตกอยู่ในช่วงเวลาห้ามส่ง: `WaitAndSend` (พักไว้ แล้วส่งเมื่อสิ้นสุดช่วงเวลา), `DropAndGo` (ข้ามข้อความ และดำเนิน journey ต่อทันที) หรือ `WaitAndDrop` (รอจนสิ้นสุดช่วงเวลา แล้วดำเนินต่อโดยไม่ส่ง) |

### EntryCapping

จำกัดความถี่ที่ผู้ใช้คนเดียวกันสามารถเข้าสู่ journey ได้

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `is_enabled` | bool | ระบุว่าเปิดใช้งานการจำกัดการเข้าหรือไม่ |
| `period` | uint64 | จำนวนวินาทีขั้นต่ำระหว่างการเข้าของผู้ใช้แต่ละครั้ง |

### ConversionWindow

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `seconds` | uint64 | ระยะเวลาหลังจากเข้าสู่ journey ที่การบรรลุเป้าหมายของผู้ใช้ยังคงนับเป็น conversion |

## Point

Point คือโหนดบน journey canvas: จุดเริ่มต้น, ข้อความ, การหน่วงเวลา, ตัวแยก และอื่นๆ

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `uuid` | string | ID ที่ไม่ซ้ำกันของ point ภายใน journey ต้องเป็น UUID ตามมาตรฐาน [RFC 4122](https://www.rfc-editor.org/rfc/rfc4122): เลขฐานสิบหก 32 ตัวในกลุ่ม 8-4-4-4-12 |
| `title` | string | ชื่อที่แสดงของ point |
| `point_type` | [`PointType`](#pointtype-enum) | ประเภทของโหนด |
| `outputs` | array of [`PointOutput`](#pointoutput) | การเชื่อมต่อไปยัง point ถัดไป |
| `position` | [`Position`](#position) | พิกัดบน canvas |
| `point_data` | object | คีย์ที่ซ้อนกันเพียงหนึ่งคีย์ ซึ่งตรงกับ `point_type` (ดูตาราง [ประเภทของ point](#point-types-and-point_data)) |

<Aside type="note">
UUID ทั้งหมด (`info.uuid`, `uuid` ของทุก point และ `next_point_uuid` ของแต่ละ output) ต้องเป็น UUID ตามมาตรฐาน RFC 4122 (กลุ่มเลขฐานสิบหก 8-4-4-4-12)
</Aside>

### PointOutput

output ของ point คือ branch ที่ออกไป คีย์ของมัน **ไม่ใช่รูปแบบอิสระ** ตัวตรวจสอบคาดหวังชุดคีย์ที่แน่นอนสำหรับแต่ละประเภทของ point และจะปฏิเสธ journey ที่มี point ที่มีจำนวน output ไม่ถูกต้องหรือมีคีย์ที่ไม่รู้จัก

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `identity.key` | string | คีย์ของ Branch ต้องเป็นไปตาม [กฎของคีย์ output](#output-keys) ด้านล่าง |
| `identity.order` | int | ลำดับการแสดงผลของ branch |
| `info.title` | string | ป้ายกำกับ branch (ไม่บังคับ) |
| `info.next_point_uuid` | string | UUID ของ point ถัดไปที่ branch นี้เชื่อมต่อ |

#### คีย์ของ Output

branch เริ่มต้น (branch แรก) จะมีชื่อว่า `"default"` เสมอ branch เพิ่มเติมจะมีชื่อว่า `"output1"`, `"output2"`, … (คำนำหน้า `output` ตามด้วยดัชนีที่เริ่มจาก 1) มี point สองประเภทที่ละเมิดกฎนี้ ซึ่งระบุไว้ด้านล่าง

| ประเภทของ Point | คีย์ของ Output ที่คาดหวัง |
|---|---|
| Entry points (`START_BY_SEGMENT`, `START_BY_API`, `EVENT`), `INAPP`, `SET_TAGS`, `WEBHOOK`, `AUDIENCE_SYNC`, และ message points ที่ไม่มี splitter (`SEND_PUSH`, `SEND_EMAIL`, `SEND_SMS`, `SEND_WHATSAPP`, `SEND_LINE`, `SEND_KAKAO`, `SEND_TELEGRAM`, `SEND_DATA`) | `default` |
| `GOAL_EVENT`, `EXIT` | ไม่มี (ไม่มี output) |
| `FILTER` | `default`, `output1` |
| `BOOLEAN_SPLITTER` | `default`, จากนั้น `output1` … `outputN` (เพิ่มหนึ่ง branch ต่อเงื่อนไข การแยกแบบใช่/ไม่ใช่ธรรมดาคือ `default` + `output1`) |
| `WAIT` (delay) | `default` การหน่วงเวลาแบบไดนามิกพร้อมการแยก branch จะเพิ่ม `output1` |
| `WAIT_EVENT` | `default` คือ branch **เมื่อ event ไม่เกิดขึ้น** `output1` (หรือ, ด้วยสคริปต์เงื่อนไข, หนึ่ง branch ต่อเงื่อนไข) คือเส้นทางเมื่อ event เกิดขึ้น |
| `SEND_PUSH` ที่มี splitter | `default`, `output1` (และ `output2` เมื่อทั้ง message และ delivery splitter เปิดใช้งาน) |
| `SEND_EMAIL` / `SEND_SMS` / `SEND_LINE` / `SEND_WHATSAPP` ที่มี splitter | `default`, `output1` |
| `SEND_WHATSAPP` ที่มี quick-reply preset | `default`, บวกหนึ่ง branch ต่อ quick reply คีย์คือค่าของ quick-reply นั้นๆ |
| `AB_SPLITTER` | `output0`, `output1`, `output2`, … (หนึ่ง branch ต่อ variant **ไม่มี `default` branch**) |

### Position

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `x` | float | พิกัดแนวนอนบน canvas |
| `y` | float | พิกัดแนวตั้งบน canvas |

## ประเภทของ Point และ point_data

`point_data` เป็น one-of: มันมีอ็อบเจกต์ที่ซ้อนกันเพียงหนึ่งอ็อบเจกต์ซึ่งคีย์ถูกกำหนดโดย `point_type` ของ point

| `point_type` | คีย์ `point_data` | วัตถุประสงค์ |
|---|---|---|
| `POINT_TYPE_START_BY_SEGMENT` | `start_by_segment` | จุดเริ่มต้น: ผู้ใช้ที่ตรงกับ segment |
| `POINT_TYPE_EVENT` | `message_bus` | จุดเริ่มต้น: ผู้ใช้ที่ทำให้เกิด event |
| `POINT_TYPE_START_BY_API` | `start_by_api` | จุดเริ่มต้น: ผู้ใช้ที่ถูกเพิ่มผ่านการเรียก [Start by API](/th/developer/api-reference/customer-journey-api/start-by-api/) |
| `POINT_TYPE_WAIT` | `delay` | รอตามช่วงเวลาที่กำหนดหรือแบบไดนามิก |
| `POINT_TYPE_WAIT_EVENT` | `wait_event` | รอจนกว่า event จะเกิดขึ้น |
| `POINT_TYPE_SEND_PUSH` | `send_push` | ส่ง push notification |
| `POINT_TYPE_SEND_EMAIL` | `send_email` | ส่งอีเมล |
| `POINT_TYPE_SEND_SMS` | `send_sms` | ส่ง SMS |
| `POINT_TYPE_SEND_WHATSAPP` | `send_whatsapp` | ส่งข้อความ WhatsApp |
| `POINT_TYPE_SEND_TELEGRAM` | `send_telegram` | ส่งข้อความ Telegram |
| `POINT_TYPE_SEND_KAKAO` | `send_kakao` | ส่งข้อความ Kakao |
| `POINT_TYPE_SEND_LINE` | `send_line` | ส่งข้อความ LINE |
| `POINT_TYPE_SEND_DATA` | `send_data` | ส่งข้อความข้อมูลแบบเงียบ |
| `POINT_TYPE_INAPP` | `inapp` | แสดง in-app message |
| `POINT_TYPE_BOOLEAN_SPLITTER` | `boolean_splitter` | แยกผู้ใช้ตามเงื่อนไข (segment, tags หรือ event) |
| `POINT_TYPE_AB_SPLITTER` | `ab_splitter` | แยกผู้ใช้เป็นกลุ่ม A/B |
| `POINT_TYPE_FILTER` | `filter` | อนุญาตให้เฉพาะผู้ใช้ที่ตรงกับ filter ดำเนินการต่อ |
| `POINT_TYPE_SET_TAGS` | `set_tags` | อัปเดต user tags |
| `POINT_TYPE_WEBHOOK` | `web_hook` | ส่งคำขอ HTTP ขาออก |
| `POINT_TYPE_GOAL_EVENT` | `goal_event` | ติดตามเป้าหมาย conversion |
| `POINT_TYPE_AUDIENCE_SYNC` | `audience_sync` | ซิงค์ผู้ใช้ไปยัง audience ภายนอก |
| `POINT_TYPE_EXIT` | `terminator` | ออกจาก journey |

<Aside type="note">
payload ของ `point_data` แต่ละประเภทมีเอกสารประกอบใน [ข้อมูลอ้างอิง Point](/th/developer/api-reference/customer-journey-api/point-reference/) จุดเริ่มต้น, การกำหนดเวลา, การแยก และการกระทำต่างๆ ได้รับการอธิบายไว้อย่างครบถ้วนที่นั่น จุดส่งข้อความจะครอบคลุมในระดับ envelope พร้อมลิงก์ไปยังเอกสารของช่องทางที่เกี่ยวข้อง
</Aside>

### ตัวอย่าง Point

point "set tags" ที่มีการเชื่อมต่อดาวน์สตรีมเพียงเส้นเดียว:

```json
{
  "uuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
  "title": "Tag as engaged",
  "point_type": "POINT_TYPE_SET_TAGS",
  "position": { "x": 480, "y": 120 },
  "outputs": [
    {
      "identity": { "key": "default", "order": 0 },
      "info": { "title": "", "next_point_uuid": "ffffffff-1111-2222-3333-444444444444" }
    }
  ],
  "point_data": {
    "set_tags": {
      "application_code": "XXXXX-XXXXX",
      "tags": [ { "name": "engaged", "value": "true" } ]
    }
  }
}
```

## JourneyComment

| ฟิลด์ | ประเภท | คำอธิบาย |
|---|---|---|
| `id` | string | UUID ของความคิดเห็น |
| `message` | string | ข้อความของความคิดเห็น |
| `position` | [`Position`](#position) | พิกัดบน canvas |
| `index` | int | ลำดับการแสดงผล |
| `created_at` | string | การประทับเวลาที่สร้าง (ISO 8601) |
| `deleted` | bool | ระบุว่าความคิดเห็นถูกลบหรือไม่ |

## Enums

### JourneyStatus enum

`STATUS_DRAFT`, `STATUS_RUNNING`, `STATUS_FINISHED`, `STATUS_ARCHIVED`, `STATUS_PAUSED`, `STATUS_UNKNOWN`.

### CampaignType enum

- `TriggerBased`: ผู้ใช้เข้าสู่ Journey เมื่อเกิด event
- `AudienceBased`: ผู้ใช้เข้าสู่ Journey จาก segment
- `APIBased`: ผู้ใช้เข้าสู่ Journey ผ่านการเรียก Start by API
- `Mixed`: มีประเภทการเข้ามากกว่าหนึ่งประเภท
- `Unknown`: ไม่ได้กำหนดประเภทการเข้า

### PointType enum

ดูตาราง [ประเภทของ point](#point-types-and-point_data) ด้านบนสำหรับรายการทั้งหมดและคีย์ `point_data` ที่แต่ละประเภทจับคู่

### UserIDTrackChangePolicy enum

ควบคุมสิ่งที่เกิดขึ้นกับผู้ใช้ที่อยู่กลาง journey เมื่อ [User ID](/th/developer/api-reference/api-identifiers/#user-id) ของพวกเขาเปลี่ยนแปลง:

- `DEFAULT`: พฤติกรรมเริ่มต้น
- `TRACK`: ติดตามผู้ใช้ต่อไปภายใต้ ID ใหม่
- `DROP`: นำผู้ใช้ออกจาก journey เมื่อ ID ของพวกเขาเปลี่ยนแปลง

## ที่เกี่ยวข้อง

<CardGrid>
  <LinkCard title="ข้อมูลอ้างอิง Point" href="/developer/api-reference/customer-journey-api/point-reference/" />
  <LinkCard title="การสร้างและอัปเดต" href="/developer/api-reference/customer-journey-api/create-update/" />
  <LinkCard title="Lifecycle" href="/developer/api-reference/customer-journey-api/lifecycle/" />
</CardGrid>