Class: PostHog::Client

Inherits:
Object
  • Object
show all
Includes:
Logging, Utils
Defined in:
lib/posthog/client.rb

Constant Summary

Constants included from Utils

Utils::UTC_OFFSET_WITHOUT_COLON, Utils::UTC_OFFSET_WITH_COLON

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

included, #logger

Methods included from Utils

convert_to_datetime, date_in_iso8601, datetime_in_iso8601, deep_symbolize_keys, formatted_offset, get_by_symbol_or_string_key, is_valid_regex, isoify_dates, isoify_dates!, seconds_to_utc_offset, stringify_keys, symbolize_keys, symbolize_keys!, time_in_iso8601, uid

Constructor Details

#initialize(opts = {}) ⇒ Client

Returns a new instance of Client.

Parameters:

  • opts (Hash) (defaults to: {})

Options Hash (opts):

  • :api_key (String)

    Your project’s api_key

  • :personal_api_key (String)

    Your personal API key

  • :max_queue_size (FixNum)

    Maximum number of calls to be remain queued. Defaults to 10_000.

  • :test_mode (Bool)

    true if messages should remain queued for testing. Defaults to false.

  • :sync_mode (Bool)

    true to send events synchronously on the calling thread. Useful in forking environments like Sidekiq and Resque. Defaults to false.

  • :on_error (Proc)

    Handles error calls from the API.

  • :host (String)

    Fully qualified hostname of the PostHog server. Defaults to ‘us.i.posthog.com`

  • :feature_flags_polling_interval (Integer)

    How often to poll for feature flag definition changes. Measured in seconds, defaults to 30.

  • :feature_flag_request_timeout_seconds (Integer)

    How long to wait for feature flag evaluation. Measured in seconds, defaults to 3.

  • :before_send (Proc)

    A block that receives the event hash and should return either a modified hash to be sent to PostHog or nil to prevent the event from being sent. e.g. ‘before_send: ->(event) { event }`

  • :disable_singleton_warning (Bool)

    true to suppress the warning when multiple clients share the same API key. Use only when you intentionally need multiple clients. Defaults to false.

  • :flag_definition_cache_provider (Object)

    An object implementing the FlagDefinitionCacheProvider interface for distributed flag definition caching. EXPERIMENTAL: This API may change in future minor version bumps.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
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
135
136
137
138
139
140
# File 'lib/posthog/client.rb', line 75

def initialize(opts = {})
  symbolize_keys!(opts)

  opts[:api_key] = normalize_string_option(opts[:api_key])
  opts[:personal_api_key] = normalize_string_option(opts[:personal_api_key], blank_as_nil: true)
  opts[:host] = normalize_host_option(opts[:host])

  @queue = Queue.new
  @api_key = opts[:api_key]
  @max_queue_size = opts[:max_queue_size] || Defaults::Queue::MAX_SIZE
  @worker_mutex = Mutex.new
  @sync_mode = opts[:sync_mode] == true && !opts[:test_mode]
  @on_error = opts[:on_error] || proc { |status, error| }
  @worker = if opts[:test_mode]
              NoopWorker.new(@queue)
            elsif @sync_mode
              nil
            else
              SendWorker.new(@queue, @api_key, opts)
            end
  if @sync_mode
    @transport = Transport.new(
      api_host: opts[:host],
      skip_ssl_verification: opts[:skip_ssl_verification],
      retries: 3
    )
    @sync_lock = Mutex.new
  end
  @worker_thread = nil
  @feature_flags_poller = nil
  @personal_api_key = opts[:personal_api_key]

  check_api_key!
  logger.error('api_key is empty after trimming whitespace; check your project API key') if @api_key == ''

  # Warn when multiple clients are created with the same API key (can cause dropped events)
  unless opts[:test_mode] || opts[:disable_singleton_warning]
    previous_count = self.class._increment_instance_count(@api_key)
    if previous_count >= 1
      logger.warn(
        'Multiple PostHog client instances detected for the same API key. ' \
        'This can cause dropped events and inconsistent behavior. ' \
        'Use a singleton pattern: instantiate once and reuse the client. ' \
        'See https://posthog.com/docs/libraries/ruby'
      )
    end
  end

  @feature_flags_poller =
    FeatureFlagsPoller.new(
      opts[:feature_flags_polling_interval],
      opts[:personal_api_key],
      @api_key,
      opts[:host],
      opts[:feature_flag_request_timeout_seconds] || Defaults::FeatureFlags::FLAG_REQUEST_TIMEOUT_SECONDS,
      opts[:on_error],
      flag_definition_cache_provider: opts[:flag_definition_cache_provider]
    )

  @distinct_id_has_sent_flag_calls = SizeLimitedHash.new(Defaults::MAX_HASH_SIZE) do |hash, key|
    hash[key] = []
  end

  @before_send = opts[:before_send]
  @deprecation_emitted_for = Concurrent::Set.new
