Class: Webhookdb::Replicator::UrlRecorderV1

Inherits:
Base
  • Object
show all
Includes:
Appydays::Loggable
Defined in:
lib/webhookdb/replicator/url_recorder_v1.rb

Constant Summary

Constants inherited from Base

Base::MAX_INDEX_NAME_LENGTH

Constants included from DBAdapter::ColumnTypes

DBAdapter::ColumnTypes::BIGINT, DBAdapter::ColumnTypes::BIGINT_ARRAY, DBAdapter::ColumnTypes::BOOLEAN, DBAdapter::ColumnTypes::COLUMN_TYPES, DBAdapter::ColumnTypes::DATE, DBAdapter::ColumnTypes::DECIMAL, DBAdapter::ColumnTypes::DOUBLE, DBAdapter::ColumnTypes::FLOAT, DBAdapter::ColumnTypes::INTEGER, DBAdapter::ColumnTypes::INTEGER_ARRAY, DBAdapter::ColumnTypes::OBJECT, DBAdapter::ColumnTypes::TEXT, DBAdapter::ColumnTypes::TEXT_ARRAY, DBAdapter::ColumnTypes::TIMESTAMP, DBAdapter::ColumnTypes::UUID

Instance Attribute Summary

Attributes inherited from Base

#service_integration

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#_any_subscriptions_to_notify?, #_backfill_state_change_fields, #_backfillers, #_clear_backfill_information, #_clear_webook_information, #_coalesce_excluded_on_update, #_enqueue_backfill_jobs, #_extra_index_specs, #_fetch_enrichment, #_find_dependency_candidate, #_notify_dependents, #_parallel_backfill, #_publish_rowupsert, #_store_enrichment_body?, #_to_json, #_upsert_update_expr, #_upsert_webhook, #_verify_backfill_err_msg, #_webhook_state_change_fields, #admin_dataset, #backfill, #backfill_not_supported_message, #calculate_and_backfill_state_machine, #calculate_backfill_state_machine, #calculate_dependency_state_machine_step, #calculate_preferred_create_state_machine, chunked_row_update_bounds, #clear_backfill_information, #clear_webhook_information, #create_table, #create_table_modification, #data_column, #dbadapter_table, #denormalized_columns, #descriptor, #dispatch_request_to, #documentation_url, #enqueue_sync_targets, #enrichment_column, #ensure_all_columns, #ensure_all_columns_modification, #find_dependent, #find_dependent!, #indices, #initialize, #on_dependency_webhook_upsert, #preferred_create_state_machine_method, #preprocess_headers_for_logging, #primary_key_column, #process_state_change, #qualified_table_sequel_identifier, #readonly_dataset, #remote_key_column, #resource_name_plural, #resource_name_singular, #schema_and_table_symbols, #storable_columns, #timestamp_column, #upsert_has_deps?, #upsert_webhook, #upsert_webhook_body, #verify_backfill_credentials, #webhook_endpoint, #webhook_response

Constructor Details

This class inherits a constructor from Webhookdb::Replicator::Base

Class Method Details

.descriptorWebhookdb::Replicator::Descriptor



7
8
9
10
11
12
13
14
15
16
17
18
19
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 7

def self.descriptor
  return Webhookdb::Replicator::Descriptor.new(
    name: "url_recorder_v1",
    ctor: ->(sint) { self.new(sint) },
    feature_roles: [],
    resource_name_singular: "URL Recorder",
    supports_webhooks: true,
    supports_backfill: false,
    description: "Record any visit to the webhook URL for later inspection. " \
                 "Useful for recording scans, like visiting QR Code. After the webhook, " \
                 "visitors can be redirected, or shown a Markdown page.",
  )
end

Instance Method Details

#_denormalized_columnsObject



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 25

def _denormalized_columns
  col = Webhookdb::Replicator::Column
  return [
    col.new(:inserted_at, TIMESTAMP, index: true),
    col.new(:request_method, TEXT),
    col.new(:path, TEXT),
    col.new(:full_url, TEXT),
    col.new(:user_agent, TEXT),
    col.new(:ip, TEXT),
    col.new(:content_type, TEXT),
    col.new(:parsed_query, OBJECT),
    col.new(:parsed_body, OBJECT),
    col.new(:raw_body, TEXT),
  ]
end

#_page_responseObject



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 95

