soup-sdk 0.3.3

채팅 이벤트 수신 SDK
Documentation

soup-sdk

Rust SDK for SOOP live information, VOD metadata, VOD chat parsing, and live chat event streaming.

The crate currently focuses on:

  • SOOP HTTP API helpers through SoopHttpClient.
  • Live WebSocket chat connection through SoopChatConnection.
  • Structured chat events through Event.
  • VOD chat XML parsing into the same event model where possible.

Documentation

  • HTTP_API.md: SoopHttpClient methods and return types.
  • CHAT.md: live chat connection lifecycle and command/event channels.
  • EVENTS.md: event enum and payload reference.
  • ARCHITECTURE.md: internal architecture and refactor direction.
  • RULES.md: working rules for AI agents and maintainers.

Installation

When using this crate from the same workspace or a local checkout:

[dependencies]
soup-sdk = { path = "libs/soup-sdk-rs" }

When the crate is published to a registry, use the published version:

[dependencies]
soup-sdk = "0.3.0"

The package name is soup-sdk; the Rust import path is soup_sdk.

Requirements

  • Rust edition 2024.
  • Tokio async runtime.
  • Network access to SOOP HTTP and WebSocket endpoints.
  • HTTP requests and WebSocket connection attempts use a default 15-second timeout.

Quick Start: HTTP API

use soup_sdk::{Result, SoopHttpClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = SoopHttpClient::new();

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

    if let soup_sdk::LiveStatus::Live(detail) = status {
        println!("title: {}", detail.title);
    }

    Ok(())
}

Quick Start: Live Chat

use std::sync::Arc;

use soup_sdk::{
    Result, SoopHttpClient,
    chat::{Event, SoopChatConnection, SoopChatOptions},
};

#[tokio::main]
async fn main() -> Result<()> {
    let http = Arc::new(SoopHttpClient::new());
    let options = SoopChatOptions {
        streamer_id: "streamer_id".to_string(),
        password: "".to_string(),
        diagnostics: false,
    };

    let connection = SoopChatConnection::new(Arc::clone(&http), options)?;
    let mut events = connection.subscribe();

    connection.start().await?;

    while let Ok(event) = events.recv().await {
        match event {
            Event::Chat(chat) => {
                println!("{}: {}", chat.user.label, chat.comment);
            }
            Event::Donation(donation) => {
                println!("{} donated {}", donation.from_label, donation.amount);
            }
            Event::Disconnected(disconnected) => {
                println!("disconnected: {:?}", disconnected.reason);
                break;
            }
            _ => {}
        }
    }

    Ok(())
}

Quick Start: VOD Chat

use soup_sdk::{Result, SoopHttpClient};

#[tokio::main]
async fn main() -> Result<()> {
    let client = SoopHttpClient::new();
    let collection = client.get_full_vod_chat(123456789).await?;

    println!("collected {} events", collection.events.len());
    println!("failed chunks: {}", collection.failures.len());
    Ok(())
}

Error Handling

Most SDK operations return soup_sdk::Result<T>, which uses soup_sdk::Error.

Current error categories include:

  • HTTP request failures.
  • WebSocket connection and protocol failures.
  • JSON parsing failures.
  • URL parsing failures.
  • internal channel failures.
  • offline stream state.
  • upstream API errors represented as strings.

Parser failures and protocol drift are observable through Event::Diagnostic when live chat diagnostics are enabled. See EVENTS.md for details.

Current Limitations

  • Live chat reconnect is intentionally not automatic in v0.3. A disconnected session emits a reason and can be recreated by the caller.
  • Chat send is not exposed in v0.3.
  • VOD full chat collection returns structured chunk success/failure metadata.
  • Live chat TLS certificate verification is currently disabled for compatibility with the upstream chat endpoint. This is intentionally documented and should be treated as a security tradeoff.

These limitations are documented so downstream users and future contributors can reason about current behavior without reading implementation code.