#![doc = include_str!("../README.md")]
#![doc(html_favicon_url = "https://avatars.githubusercontent.com/u/8597527?s=32&v=4")]
#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/8597527?s=128&v=4")]
#![doc(issue_tracker_base_url = "https://github.com/GetStream/stream-video-rust/issues/")]
pub mod client;
pub mod error;
pub mod models;
pub mod token;
mod users;
pub mod video;
pub mod webhook;
use std::sync::Arc;
use client::Client;
#[doc(inline)]
pub use client::{ClientConfig, DEFAULT_BASE_URL, NetworkLimits, RetryConfig};
#[doc(inline)]
pub use error::{ApiError, Error, Result, TokenError, WebhookError};
#[doc(inline)]
pub use token::{TokenClaims, TokenOptions};
#[doc(inline)]
pub use video::{Call, VideoClient};
#[doc(inline)]
pub use webhook::{WebhookEvent, parse_event, verify_signature};
pub const ENV_API_KEY: &str = "STREAM_API_KEY";
pub const ENV_API_SECRET: &str = "STREAM_API_SECRET";
#[derive(Clone)]
pub struct Stream {
inner: Arc<Client>,
}
impl Stream {
pub fn new(api_key: impl Into<String>, api_secret: impl Into<String>) -> Result<Self> {
Self::with_config(api_key, api_secret, ClientConfig::default())
}
pub fn with_config(
api_key: impl Into<String>,
api_secret: impl Into<String>,
config: ClientConfig,
) -> Result<Self> {
let client = Client::new(api_key.into(), api_secret.into(), config)?;
Ok(Self {
inner: Arc::new(client),
})
}
pub fn with_config_and_limits(
api_key: impl Into<String>,
api_secret: impl Into<String>,
config: ClientConfig,
limits: NetworkLimits,
) -> Result<Self> {
let client = Client::new_with_limits(api_key.into(), api_secret.into(), config, limits)?;
Ok(Self {
inner: Arc::new(client),
})
}
pub fn from_env() -> Result<Self> {
let api_key = std::env::var(ENV_API_KEY)
.map_err(|_| Error::Config(format!("{ENV_API_KEY} is not set")))?;
let api_secret = std::env::var(ENV_API_SECRET)
.map_err(|_| Error::Config(format!("{ENV_API_SECRET} is not set")))?;
Self::new(api_key, api_secret)
}
pub(crate) fn client(&self) -> &Client {
&self.inner
}
pub fn api_key(&self) -> &str {
self.inner.api_key()
}
pub fn video(&self) -> VideoClient {
VideoClient::new(self.inner.clone())
}
pub fn create_token(&self, user_id: &str) -> Result<String> {
token::create_user_token(self.inner.api_secret(), user_id, &TokenOptions::default())
}
pub fn create_token_with(&self, user_id: &str, opts: TokenOptions) -> Result<String> {
token::create_user_token(self.inner.api_secret(), user_id, &opts)
}
pub fn decode_token(&self, token: &str) -> Result<TokenClaims> {
token::decode_token(self.inner.api_secret(), token)
}
pub fn verify_webhook(&self, body: &[u8], signature: &str) -> bool {
webhook::verify_signature(body, signature, self.inner.api_secret())
}
pub fn parse_webhook(&self, body: &[u8], signature: &str) -> Result<WebhookEvent> {
if !self.verify_webhook(body, signature) {
return Err(Error::Webhook(WebhookError::SignatureMismatch));
}
Ok(webhook::parse_event(body)?)
}
}
pub mod rtc;