end

Class Method Details

._decrement_instance_count(api_key) ⇒ Object



44
45
46
47
48
49
# File 'lib/posthog/client.rb', line 44

def _decrement_instance_count(api_key)
  @instances_mutex.synchronize do
    count = (@instances_by_api_key[api_key] || 1) - 1
    @instances_by_api_key[api_key] = [count, 0].max
  end
end

._increment_instance_count(api_key) ⇒ Object



36
37
38
39
40
41
42
# File 'lib/posthog/client.rb', line 36

def _increment_instance_count(api_key)
  @instances_mutex.synchronize do
    count = @instances_by_api_key[api_key] || 0
    @instances_by_api_key[api_key] = count + 1
    count
  end
end

.reset_instance_tracking!Object

Resets instance tracking. Used primarily for testing. In production, instance counts persist for the lifetime of the process.



30
31
32
33
34
# File 'lib/posthog/client.rb', line 30

def reset_instance_tracking!
  @instances_mutex.synchronize do
    @instances_by_api_key = {}
  end
end

Instance Method Details

#alias(attrs) ⇒ Object

Aliases a user from one id to another

Parameters:

  • attrs (Hash)

Options Hash (attrs):

  • :alias (String)

    The alias to give the distinct id

  • :message_id (String)

    ID that uniquely identifies a message across the API. (optional)

  • :timestamp (Time)

    When the event occurred (optional)

  • :distinct_id (String)

    The ID for this user in your database



322
323
324
325
# File 'lib/posthog/client.rb', line 322

def alias(attrs)
  symbolize_keys! attrs
  enqueue(FieldParser.parse_for_alias(attrs))
end

#capture(attrs) ⇒ Object

Captures an event

Parameters:

  • attrs (Hash)

Options Hash (attrs):

  • :event (String)

    Event name

  • :properties (Hash)

    Event properties (optional)

  • :send_feature_flags (Bool, Hash, SendFeatureFlagsOptions)

    Whether to send feature flags with this event, or configuration for feature flag evaluation (optional)

  • :flags (PostHog::FeatureFlagEvaluations)

    A snapshot returned by #evaluate_flags. When present, ‘$feature/<key>` and `$active_feature_flags` are attached from the snapshot without making an additional /flags request, and this takes precedence over `:send_feature_flags`.

  • :uuid (String)

    ID that uniquely identifies an event; events in PostHog are deduplicated by the combination of teamId, timestamp date, event name, distinct id, and UUID

  • :message_id (String)

    ID that uniquely identifies a message across the API. (optional)

  • :timestamp (Time)

    When the event occurred (optional)

  • :distinct_id (String)

    The ID for this user in your database



189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# File 'lib/posthog/client.rb', line 189

