# Stream Status API

ใช้เอ็นด์พอยต์ **Stream Status** เพื่อถาม DailyPlay ว่าควรแสดงสตรีมตอนนี้หรือไม่ —
ก่อนที่จะใส่ iframe, ปุ่ม Play ลอย หรือ overlay กำหนดเองบนเว็บไซต์

นี่คือ **GET สาธารณะ** (ไม่ต้องมี API key) เหมาะสำหรับเจ้าของไซต์/แอปที่ต้องการ:

- แสดง overlay ของสตรีม**เฉพาะตอนสตรีมใช้งานอยู่**
- ซ่อนปุ่ม Play เมื่อแคมเปญยังไม่เริ่มหรือจบแล้ว
- ไม่โหลดตัวเล่นสตรีมเต็มเมื่อไม่มีเกมที่เผยแพร่

:::tip[ออกแบบให้น้ำหนักเบา]
ต่างจากเพย์โหลดของตัวเล่นสตรีมเต็ม เอ็นด์พอยต์นี้**ไม่**คืนค่า config หรือรางวัลของเกม และ
**ไม่**บันทึก analytics ใช้สำหรับเกตความพร้อมใช้งาน แล้วโหลด URL สตรีมเมื่อ
`available` เป็น `true` เท่านั้น
:::

## เอ็นด์พอยต์

```
GET https://app.dailyplay.ai/api/stream-status?org_slug=<org-slug>&stream_slug=<stream-slug>
```

| พารามิเตอร์    | จำเป็น | คำอธิบาย |
| ------------- | ------ | -------- |
| `org_slug`    | ใช่    | slug องค์กร (จาก URL แชร์สตรีม) |
| `stream_slug` | ใช่    | slug สตรีม (จาก URL แชร์สตรีม) |

**การยืนยันตัวตน:** ไม่มี  
**CORS:** `Access-Control-Allow-Origin: *` (เรียกจากเบราว์เซอร์ได้)  
**แคช:** `public, s-maxage=30, stale-while-revalidate=60` — โฮสต์สามารถ poll ประมาณทุก 30 วินาที

### ตัวอย่าง

```
https://app.dailyplay.ai/api/stream-status?org_slug=your-org&stream_slug=summer-campaign
```

## การตอบกลับ

HTTP `200` พร้อม `success: true` หมายถึงคำขอถูกประมวลผลแล้ว ใช้ **`data.available`** เพื่อตัดสินใจ
ว่าจะแสดง UI สตรีมหรือไม่

### พร้อมใช้งาน

```json
{
  "success": true,
  "data": {
    "available": true,
    "reason": null,
    "total_games": 4,
    "starts_at": null,
    "ends_at": null,
    "timezone": "UTC",
    "server_time": "2026-10-15T07:23:43.597Z",
    "stream": {
      "slug": "summer-campaign",
      "status": "active"
    },
    "organization": {
      "slug": "your-org"
    }
  }
}
```

### ไม่พร้อมใช้งาน

```json
{
  "success": true,
  "data": {
    "available": false,
    "reason": "stream_inactive",
    "total_games": 0,
    "starts_at": null,
    "ends_at": null,
    "timezone": "UTC",
    "server_time": "2026-10-15T07:23:43.597Z",
    "stream": {
      "slug": "summer-campaign",
      "status": "draft"
    },
    "organization": {
      "slug": "your-org"
    }
  }
}
```

### ฟิลด์การตอบกลับ

| ฟิลด์ | ประเภท | คำอธิบาย |
| ----- | ------ | -------- |
| `available` | boolean | `true` เมื่อผู้เข้าชมเล่นสตรีมได้ |
| `reason` | string \| null | เหตุผลที่ไม่พร้อมใช้ (`null` เมื่อพร้อมใช้) |
| `total_games` | number | จำนวนเกมที่**เผยแพร่แล้ว**บนสตรีม (`0` เมื่อไม่สาธารณะ) |
| `starts_at` / `ends_at` | string \| null | ขอบเขตตารางเวลาเป็น ISO UTC (จากโซนเวลาของสตรีม) |
| `timezone` | string | โซนเวลาสตรีมที่ใช้ตรวจตารางเวลา |
| `server_time` | string | นาฬิกาเซิร์ฟเวอร์ (ISO UTC) ของการตัดสินใจ |
| `stream.slug` / `status` | string | ตัวตนและสถานะสตรีม |
| `organization.slug` | string | slug องค์กร |

### เหตุผลที่ไม่พร้อมใช้

