soup-sdk 0.3.2

채팅 이벤트 수신 SDK
Documentation
# HTTP API Reference

This document describes the public HTTP-facing interface exposed by `SoopHttpClient`.

All methods are async except `new`, and most return `soup_sdk::Result<T>`.

```rust
use soup_sdk::SoopHttpClient;

let client = SoopHttpClient::new();
```

## Error Model

HTTP APIs return `soup_sdk::Result<T>`.

Possible error categories include:

- `Error::Transport`: request or response-body transport failures from `reqwest`.
- `Error::HttpStatus`: non-success HTTP response status with URL context.
- `Error::Decode`: response JSON/text/timestamp decoding failures.
- `Error::Parse`: SDK parser failures.
- `Error::Protocol`: upstream response indicates an unusable or unexpected protocol/API state.
- `Error::StreamOffline`: used by chat startup when live detail says the stream is offline.
- `Error::URLParse`: invalid URL construction or parsing.

## `SoopHttpClient::new`

Creates a new HTTP client.

```rust
let client = SoopHttpClient::new();
```

Inputs: none.

Returns: `SoopHttpClient`.

Notes:

- Internally wraps `reqwest::Client`.
- Uses a default 15-second HTTP request timeout.
- The current constructor does not expose custom timeout, proxy, cookie, or header configuration.

## `get_live_status`

Fetches live stream detail by streamer ID.

```rust
let status = client.get_live_status("streamer_id").await?;
```

Input:

- `streamer_id: &str`: SOOP streamer ID.

Returns:

```rust
Result<LiveStatus>
```

`LiveStatus` variants:

- `Offline`
- `Live(LiveDetail)`

`LiveDetail` fields:

- `is_live: bool`
- `ch_domain: String`
- `ch_pt: u64`
- `ch_no: String`
- `streamer_nick: String`
- `title: String`
- `categories: Vec<String>`

Behavior:

- If the stream is offline, returns `LiveStatus::Offline`.
- If the stream is live, returns `LiveStatus::Live(LiveDetail)`.
- The method parses a lightweight response first, then parses the full live detail only when the stream is live.

Failure modes:

- HTTP request failure.
- non-success HTTP status.
- invalid JSON.

## `get_station`

Fetches station and broadcast summary information by streamer ID.

```rust
let station = client.get_station("streamer_id").await?;
```

Input:

- `streamer_id: &str`

Returns:

```rust
Result<Station>
```

`Station` fields:

- `broad_start: DateTime<Utc>`
- `is_password: bool`
- `viewer_count: u64`
- `title: String`

Failure modes:

- HTTP request failure.
- non-success HTTP status.
- invalid JSON.
- timestamp decode failure.

## `get_signature_emoticon`

Fetches streamer signature emoticon metadata.

```rust
let emoticons = client.get_signature_emoticon("streamer_id").await?;
```

Input:

- `streamer_id: &str`

Returns:

```rust
Result<SignatureEmoticonData>
```

`SignatureEmoticonData` fields:

- `tier_1: Vec<Emoticon>`
- `tier_2: Vec<Emoticon>`

`Emoticon` fields:

- `title: String`
- `pc_img: String`
- `mobile_img: String`

Failure modes:

- HTTP request failure.
- non-success HTTP status.
- invalid JSON.

## `get_vod_list`

Fetches review VODs for a streamer.

```rust
let vods = client.get_vod_list("streamer_id", 1).await?;
```

Inputs:

- `streamer_id: &str`
- `page: u32`

Returns:

```rust
Result<Vec<VOD>>
```

`VOD` fields:

- `id: u64`
- `title: String`
- `thumbnail_url: String`
- `duration: u64`
- `reg_date: DateTime<Utc>`

Behavior:

- Filters raw VODs to entries with `auth_no == 101`.
- Normalizes protocol-relative thumbnail URLs by prefixing `https:`.

Failure modes:

- HTTP request failure.
- non-success HTTP status.
- invalid JSON.
- timestamp decode failure.

## `get_vod_detail`

Fetches VOD detail and file metadata.

```rust
let detail = client.get_vod_detail(123456789).await?;
```

Input:

- `vod_id: u64`

Returns:

```rust
Result<VODDetail>
```

`VODDetail` fields:

- `id: String`
- `title: String`
- `channel_id: String`
- `broad_start: String`
- `files: Vec<VODFile>`

`VODFile` fields:

- `id: u64`
- `order: u32`
- `file_key: String`
- `file_start: String`
- `chat: String`
- `duration: u64`

Failure modes:

- HTTP request failure.
- non-success HTTP status.
- invalid JSON.
- `Error::Protocol` when the upstream response does not contain usable VOD data.

## `get_vod_chat`

Fetches a VOD chat XML chunk.

```rust
let xml = client.get_vod_chat(&file.chat, 0).await?;
```

Inputs:

- `chat_url: &str`: VOD chat URL from `VODFile.chat`.
- `start_time: u64`: chunk start time in seconds.

Returns:

```rust
Result<String>
```

Behavior:

- Appends `&startTime={start_time}` to the provided chat URL.
- Returns the raw XML response body as a string.

Failure modes:

- HTTP request failure.
- non-success HTTP status.
- response text decoding failure.

## `get_full_vod_chat`

Fetches VOD detail, downloads VOD chat chunks, and parses events.

```rust
let collection = client.get_full_vod_chat(123456789).await?;
```

Input:

- `vod_id: u64`

Returns:

```rust
Result<VodChatCollection>
```

`VodChatCollection` fields:

- `events: Vec<Event>`
- `chunks: Vec<VodChatChunk>`
- `failures: Vec<VodChatChunkFailure>`

Behavior:

- Calls `get_vod_detail`.
- Iterates over VOD files.
- Downloads chat XML in 300-second chunks.
- Parses XML into `Event` values.
- Records successful chunk metadata in `chunks`.
- Records chunk-level fetch or XML parse failures in `failures`.
- Empty XML responses are skipped and are not recorded as either successful chunks or failures.

Current limitation:

- `events` may still be partial if individual chunks fail. Empty upstream responses are intentionally ignored rather than represented in `failures`.

Failure modes:

- VOD detail fetch failure.
- Other chunk-level failures are currently best-effort and may not fail the whole method.