def capture(attrs)
  symbolize_keys! attrs

  # Precedence: an explicit `flags` snapshot always wins, regardless of
  # `send_feature_flags`. The snapshot guarantees the event carries the same
  # values the developer branched on with no additional network call.
  if attrs[:flags]
    if attrs[:flags].is_a?(FeatureFlagEvaluations)
      if attrs[:send_feature_flags]
        logger.warn(
          '[FEATURE FLAGS] Both `flags` and `send_feature_flags` were passed to ' \
          'capture(); using `flags` and ignoring `send_feature_flags`.'
        )
      end
      snapshot_props = attrs[:flags]._get_event_properties
      attrs[:properties] = snapshot_props.merge(attrs[:properties] || {})
      attrs.delete(:flags)
      attrs.delete(:send_feature_flags)
    else
      logger.warn(
        '[FEATURE FLAGS] capture(flags:) expects a PostHog::FeatureFlagEvaluations snapshot ' \
        "from `client.evaluate_flags(...)`; got #{attrs[:flags].class}. Ignoring."
      )
      attrs.delete(:flags)
    end
  end

  send_feature_flags_param = attrs[:send_feature_flags]
  if send_feature_flags_param
    _emit_deprecation(
      :capture_send_feature_flags,
      '`send_feature_flags` on `capture` is deprecated and will be removed in a future major ' \
      'version. Pass a `flags` snapshot from `client.evaluate_flags(...)` instead — it ' \
      'avoids a second `/flags` request per capture and guarantees the event carries the ' \
      'exact flag values your code branched on.'
    )
    # Handle different types of send_feature_flags parameter
    case send_feature_flags_param
    when true
      # Backward compatibility: simple boolean
      feature_variants = @feature_flags_poller.get_feature_variants(attrs[:distinct_id], attrs[:groups] || {})
    when Hash
      # Hash with options
      options = SendFeatureFlagsOptions.from_hash(send_feature_flags_param)
      feature_variants = @feature_flags_poller.get_feature_variants(
        attrs[:distinct_id],
        attrs[:groups] || {},
        options ? options.person_properties : {},
        options ? options.group_properties : {},
        options ? options.only_evaluate_locally : false
      )
    when SendFeatureFlagsOptions
      # SendFeatureFlagsOptions object
      feature_variants = @feature_flags_poller.get_feature_variants(
        attrs[:distinct_id],
        attrs[:groups] || {},
        send_feature_flags_param.person_properties,
        send_feature_flags_param.group_properties,
        send_feature_flags_param.only_evaluate_locally || false
      )
    else
      # Invalid type, treat as false
      feature_variants = nil
    end

    attrs[:feature_variants] = feature_variants if feature_variants
  end

  enqueue(FieldParser.parse_for_capture(attrs))
end

#capture_exception(exception, distinct_id = nil, additional_properties = {}, flags: nil) ⇒ Object

Captures an exception as an event

Parameters:

  • exception (Exception, String, Object)

    The exception to capture, a string message, or exception-like object

  • distinct_id (String) (defaults to: nil)

    The ID for the user (optional, defaults to a generated UUID)

  • additional_properties (Hash) (defaults to: {})

    Additional properties to include with the exception event (optional)

  • flags (PostHog::FeatureFlagEvaluations) (defaults to: nil)

    A snapshot returned by #evaluate_flags. Forwarded to the inner #capture call so the captured ‘$exception` event carries the same `$feature/<key>` and `$active_feature_flags` properties as the snapshot.



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/posthog/client.rb', line 268

def capture_exception(exception, distinct_id = nil, additional_properties = {}, flags: nil)
  exception_info = ExceptionCapture.build_parsed_exception(exception)

  return if exception_info.nil?

  no_distinct_id_was_provided = distinct_id.nil?
  distinct_id ||= SecureRandom.uuid

  properties = { '$exception_list' => [exception_info] }
  properties.merge!(additional_properties) if additional_properties && !additional_properties.empty?
  properties['$process_person_profile'] = false if no_distinct_id_was_provided

  event_data = {
    distinct_id: distinct_id,
    event: '$exception',
    properties: properties,
    timestamp: Time.now
  }
  event_data[:flags] = flags if flags

  capture(event_data)
end

#clearObject

Clears the queue without waiting.

Use only in test mode



162
163
164
# File 'lib/posthog/client.rb', line 162

def clear
  @queue.clear
end

#dequeue_last_messageHash

Returns pops the last message from the queue.

Returns:

  • (Hash)

    pops the last message from the queue



