Module: Webhookdb
- Extended by:
 - MethodUtilities
 
- Includes:
 - Appydays::Configurable, Appydays::Loggable
 
- Defined in:
 - lib/webhookdb.rb,
lib/webhookdb/json.rb,
lib/webhookdb/version.rb 
Defined Under Namespace
Modules: API, AWS, Admin, AdminAPI, Apps, Async, Console, Crypto, Dbutil, DemoMode, EmailOctopus, Enumerable, Fixtures, Formatting, Front, GoogleCalendar, Http, Icalendar, Id, IntegrationSpecHelpers, Intercom, Jobs, Json, Liquid, Message, Messages, MethodUtilities, MicrosoftCalendar, Nextpax, Oauth, PhoneNumber, Plaid, Platform, Plivo, Postgres, Postmark, Redis, Sentry, Signalwire, SpecHelpers, Sponsy, Tasks, Theranest, Transistor, Twilio, WindowsTZ Classes: AggregateResult, BackfillJob, Backfiller, Cloudflare, ConnectionCache, Convertkit, Customer, DBAdapter, DatabaseDocument, DatabaseLocked, DeveloperAlert, Github, Heroku, Idempotency, Increase, InvalidInput, InvalidPostcondition, InvalidPrecondition, InvariantViolation, LockFailed, LoggedWebhook, Organization, OrganizationMembership, RegressionModeSkip, Replicator, Role, Service, ServiceIntegration, Shopify, Slack, Snowflake, Stripe, Subscription, SyncTarget, TypedStruct, WebhookResponse, WebhookSubscription, Webterm, Xml
Constant Summary collapse
- APPLICATION_NAME =
 "Webhookdb"- RACK_ENV =
 ENV.fetch("RACK_ENV", "development")
- COMMIT =
 ENV.fetch("HEROKU_SLUG_COMMIT", "unknown-commit")
- RELEASE =
 ENV.fetch("HEROKU_RELEASE_VERSION", "unknown-release")
- RELEASE_CREATED_AT =
 ENV.fetch("HEROKU_RELEASE_CREATED_AT") { Time.at(0).utc.iso8601 }
- INTEGRATION_TESTS_ENABLED =
 ENV.fetch("INTEGRATION_TESTS", false)
- DATA_DIR =
 Pathname(__FILE__).dirname.parent + "data"
- UNAMBIGUOUS_CHARS =
          
Remove ambiguous characters (L, I, 1 or 0, O) and vowels from possible codes to avoid creating ambiguous codes or real words.
 "CDFGHJKMNPQRTVWXYZ23469".chars.freeze
- NUMBERS_TO_WORDS =
 { "0" => "zero", "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five", "6" => "six", "7" => "seven", "8" => "eight", "9" => "nine", }.freeze
- VERSION =
 "0.1.0"
Class Method Summary collapse
- 
  
    
      .cached_get(key)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
If globals caching is enabled, see if there is a cached value under
keyand return it if so. - 
  
    
      .idempotency_key(instance, *parts)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Generate a key for the specified Sequel model
instanceand any additionalpartsthat can be used for idempotent requests. - .load_app ⇒ Object
 - 
  
    
      .regression_mode?  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    
Regression mode is true when we re replaying webhooks locally, or for some other reason, want to disable certain checks we use in production.
 - 
  
    
      .request_user_and_admin  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Return the request user and admin stored in TLS.
 - 
  
    
      .set_request_user_and_admin(user, admin, &block)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Return the request user stored in TLS.
 - .take_unambiguous_chars(n) ⇒ Object
 - 
  
    
      .to_slug(s)  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Convert a string into something we consistently use for slugs: a-z, 0-9, and underscores only.
 
Methods included from MethodUtilities
attr_predicate, attr_predicate_accessor, singleton_attr_accessor, singleton_attr_reader, singleton_attr_writer, singleton_method_alias, singleton_predicate_accessor, singleton_predicate_reader
Class Method Details
.cached_get(key) ⇒ Object
If globals caching is enabled, see if there is a cached value under key and return it if so. If there is not, evaluate the given block and store that value. Generally used for looking up well-known database objects like certain roles.
      109 110 111 112 113 114 115 116 117  | 
    
      # File 'lib/webhookdb.rb', line 109 def self.cached_get(key) if self.use_globals_cache result = self.globals_cache[key] return result if result end result = yield() self.globals_cache[key] = result return result end  | 
  