| `reason` | ความหมาย |
| -------- | -------- |
| `not_public` | สตรีมไม่สาธารณะ (ไม่เปิดเผยรายละเอียด) |
| `stream_inactive` | สถานะไม่ใช่ `active` (เช่น draft / archived) |
| `stream_not_started` | เวลาปัจจุบันอยู่ก่อน `starts_at` |
| `stream_ended` | เวลาปัจจุบันอยู่หลัง `ends_at` |
| `no_games` | สตรีมใช้งาน/สาธารณะแต่ไม่มีเกมที่เผยแพร่ |

### การตอบกลับข้อผิดพลาด

| รหัส | เมื่อ |
| ---- | ---- |
| `400` | ขาด `org_slug` หรือ `stream_slug` |
| `404` | ไม่พบองค์กรหรือสตรีม |
| `405` | เมธอดอื่นนอกจาก `GET` / `OPTIONS` |
| `500` | ข้อผิดพลาดเซิร์ฟเวอร์ |

```json
{
  "success": false,
  "error": "Stream not found"
}
```

---

## เมื่อไหร่สตรีมจึง “พร้อมใช้งาน”

ต้องเป็นจริงทั้งหมดดังนี้:

1. มีสตรีมภายใต้ org slug ที่ระบุ
2. สตรีมเป็น**สาธารณะ**
3. สถานะสตรีมเป็น **`active`**
4. หากมีเวลาเริ่ม ต้องเริ่มแล้ว (ในโซนเวลาของสตรีม)
5. หากมีเวลาสิ้นสุด ต้องยังไม่สิ้นสุด
6. มีเกมที่**เผยแพร่แล้ว**อย่างน้อยหนึ่งเกมติดกับสตรีม

---

## การเชื่อมต่อทั่วไป: เกต overlay

เจ้าของไซต์มักไม่ใส่ปุ่ม Play ลอยหรือโมดอลลงใน DOM จนกว่าสตรีมจะสด

```html
<script>
  async function shouldShowStreamOverlay(orgSlug, streamSlug) {
    const url =
      "https://app.dailyplay.ai/api/stream-status" +
      `?org_slug=${encodeURIComponent(orgSlug)}` +
      `&stream_slug=${encodeURIComponent(streamSlug)}`;

    const res = await fetch(url);
    const json = await res.json();
    return Boolean(json?.success && json?.data?.available);
  }

  async function maybeMountOverlay() {
    const available = await shouldShowStreamOverlay(
      "your-org",
      "summer-campaign"
    );

    if (!available) {
      // อย่าใส่ iframe / ปุ่มลอย
      return;
    }

    // ใส่ overlay หรือ iframe:
    // https://app.dailyplay.ai/stream/your-org/summer-campaign/widget?origin=...
  }

  maybeMountOverlay();
  // ไม่บังคับ: ตรวจซ้ำทุก ~30 วินาทีให้สอดคล้องแคช CDN
  setInterval(maybeMountOverlay, 30000);
</script>
```

### URL สตรีมที่แนะนำหลังตรวจผ่าน

| วัตถุประสงค์ | URL |
| ------------ | --- |
| หน้าสตรีมเต็ม | `https://app.dailyplay.ai/stream/<org-slug>/<stream-slug>` |
| วิดเจ็ต / overlay ลอย | `https://app.dailyplay.ai/stream/<org-slug>/<stream-slug>/widget?origin=<encoded-site-origin>` |

ดู snippet วิดเจ็ตโฮสต์ที่ [Floating Play Button](/th/sharing/floating-play-button/) สคริปต์วิดเจ็ตของ DailyPlay ก็เกตตัวเปิดสตรีมให้แสดงเฉพาะเมื่อเล่นได้

:::note[โทเค็นเซสชัน]
หากสตรีมต้องใช้โทเค็นเซสชัน API ความพร้อมใช้งานยังเป็น `true` ได้ขณะที่การเล่นต้องมีโทเค็น
สร้างโทเค็นด้วย [Session Tokens](/th/api/session-tokens/) API (Business+)
:::

---

## ขั้นตอนต่อไป

- [ฝังเกมและสตรีม](/th/sharing/embed/)
- [Floating Play Button](/th/sharing/floating-play-button/)
- [Session Tokens](/th/api/session-tokens/) สำหรับการเข้าถึงแบบควบคุม
- [API Reference](/th/api/reference/) สำหรับรายการเอ็นด์พอยต์ทั้งหมด