328
329
330
# File 'lib/posthog/client.rb', line 328

def dequeue_last_message
  @queue.pop
end

#evaluate_flags(distinct_id, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false, disable_geoip: nil, flag_keys: nil) ⇒ PostHog::FeatureFlagEvaluations

Evaluate feature flags for a distinct id and return a snapshot.

The returned FeatureFlagEvaluations can be queried with ‘is_enabled` / `get_flag` / `get_flag_payload`, narrowed with `only_accessed` / `only`, and passed to #capture via the `flags:` option to attach `$feature/<key>` and `$active_feature_flags` without an extra /flags request.

Parameters:

  • distinct_id (String)

    The distinct id of the user

  • groups (Hash) (defaults to: {})
  • person_properties (Hash) (defaults to: {})

    key-value pairs of properties to associate with the user

  • group_properties (Hash) (defaults to: {})
  • only_evaluate_locally (Boolean) (defaults to: false)

    Skip the remote /flags call entirely

  • disable_geoip (Boolean) (defaults to: nil)

    Stamped on captured access events

  • flag_keys (Array<String>) (defaults to: nil)

    When set, scopes the underlying /flags request to only these flag keys (sent as ‘flag_keys_to_evaluate`). Distinct from FeatureFlagEvaluations#only, which filters the already-fetched snapshot in memory.

Returns:



463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
# File 'lib/posthog/client.rb', line 463

def evaluate_flags(
  distinct_id,
  groups: {},
  person_properties: {},
  group_properties: {},
  only_evaluate_locally: false,
  disable_geoip: nil,
  flag_keys: nil
)
  host = _feature_flag_evaluations_host

  if distinct_id.nil? || distinct_id.to_s.empty?
    return FeatureFlagEvaluations.new(host: host, distinct_id: '', flags: {})
  end

  person_properties, group_properties = add_local_person_and_group_properties(
    distinct_id, groups, person_properties, group_properties
  )

  records = {}
  locally_evaluated_keys = Set.new
  flag_keys_set = flag_keys&.to_set(&:to_s)

  @feature_flags_poller.load_feature_flags
  poller_flags_by_key = @feature_flags_poller.feature_flags_by_key || {}

  poller_flags_by_key.each do |key, definition|
    next if flag_keys_set && !flag_keys_set.include?(key.to_s)

    begin
      match = @feature_flags_poller.send(
        :_compute_flag_locally,
        definition, distinct_id, groups, person_properties, group_properties
      )
    rescue PostHog::RequiresServerEvaluation, PostHog::InconclusiveMatchError, StandardError
      next
    end

    next if match.nil?

    records[key.to_s] = FeatureFlagEvaluations::EvaluatedFlagRecord.new(
      key: key.to_s,
      enabled: match.is_a?(String) || (match ? true : false),
      variant: match.is_a?(String) ? match : nil,
      payload: FeatureFlagResult.parse_payload(
        @feature_flags_poller.send(:_compute_flag_payload_locally, key, match)
      ),
      id: definition[:id],
      version: nil,
      reason: FeatureFlagEvaluations::EVALUATED_LOCALLY_REASON,
      locally_evaluated: true
    )
    locally_evaluated_keys << key.to_s
  end

  request_id = nil
  evaluated_at = nil
  errors_while_computing = false
  quota_limited = false

  # Skip the remote `/flags` round-trip when the caller scoped the request
  # to a fixed set of `flag_keys` and we've already resolved every one of
  # them locally. Without `flag_keys` set, we can't know whether the server
  # has flags we don't have definitions for, so we still hit `/flags`.
  all_requested_flags_resolved_locally = flag_keys_set && (flag_keys_set - locally_evaluated_keys).empty?

  if !only_evaluate_locally && !all_requested_flags_resolved_locally
    begin
      flags_response = @feature_flags_poller.get_flags(
        distinct_id, groups, person_properties, group_properties, flag_keys, disable_geoip
      )
      request_id = flags_response[:requestId]
      evaluated_at = flags_response[:evaluatedAt]
      errors_while_computing = flags_response[:errorsWhileComputingFlags] == true
      quota_limited = (flags_response[:quotaLimited] || []).include?('feature_flags')
      remote_flags = flags_response[:flags] || {}
      remote_flags.each do |key, ff|
        key_str = key.to_s
        next if locally_evaluated_keys.include?(key_str)

         = ff.
        reason = ff.reason
        records[key_str] = FeatureFlagEvaluations::EvaluatedFlagRecord.new(
          key: key_str,
          enabled: ff.enabled ? true : false,
          variant: ff.variant,
          payload: FeatureFlagResult.parse_payload(ff.payload),
          id:  ? .id : nil,
          version:  ? .version : nil,
          reason: reason ? (reason.description || reason.code) : nil,
          locally_evaluated: false
        )
      end
    rescue StandardError => e
      @on_error&.call(-1, "Error evaluating flags remotely: #{e}")
    end
  end

  FeatureFlagEvaluations.new(
    host: host,
    distinct_id: distinct_id,
    flags: records,
    groups: groups,
    disable_geoip: disable_geoip,
    request_id: request_id,
    evaluated_at: evaluated_at,
    flag_definitions_loaded_at: @feature_flags_poller.flag_definitions_loaded_at,
    errors_while_computing: errors_while_computing,
    quota_limited: quota_limited
  )