.idempotency_key(instance, *parts) ⇒ Object
Generate a key for the specified Sequel model instance and any additional parts that can be used for idempotent requests.
      127 128 129 130 131 132 133 134 135 136 137 138 139  | 
    
      # File 'lib/webhookdb.rb', line 127 def self.idempotency_key(instance, *parts) key = "%s-%s" % [instance.class.implicit_table_name, instance.pk] if instance.respond_to?(:updated_at) && instance.updated_at parts << instance.updated_at elsif instance.respond_to?(:created_at) && instance.created_at parts << instance.created_at end parts << SecureRandom.hex(8) if self.bust_idempotency key << "-" << parts.map(&:to_s).join("-") unless parts.empty? return key end  | 
  
.load_app ⇒ Object
      89 90 91 92 93 94 95 96 97  | 
    
      # File 'lib/webhookdb.rb', line 89 def self.load_app $stdout.sync = true $stderr.sync = true Appydays::Loggable.configure_12factor(format: self.log_format, application: APPLICATION_NAME) require "webhookdb/postgres" Webhookdb::Postgres.load_models end  | 
  
.regression_mode? ⇒ Boolean
Regression mode is true when we re replaying webhooks locally, or for some other reason, want to disable certain checks we use in production. For example, we may want to ignore certain errors (like if integrations are missing dependency rows), or disable certain validations (like always assume the webhook is valid).
      80 81 82  | 
    
      # File 'lib/webhookdb.rb', line 80 def self.regression_mode? return self.regression_mode end  | 
  
.request_user_and_admin ⇒ Object
Return the request user and admin stored in TLS. See service.rb for implementation.
Note that the second return value (the admin) will be nil if not authed as an admin, and if an admin is impersonating, the impersonated customer is the first value.
Both values will be nil if no user is authed or this is called outside of a request.
Usually these fields should only be used where it would be sufficiently difficult to pass the current user through the stack. In the API, you should instead use the ‘current customer’ methods like current_customer, and admin_customer, NOT using TLS. Outside of the API, this should only be used for things like auditing; it should NOT, for example, ever be used to determine the ‘customer owner’ of objects being created. Nearly all code will be simpler if the current customer is passed around. But it would be too complex for some code (like auditing) so this system exists. Overuse of request_user_and_admin will inevitably lead to regret.
      196 197 198  | 
    
      # File 'lib/webhookdb.rb', line 196 def self.request_user_and_admin return Thread.current[:request_user], Thread.current[:request_admin] end  | 
  
.set_request_user_and_admin(user, admin, &block) ⇒ Object
Return the request user stored in TLS. See service.rb for details.
      201 202 203 204 205 206 207 208 209 210 211 212 213 214  | 
    
      # File 'lib/webhookdb.rb', line 201 def self.set_request_user_and_admin(user, admin, &block) if !user.nil? && !admin.nil? && self.request_user_and_admin != [nil, nil] raise Webhookdb::InvalidPrecondition, "request user is already set: #{user}, #{admin}" end Thread.current[:request_user] = user Thread.current[:request_admin] = admin return if block.nil? begin yield ensure Thread.current[:request_user] = nil Thread.current[:request_admin] = nil end end  | 
  
.take_unambiguous_chars(n) ⇒ Object
      149 150 151  | 
    
      # File 'lib/webhookdb.rb', line 149 def self.take_unambiguous_chars(n) return Array.new(n) { UNAMBIGUOUS_CHARS.sample }.join end  | 
  
.to_slug(s) ⇒ Object
Convert a string into something we consistently use for slugs: a-z, 0-9, and underscores only. Leading numbers are converted to words.
Acme + Corporation -> “acme_corporation” 1Byte -> “one_byte” 10Byte -> “one0_byte”
      159 160 161 162 163 164 165  | 
    
      # File 'lib/webhookdb.rb', line 159 def self.to_slug(s) raise ArgumentError, "s cannot be nil" if s.nil? return "" if s.blank? slug = s.downcase.strip.gsub(/[^a-z0-9]/, "_").squeeze("_") slug = NUMBERS_TO_WORDS[slug.first] + slug[1..] if slug.first.match?(/[0-9]/) return slug end  |