Class: OmniSocials::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/omnisocials/client.rb

Overview

Synchronous client for the OmniSocials Public API.

require "omnisocials"

client = OmniSocials::Client.new  # reads OMNISOCIALS_API_KEY from env
# or: OmniSocials::Client.new(api_key: "omsk_live_...", base_url: ...,
#                             timeout: ..., max_retries: ...)

post = client.posts.create(
content: "Hello from the SDK",
channels: ["instagram", "linkedin"],
scheduled_at: "2026-08-01T09:00:00Z"
)

Zero runtime dependencies: built on Net::HTTP, OpenSSL, and JSON from the Ruby standard library. A fresh connection is opened per request, so there is nothing to close.

Constant Summary collapse

DEFAULT_BASE_URL =
"https://api.omnisocials.com/v1"
DEFAULT_TIMEOUT =
30.0
DEFAULT_MAX_RETRIES =
2
USER_AGENT =
"omnisocials-ruby/#{VERSION}"
RETRY_STATUSES =

Statuses that are retried automatically (alongside connection errors).

[429, 500, 502, 503, 504].freeze
METHOD_CLASSES =
{
  "GET" => Net::HTTP::Get,
  "POST" => Net::HTTP::Post,
  "PATCH" => Net::HTTP::Patch,
  "DELETE" => Net::HTTP::Delete
}.freeze
CONNECTION_ERRORS =
[
  Errno::ECONNREFUSED,
  Errno::ECONNRESET,
  Errno::EHOSTUNREACH,
  Errno::ENETUNREACH,
  Errno::EPIPE,
  Errno::ETIMEDOUT,
  SocketError,
  EOFError,
  IOError,
  Net::OpenTimeout,
  Net::ReadTimeout,
  Net::WriteTimeout,
  OpenSSL::SSL::SSLError,
  Timeout::Error
].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api_key: nil, base_url: nil, timeout: DEFAULT_TIMEOUT, max_retries: DEFAULT_MAX_RETRIES) ⇒ Client

api_key - API key (omsk_live_* / omsk_test_*). Falls back to the OMNISOCIALS_API_KEY environment variable. Raises OmniSocials::AuthenticationError when neither is set. base_url - API base URL (default https://api.omnisocials.com/v1). timeout - per-request timeout in seconds (default 30). max_retries - automatic retries after the first attempt (default 2), applied on 429, 5xx, and connection errors.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/omnisocials/client.rb', line 72

def initialize(api_key: nil, base_url: nil, timeout: DEFAULT_TIMEOUT,
               max_retries: DEFAULT_MAX_RETRIES)
  key = api_key.nil? || api_key.to_s.empty? ? ENV["OMNISOCIALS_API_KEY"] : api_key
  if key.nil? || key.to_s.empty?
    raise AuthenticationError.new(
      "No API key provided. Pass api_key: ... to OmniSocials::Client.new " \
      "or set the OMNISOCIALS_API_KEY environment variable. Create a key " \
      "in the OmniSocials app under Settings -> API Keys.",
      status: nil
    )
  end
  @api_key = key
  @base_url = (base_url || DEFAULT_BASE_URL).sub(%r{/+\z}, "")
  @timeout = Float(timeout)
  @max_retries = [max_retries.to_i, 0].max

  @posts = Resources::Posts.new(self)
  @media = Resources::Media.new(self)
  @folders = Resources::Folders.new(self)
  @accounts = Resources::Accounts.new(self)
  @analytics = Resources::Analytics.new(self)
  @locations = Resources::Locations.new(self)
  @webhooks = Resources::Webhooks.new(self)
end

Instance Attribute Details

#accountsObject (readonly)

Returns the value of attribute accounts.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def accounts
  @accounts
end

#analyticsObject (readonly)

Returns the value of attribute analytics.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def analytics
  @analytics
end

#api_keyObject (readonly)

Returns the value of attribute api_key.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def api_key
  @api_key
end

#base_urlObject (readonly)

Returns the value of attribute base_url.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def base_url
  @base_url
end

#foldersObject (readonly)

Returns the value of attribute folders.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def folders
  @folders
end

#locationsObject (readonly)

Returns the value of attribute locations.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def locations
  @locations
end

#max_retriesObject (readonly)

Returns the value of attribute max_retries.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def max_retries
  @max_retries
end

#mediaObject (readonly)

Returns the value of attribute media.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def media
  @media
end

#postsObject (readonly)

Returns the value of attribute posts.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def posts
  @posts
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def timeout
  @timeout
end

#webhooksObject (readonly)

Returns the value of attribute webhooks.



61
62
63
# File 'lib/omnisocials/client.rb', line 61

def webhooks
  @webhooks
end

Instance Method Details

#healthObject

GET /health - API health check (no scopes required).



98
99
100
# File 'lib/omnisocials/client.rb', line 98

def health
  request("GET", "/health")
end

#request(method, path, query: nil, json: nil, multipart: nil) ⇒ Object

Perform an HTTP request against the API with automatic retries.

Returns the parsed response body (Hash/Array) as-is, the raw text for non-JSON responses, or nil for 204. Raises an OmniSocials::APIError subclass on non-2xx and OmniSocials::APIConnectionError when no response was ever received.

Raises:



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/omnisocials/client.rb', line 108

def request(method, path, query: nil, json: nil, multipart: nil)
  uri = build_uri(path, query)
  last_error = nil

  (max_retries + 1).times do |attempt|
    begin
      response = perform(method, uri, json: json, multipart: multipart)
    rescue *CONNECTION_ERRORS => e
      last_error = e
      break if attempt >= max_retries

      sleep(Internal.backoff_delay(attempt, nil))
      next
    end

    should_retry, retry_after = retry_info(response)
    if should_retry && attempt < max_retries
      sleep(Internal.backoff_delay(attempt, retry_after))
      next
    end
    return handle_response(response)
  end

  raise APIConnectionError,
        "Connection error while requesting #{method} #{uri}: " \
        "#{last_error.class}: #{last_error.message}"
end