end

#flushObject

Synchronously waits until the worker has cleared the queue.

Use only for scripts which are not long-running, and will specifically exit



146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/posthog/client.rb', line 146

def flush
  if @sync_mode
    # Wait for any in-flight sync send to complete
    @sync_lock.synchronize {} # rubocop:disable Lint/EmptyBlock
    return
  end

  while !@queue.empty? || @worker.is_requesting?
    ensure_worker_running
    sleep(0.1)
  end
end

#get_all_flags(distinct_id, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false) ⇒ Hash

Returns all flags for a given user

Parameters:

  • distinct_id (String)

    The distinct id of the user

  • groups (Hash) (defaults to: {})
  • person_properties (Hash) (defaults to: {})

    key-value pairs of properties to associate with the user.

  • group_properties (Hash) (defaults to: {})

Returns:

  • (Hash)

    String (not symbol) key value pairs of flag and their values



583
584
585
586
587
588
589
590
591
592
593
594
# File 'lib/posthog/client.rb', line 583

def get_all_flags(
  distinct_id,
  groups: {},
  person_properties: {},
  group_properties: {},
  only_evaluate_locally: false
)
  person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups,
                                                                              person_properties, group_properties)
  @feature_flags_poller.get_all_flags(distinct_id, groups, person_properties, group_properties,
                                      only_evaluate_locally)
end

#get_all_flags_and_payloads(distinct_id, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false) ⇒ Hash

Returns all flags and payloads for a given user

Parameters:

  • distinct_id (String)

    The distinct id of the user

  • [Hash] (Hash)

    a customizable set of options

  • [Boolean] (Hash)

    a customizable set of options

Returns:

  • (Hash)

    A hash with the following keys: featureFlags: A hash of feature flags featureFlagPayloads: A hash of feature flag payloads



644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
# File 'lib/posthog/client.rb', line 644

def get_all_flags_and_payloads(
  distinct_id,
  groups: {},
  person_properties: {},
  group_properties: {},
  only_evaluate_locally: false
)
  person_properties, group_properties = add_local_person_and_group_properties(
    distinct_id, groups, person_properties, group_properties
  )
  response = @feature_flags_poller.get_all_flags_and_payloads(
    distinct_id, groups, person_properties, group_properties, only_evaluate_locally
  )

  # Remove internal information
  response.delete(:requestId)
  response.delete(:evaluatedAt)
  response
end

#get_feature_flag(key, distinct_id, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false, send_feature_flag_events: true) ⇒ String?

Deprecated.

Returns whether the given feature flag is enabled for the given user or not

The provided properties are used to calculate feature flags locally, if possible.

