- New error class hierarchy under
GetStreamRuby:StreamError < StandardError. Abstract base for every SDK-raised exception.ApiError < StreamError. Raised on any HTTP 4xx/5xx, and on responses whose body cannot be parsed as the canonicalAPIErrorenvelope. Exposesstatus_code,code,message,exception_fields,unrecoverable,raw_response_body,more_info,details. Previously onlymessagesurvived.RateLimitError < ApiError. Raised on HTTP 429. Addsretry_after(Float seconds, nil when the header is absent). Parses theRetry-Afterresponse header per RFC 7231 in both integer-seconds and HTTP-date forms. Past HTTP-dates clamp to 0.TransportError < StreamError. Raised when no HTTP response is received (connection reset, timeout, TLS handshake failure, DNS failure). Exposeserror_typefrom the enumconnection_reset,timeout,dns_failure,tls_handshake_failed,unknown. Always raised inside the matchingrescue Faraday::Errorblock, soException#causeis set to the underlying Faraday error.TaskError < StreamError. Raised bywait_for_taskwhen an async task finishes withstatus="failed". Exposestask_id,error_type,description,stack_trace,version.
- New
Client#wait_for_task(task_id, poll_interval: 1, timeout: 60)helper. Polls/api/v2/tasks/:idand: returns the taskresultpayload when status reachescompleted; raisesTaskErrorwhen status reachesfailed; raisesTransportErrorwitherror_type: "timeout"when the deadline elapses. Client#post(and the multipart upload path) now deserialize the full canonicalAPIErrorenvelope (code,message,exception_fields,more_info,StatusCode,details,unrecoverable,duration) and populate the newApiErrorattributes.- Regenerated from the latest chat OpenAPI spec. New endpoints:
Moderation#analyze,Moderation#bulk_action_appeals,Moderation#get_setup_session,Moderation#upsert_setup_session;Feeds#get_or_create_follow,Feeds#get_or_create_unfollow,Feeds#get_user_interests;Chat#create_segment,Chat#update_segment,Chat#add_segment_targets;Common#cancel_import_v2_task;Video#report_client_call_event, together with the request and response models backing them. - New webhook event types
moderation.image_analysis.completeandmoderation.text_analysis.complete, parsed intoModerationImageAnalysisCompleteEventandModerationTextAnalysisCompleteEvent. - Structured logging (CHA-2957): the existing
logger:kwarg onGetStreamRuby::Client.new/Configurationnow drives 4 events:client.initialized(INFO, once at construction),http.request.sentandhttp.response.received(DEBUG, the latter fires for every response including 4xx/5xx), andhttp.request.failed(ERROR, transport failures only, no HTTP response received). Query values and top-level JSON body keys forapi_key/api_secret/token/passwordare always redacted to<redacted>; no headers are ever logged. Newlog_bodies:option (defaultfalse) opts into logging request/response bodies (still key-redacted) and emits one WARN at construction. NewGetStreamRuby::LogRedactionmodule (redact_query,redact_json_body,redact_message). - New opt-in retry policy (CHA-2959):
GetStreamRuby::RetryConfig(enabled:,max_attempts:,max_backoff:) passed via the newretry_config:option onClient.new/Configuration. Disabled by default. When enabled, onlyGET/HEADrequests are retried, and only on HTTP 429 (unlessunrecoverable) or a transport error, honoringRetry-After(clamped tomax_backoff, no jitter) or otherwise waiting a full-jitter delay up tomin(max_backoff, 2**attempt). Each retried attempt logshttp.request.failedat DEBUG with aretry.attemptfield.
- The old
GetStreamRuby::APIErrorconstant remains as a deprecated alias forGetStreamRuby::ApiErrorfor one minor cycle, slated for removal in v9.0. First access emits a one-timeKernel.warndeprecation notice. - The old
GetStreamRuby::Errorconstant is preserved as an alias forStreamError. Existingrescue GetStreamRuby::Errorclauses continue to match. - Pre-flight multipart validation (
file name must be provided,file not found) now raisesArgumentErrorinstead of the oldAPIError. These are caller-side programming errors and don't belong on the API-error surface. Models::FlagResponsenow represents the full flag record (created_at,updated_at,target_message,target_user,user,reason,details,custom, and related fields). The moderation flag-action acknowledgement, which carriesitem_idandduration, moved to the newModels::FlagItemResponse;Moderation#flagnow returnsFlagItemResponse. The wire response of/api/v2/moderation/flagis unchanged, only the model name changed, so code readingitem_id/durationoff the parsed response is unaffected. Code referencing theFlagResponsemodel class for those two fields should switch toFlagItemResponse.ChannelInput#config_overridesandChannelDataUpdate#config_overridesare now typed asChannelConfigOverrides(the override-specific field set) instead of the fullChannelConfig.LLMRule#descriptionandTargetResolution#bitrateare now optional.- The former "connection pool" INFO line (CHA-2956) is now
client.initializedand carries the structured-logging field set above (adapter identity is no longer part of it; a silent adapter fallback still always WARNs, seewarn_pool_fallback). Its old$stdoutfallback is removed: with nologger:configured, the SDK now produces zero log output. - Breaking: removed the always-on
faraday-retrymiddleware (and thefaraday-retryruntime dependency). It used to silently retryGET/HEAD/PUT/DELETE/OPTIONSrequests up to 3 times on a timeout exception only (never on 429 or other HTTP status codes). Retries are now opt-in viaretry_config:(see Added), apply only toGET/HEAD, and additionally cover 429. Passretry_config: GetStreamRuby::RetryConfig.new(enabled: true)to restore retry-on-timeout behavior.
- Webhook handling spec helpers (CHA-2961):
UnknownEventclass for forward-compat;gunzip_payload,decode_sqs_payload,decode_sns_payloadprimitives;parse_event(returns typed event orUnknownEventfor unrecognized discriminators);verify_and_parse_webhookHTTP composite;parse_sqs/parse_snsqueue composites (no signature; backend emits no HMAC for queue messages today). Security for queue-delivered payloads is enforced via AWS IAM on the SQS/SNS subscription, not in-SDK. - New
Stream::Webhookmodule alias (preferred).StreamChat::Webhookretained as backward-compat alias for one minor-version cycle. - New unified error class:
StreamChat::Webhook::InvalidWebhookErrorcovering signature mismatch, invalid JSON, missing/non-stringtypefield, gzip decompression failure, invalid base64 in a queue body, and malformed SNS envelopes. Distinguish failure modes via the message substring orcausechain rather than the class. - New instance methods on
GetStreamRuby::Client:verify_signature(body, signature)andverify_and_parse_webhook(body, signature)that drop theapi_secretparameter in favor of the client's stored secret. Dual API: module-level methods remain available. - New instance methods on
GetStreamRuby::Client:parse_sqs(message_body)andparse_sns(notification_body)(no signature; AWS IAM). - Conformance fixture suite under
test/fixtures/webhooks/(14 event-type buckets plus_invalid/negative cases).
- Auth tokens now backdate the JWT
iatclaim byClient::AUTH_IAT_LEEWAY_SECONDS(5s).iatis a whole-second value (RFC 7519 NumericDate) and the server applies minimal forward leeway, so stampingiat = Time.now.to_icaused a small fraction of requests to be rejected withtoken used before issue at (iat)(HTTP 401) whenever the caller's clock was even marginally ahead of the server and the second-truncation landed on a boundary. Backdating keeps the token safely behind the server clock. The legacystream-chat-rubyclient never sentiat, so upgrades from it newly exposed this. event_class_for_typenow referencesGetStream::Generated::Models::*Event(wasStreamChat::*Event, which raisedNameErrorat runtime).parse_eventresolves known event types correctly.
- New runtime dependency:
faraday-net_http_persistent ~> 2.3+net-http-persistent ~> 4.0. Default Faraday adapter switched fromFaraday.default_adapter(plainNet::HTTP, no pool) to:net_http_persistent(pooled). Matches legacystream-chat-ruby. - New constructor kwargs on
GetStreamRuby.manual/Configuration:max_conns_per_host:default5idle_timeout:default55(seconds)connect_timeout:default10(seconds)request_timeout:default30(seconds)http_client:escape hatch (Faraday::Connection); when set, the 4 knobs above are ignored.
- Per-call
request_timeout:kwarg onClient#make_requestfor one-off overrides without rebuilding the client. - One INFO log on
Client.newlisting the effective pool config + escape-hatch flag.
- Default adapter is now
:net_http_persistent; long-lived processes hold up to 5 idle TCP connections per upstream host until they age out at 55s. - The
Connection: keep-aliverequest header is no longer emitted on the default path (net_http_persistentkeeps connections alive natively). Still emitted when the user opts into a customfaraday_adapterwithconnection_keep_alive: true.
- The
timeout:kwarg remains as an alias forrequest_timeout:. - The
faraday_adapterkwarg remains as an alternate escape hatch. When set,pool_size/idle_timeoutare NOT applied (those arenet_http_persistent-specific).
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Type names across all products now follow the OpenAPI spec naming convention: response types are suffixed with
Response, input types withRequest. See MIGRATION_v2_to_v3.md for the complete rename mapping. Event(WebSocket envelope type) renamed toWSEvent. Base event type renamed fromBaseEventtoEvent(with fieldtypeinstead ofT).- Event composition changed from monolithic
*Presetembeds to modularHas*types. Pagerrenamed toPagerResponseand migrated from offset-based to cursor-based pagination (next/prevtokens).
- Full product coverage: Chat, Video, Moderation, and Feeds APIs are all supported in a single SDK.
- Feeds: activities, feeds, feed groups, follows, comments, reactions, collections, bookmarks, membership levels, feed views, and more.
- Video: calls, recordings, transcription, closed captions, SFU, call statistics, user feedback analytics, and more.
- Moderation: flags, review queue, moderation rules, config, appeals, moderation logs, and more.
- Push notification types, preferences, and templates.
- Webhook support:
WHEventenvelope class for receiving webhook payloads, utility methods for decoding and verifying webhook signatures, and a full set of individual typed event classes for every event across all products (Chat, Video, Moderation, Feeds) usable as discriminated event types. - Cursor-based pagination across all list endpoints.