def _page_response
  headers = {"Content-Type" => "text/html; charset=UTF-8"}
  content = self.service_integration.api_url
  content_is_doc = content.start_with?("<!DOCTYPE") || content.starts_with?("<html")
  body = if content_is_doc
           content
  else
    tmpl_file = File.open(Webhookdb::DATA_DIR + "messages/replicators/url-recorder.liquid")
    liquid_tmpl = Liquid::Template.parse(tmpl_file.read)
    liquid_tmpl.render!({"content" => content})
  end
  return Webhookdb::WebhookResponse.new(status: 200, headers:, body:)
end

#_prepare_for_insert(_resource, event, request, enrichment) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 46

def _prepare_for_insert(_resource, event, request, enrichment)
  # rr = Rack::Request.new
  rr = request.rack_request
  raise Webhookdb::InvalidPrecondition, "#{request} must have rack_request set" if rr.nil?
  r = {
    "unique_id" => self.service_integration.sequence_nextval,
    "inserted_at" => Time.now,
    "request_method" => rr.request_method,
    "path" => rr.path,
    "parsed_query" => rr.GET,
    "raw_query" => rr.query_string,
    "full_url" => rr.url,
    "user_agent" => rr.user_agent,
    "ip" => rr.ip,
    "content_type" => rr.content_type,
    "raw_body" => nil,
    "parsed_body" => nil,
  }
  if !request.body.is_a?(String)
    # If we were able to parse the request body (usually means it's JSON), store it.
    r["parsed_body"] = request.body
  elsif rr.POST.present?
    # If Rack was able to parse the request body (usually means it's form encoded), store it.
    r["parsed_body"] = rr.POST
  else
    # Store the raw body if nothing can parse it.
    r["raw_body"] = request.body
  end
  return super(r, event, request, enrichment)
end

#_redirect_responseObject



90
91
92
93
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 90

def _redirect_response
  headers = {"Location" => self.service_integration.api_url, "Content-Type" => "text/plain"}
  return Webhookdb::WebhookResponse.new(status: 302, headers:, body: "")
end

#_remote_key_columnObject



21
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 21

def _remote_key_column = Webhookdb::Replicator::Column.new(:unique_id, BIGINT)

#_resource_and_event(_request) ⇒ Object



42
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 42

def _resource_and_event(_request) = [{}, nil]

#_resource_to_dataObject



77
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 77

def _resource_to_data(*) = {}

#_timestamp_column_nameObject



41
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 41

def _timestamp_column_name = :inserted_at

#_update_where_exprObject



44
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 44

def _update_where_expr = self.qualified_table_sequel_identifier[:inserted_at] < Sequel[:excluded][:inserted_at]

#_webhook_response(_request) ⇒ Object



79
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 79

def _webhook_response(_request) = self.redirect? ? self._redirect_response : self._page_response

#calculate_webhook_state_machineObject



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

def calculate_webhook_state_machine
  step = Webhookdb::Replicator::StateMachineStep.new
  if self.service_integration.api_url.blank?
    step.output = %(After users visit the WebhookDB endpoint,
they can either be redirected to a location of your own,
or we'll render an HTML page to show them.

To use a redirect, input a URL starting with 'https://'.

To render a page, paste in the HTML:

- If the text starts with an `html` tag, it will be used as-is
for the page's HTML, so you can use your own styles.
- Otherwise we assume the content is a relatively simple message,
and it's rendered with basic WebhookDB styles.)
    return step.prompting("URL, HTML, or text").api_url(self.service_integration)
  end
  step.output = %(
All set! Every visit to
#{self.webhook_endpoint}
will be recorded.

If you want to modify what users see after the visit is recorded,
run `webhookdb integration reset #{self.descriptor.name}.

#{self._query_help_output})
  return step.completed
end

#process_webhooks_synchronously?Boolean

Returns:

  • (Boolean)


81
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 81

def process_webhooks_synchronously? = true

#redirect?Boolean

Returns:

  • (Boolean)


88
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 88

def redirect? = self.service_integration.api_url =~ %r{^https?://}

#requires_sequence?Boolean

Returns:

  • (Boolean)


23
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 23

def requires_sequence? = true

#synchronous_processing_response_bodyObject



83
84
85
86
# File 'lib/webhookdb/replicator/url_recorder_v1.rb', line 83

def synchronous_processing_response_body(*)
  resp = self.redirect? ? self._redirect_response : self._page_response
  return resp.body
end