Module: Webhookdb::Replicator::IntercomV1Mixin

Included in:
IntercomContactV1, IntercomConversationV1
Defined in:
lib/webhookdb/replicator/intercom_v1_mixin.rb

Constant Summary collapse

QUESTIONABLE_TIMESTAMP =

Timestamps can be unix timestamps when listing a resource, or strings in other cases, like webhooks. This may have to do with API versions. Handle both.

Webhookdb::Replicator::Column::IsomorphicProc.new(
  ruby: lambda do |i, **_|
    return nil if i.nil?
    return Time.at(i)
  rescue TypeError
    return Time.parse(i)
  end,
  sql: lambda do |*|
    # We would have to check the type of the data, which is a pain, so don't worry about this for now.
    raise NotImplementedError
  end,
)

Instance Method Summary collapse

Instance Method Details

#_fetch_backfill_page(pagination_token, **_kwargs) ⇒ Object



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
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 78

def _fetch_backfill_page(pagination_token, **_kwargs)
  unless self.auth_credentials?
    raise Webhookdb::Replicator::CredentialsMissing,
          "This integration requires that the Intercom Auth integration has a valid Auth Token"
  end

  query = {per_page: Webhookdb::Intercom.page_size}
  # Intercom started 500ing with this set to empty.
  query[:starting_after] = pagination_token if pagination_token
  begin
    response = Webhookdb::Http.get(
      self._mixin_backfill_url,
      query:,
      headers: self.intercom_auth_headers,
      logger: self.logger,
      timeout: Webhookdb::Intercom.http_timeout,
    )
  rescue Webhookdb::Http::Error => e
    #  We are looking to catch the "api plan restricted" error. This is always a 403 and every
    # 403 will be an "api plan restricted" error according to the API documentation. Because we
    # specify the API version in our headers we can expect that this won't change.
    raise e unless e.status == 403
    self.logger.warn("intercom_api_restricted", intercom_error: e.body)
    # We should basically noop here, i.e. pretend that the page is empty, so that we don't trigger
    # a TypeError in the backfiller.
    return [], nil
  end
  data = response.parsed_response.fetch("data", [])
  starting_after = response.parsed_response.dig("pages", "next", "starting_after")
  return data, starting_after
end

#_mixin_backfill_urlObject

Raises:

  • (NotImplementedError)


76
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 76

def _mixin_backfill_url = raise NotImplementedError

#_resource_and_event(request) ⇒ Object



41
42
43
44
45
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 41

def _resource_and_event(request)
  body = request.body
  return body.fetch("data").fetch("item"), body if body.fetch("type") == "notification_event"
  return body, nil
end

#_timestamp_column_nameObject



51
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 51

def _timestamp_column_name = :updated_at

#_update_where_exprObject



47
48
49
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 47

def _update_where_expr
  return self.qualified_table_sequel_identifier[:updated_at] < Sequel[:excluded][:updated_at]
end

#_webhook_response(request) ⇒ Object



53
54
55
56
57
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 53

def _webhook_response(request)
  # Intercom webhooks are done through a centralized oauth replicator,
  # so the secret is for the app, not the individual replicator.
  return Webhookdb::Intercom.webhook_response(request, Webhookdb::Intercom.client_secret)
end

#auth_credentials?Boolean

Returns:

  • (Boolean)


36
37
38
39
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 36

def auth_credentials?
  auth = self.find_auth_integration
  return auth.backfill_key.present?
end

#calculate_backfill_state_machineWebhookdb::Replicator::StateMachineStep



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 60

def calculate_backfill_state_machine
  # can inherit credentials from the auth dependency
  if (step = self.calculate_dependency_state_machine_step(dependency_help: ""))
    return step
  end
  step = Webhookdb::Replicator::StateMachineStep.new
  step.output = %(We will start replicating #{self.resource_name_singular} information into your WebhookDB database.

#{self._query_help_output(prefix: "Once data is available, you can query #{self.resource_name_plural}.")})
  return step.completed
end

#find_auth_integrationObject

Quick note on these Intercom integrations: although we will technically be bringing in information from webhooks, all webhooks for the WebhookDB app will use a single endpoint and we use the WebhookDB app’s Client Secret for webhook verification, which means that webhooks actually don’t require any setup on the integration level. Thus, ‘supports_webhooks` is false.



24
25
26
27
28
29
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 24

def find_auth_integration
  # rubocop:disable Naming/MemoizedInstanceVariableName
  return @auth ||= Webhookdb::Replicator.find_at_root!(self.service_integration,
                                                       service_name: "intercom_marketplace_root_v1",)
  # rubocop:enable Naming/MemoizedInstanceVariableName
end

#intercom_auth_headersObject



31
32
33
34
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 31

def intercom_auth_headers
  root_sint = self.find_auth_integration
  return Webhookdb::Intercom.auth_headers(root_sint.backfill_key)
end

#on_dependency_webhook_upsert(_replicator, _payload) ⇒ Object



72
73
74
# File 'lib/webhookdb/replicator/intercom_v1_mixin.rb', line 72

def on_dependency_webhook_upsert(_replicator, _payload, *)
  return
end