‘groups` are a mapping from group type to group key. So, if you have a group type of “organization” and a group key of “5”, you would pass groups=“5”. `group_properties` take the format: { group_type_name: { group_properties } } So, for example, if you have the group type “organization” and the group key “5”, with the properties name, and employee count, you’ll send these as: “‘ruby

group_properties: {"organization": {"name": "PostHog", "employees": 11}}

“‘

Parameters:

  • key (String)

    The key of the feature flag

  • distinct_id (String)

    The distinct id of the user

  • groups (Hash) (defaults to: {})
  • person_properties (Hash) (defaults to: {})

    key-value pairs of properties to associate with the user.

  • group_properties (Hash) (defaults to: {})

Returns:

  • (String, nil)

    The value of the feature flag



395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
# File 'lib/posthog/client.rb', line 395

def get_feature_flag(
  key,
  distinct_id,
  groups: {},
  person_properties: {},
  group_properties: {},
  only_evaluate_locally: false,
  send_feature_flag_events: true
)
  _emit_deprecation(
    :get_feature_flag,
    '`get_feature_flag` is deprecated and will be removed in a future major version. ' \
    'Use `client.evaluate_flags(distinct_id, ...)` and call `flags.get_flag(key)` instead — ' \
    'this consolidates flag evaluation into a single `/flags` request per incoming request.'
  )
  # Bypass the public `get_feature_flag_result` so the user only sees one deprecation warning.
  result = _get_feature_flag_result(
    key, distinct_id,
    groups: groups, person_properties: person_properties, group_properties: group_properties,
    only_evaluate_locally: only_evaluate_locally, send_feature_flag_events: send_feature_flag_events
  )
  result&.value
end

#get_feature_flag_payload(key, distinct_id, match_value: nil, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false) ⇒ Object

Deprecated.

Use #get_feature_flag_result instead, which returns both the flag value and payload and properly raises the $feature_flag_called event.

Returns payload for a given feature flag

Parameters:

  • key (String)

    The key of the feature flag

  • distinct_id (String)

    The distinct id of the user

  • [String (Hash)

    a customizable set of options

  • [Hash] (Hash)

    a customizable set of options

  • [Boolean] (Hash)

    a customizable set of options



610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
# File 'lib/posthog/client.rb', line 610

def get_feature_flag_payload(
  key,
  distinct_id,
  match_value: nil,
  groups: {},
  person_properties: {},
  group_properties: {},
  only_evaluate_locally: false
)
  _emit_deprecation(
    :get_feature_flag_payload,
    '`get_feature_flag_payload` is deprecated and will be removed in a future major version. ' \
    'Use `client.evaluate_flags(distinct_id, ...)` and call `flags.get_flag_payload(key)` ' \
    'instead — this consolidates flag evaluation into a single `/flags` request per ' \
    'incoming request.'
  )
  person_properties, group_properties = add_local_person_and_group_properties(distinct_id, groups,
                                                                              person_properties, group_properties)
  @feature_flags_poller.get_feature_flag_payload(key, distinct_id, match_value, groups, person_properties,
                                                 group_properties, only_evaluate_locally)
end

#get_feature_flag_result(key, distinct_id, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false, send_feature_flag_events: true) ⇒ Object



421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
# File 'lib/posthog/client.rb', line 421

def get_feature_flag_result(
  key,
  distinct_id,
  groups: {},
  person_properties: {},
  group_properties: {},
  only_evaluate_locally: false,
  send_feature_flag_events: true
)
  _emit_deprecation(
    :get_feature_flag_result,
    '`get_feature_flag_result` is deprecated and will be removed in a future major version. ' \
    'Use `client.evaluate_flags(distinct_id, ...)` and call `flags.get_flag(key)` / ' \
    '`flags.get_flag_payload(key)` instead — this consolidates flag evaluation into a single ' \
    '`/flags` request per incoming request.'
  )
  _get_feature_flag_result(
    key, distinct_id,
    groups: groups, person_properties: person_properties, group_properties: group_properties,
    only_evaluate_locally: only_evaluate_locally, send_feature_flag_events: send_feature_flag_events
  )
end

#get_remote_config_payload(flag_key) ⇒ String

Returns The decrypted value of the feature flag payload.

Parameters:

  • flag_key (String)

    The unique flag key of the feature flag

Returns:

  • (String)

    The decrypted value of the feature flag payload



369
370
371
# File 'lib/posthog/client.rb', line 369

def get_remote_config_payload(flag_key)
  @feature_flags_poller.get_remote_config_payload(flag_key)
end

#group_identify(attrs) ⇒ Object

Identifies a group

Parameters:

  • attrs (Hash)

Options Hash (attrs):

  • :group_type (String)

    Group type

  • :group_key (String)

    Group key

  • :properties (Hash)

    Group properties (optional)

  • :distinct_id (String)

    Distinct ID (optional)

  • :message_id (String)

    ID that uniquely identifies a message across the API. (optional)

  • :timestamp (Time)

    When the event occurred (optional)

  • :distinct_id (String)

    The ID for this user in your database



311
312
313
314
# File 'lib/posthog/client.rb', line 311

def group_identify(attrs)
  symbolize_keys! attrs
  enqueue(FieldParser.parse_for_group_identify(attrs))
end

#identify(attrs) ⇒ Object

Identifies a user

Parameters:

  • attrs (Hash)

Options Hash (attrs):

  • :properties (Hash)

    User properties (optional)

  • :message_id (String)

    ID that uniquely identifies a message across the API. (optional)

  • :timestamp (Time)

    When the event occurred (optional)

  • :distinct_id (String)

    The ID for this user in your database



297
298
299
300
# File 'lib/posthog/client.rb', line 297

def identify(attrs)
  symbolize_keys! attrs
  enqueue(FieldParser.parse_for_identify(attrs))
end

#is_feature_enabled(flag_key, distinct_id, groups: {}, person_properties: {}, group_properties: {}, only_evaluate_locally: false, send_feature_flag_events: true) ⇒ Object

Deprecated.

Use #evaluate_flags and FeatureFlagEvaluations#is_enabled instead.

TODO: In future version, rename to ‘feature_flag_enabled?`



339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
# File 'lib/posthog/client.rb', line 339

def is_feature_enabled( # rubocop:disable Naming/PredicateName
  flag_key,
  distinct_id,
  groups: {},
  person_properties: {},
  group_properties: {},
  only_evaluate_locally: false,
  send_feature_flag_events: true
)
  _emit_deprecation(
    :is_feature_enabled,
    '`is_feature_enabled` is deprecated and will be removed in a future major version. ' \
    'Use `client.evaluate_flags(distinct_id, ...)` and call `flags.enabled?(key)` instead — ' \
    'this consolidates flag evaluation into a single `/flags` request per incoming request.'
  )
  # Bypass the public `get_feature_flag` so the user only sees a single deprecation
  # warning per call, not a cascade.
  result = _get_feature_flag_result(
    flag_key, distinct_id,
    groups: groups, person_properties: person_properties, group_properties: group_properties,
    only_evaluate_locally: only_evaluate_locally, send_feature_flag_events: send_feature_flag_events
  )
  response = result&.value
  return nil if response.nil?

  !!response
end

#queued_messagesFixnum

Returns number of messages in the queue.

Returns:

  • (Fixnum)

    number of messages in the queue



333
334
335
# File 'lib/posthog/client.rb', line 333

def queued_messages
  @queue.length
end

#reload_feature_flagsObject



664
665
666
667
668
669
670
671
672
# File 'lib/posthog/client.rb', line 664

def reload_feature_flags
  unless @personal_api_key
    logger.error(
      'You need to specify a personal_api_key to locally evaluate feature flags'
    )
    return
  end
  @feature_flags_poller.load_feature_flags(true)
end

#shutdownObject



674
675
676
677
678
679
680
681
682
683
# File 'lib/posthog/client.rb', line 674

def shutdown
  self.class._decrement_instance_count(@api_key) if @api_key
  @feature_flags_poller.shutdown_poller
  flush
  if @sync_mode
    @sync_lock.synchronize { @transport&.shutdown }
  else
    @worker&.shutdown
  end
end