Files
astuto/app/jobs/run_webhook.rb
Riccardo Graziosi a12a95eccc Add webhooks (#447)
2024-12-20 14:06:48 +01:00

105 lines
2.8 KiB
Ruby

class RunWebhook < ActiveJob::Base
queue_as :webhooks
# entities is a hash with entity_name as key and entity_id as value (entity_name will be mapped to an ActiveRecord class)
def perform(webhook_id:, current_tenant_id:, is_test: false, entities: {})
Current.tenant = Tenant.find(current_tenant_id)
logger.info { "[#{Current.tenant.subdomain}] Performing RunWebhook ActiveJob for webhook ID #{webhook_id}" }
# Find webhook from DB
webhook = Webhook.find(webhook_id)
# Skip if webhook is disabled and is not a test
return if !is_test && !webhook.is_enabled
# Load entities from DB
loaded_entities = {}
entities.each do |entity_name, entity_id|
entity_class = map_entity_name_to_class(entity_name)
# If there is an ActiveRecord class for that entity_name, load it from DB
# Otherwise, just pass the ID (this is the special case of trigger 'delete_post')
if entity_class
loaded_entities[entity_name] = entity_class.find(entity_id)
else
loaded_entities[entity_name] = entity_id
end
end
# Build context based on webhook's trigger
context = CreateLiquidTemplateContextWorkflow.new(
webhook_trigger: webhook.trigger,
is_test: is_test,
entities: loaded_entities,
).run
# Parse and render template for webhook's URL
url_template = Liquid::Template.parse(webhook.url)
url = url_template.render(context)
# Parse and render template for webhook's HTTP body
http_body_template = Liquid::Template.parse(webhook.http_body)
http_body = http_body_template.render(context)
# Prepare HTTP body
if webhook.http_body.present?
http_body = JSON.parse(http_body).to_json
else
http_body = nil
end
# Prepare HTTP headers
if webhook.http_headers.present?
http_headers = JSON.parse(webhook.http_headers).each_with_object({}) do |header, memo|
memo[header['key']] = header['value']
end
else
http_headers = {}
end
# Make HTTP request
HTTParty.send(
map_webhook_http_method(webhook.http_method).downcase,
url,
{
body: http_body,
headers: http_headers,
}
)
end
private
def map_webhook_http_method(http_method)
case http_method
when :http_post
'POST'
when :http_put
'PUT'
when :http_patch
'PATCH'
when :http_delete
'DELETE'
else
'POST'
end
end
def map_entity_name_to_class(entity_name)
case entity_name
when :post
Post
when :user, :post_author, :comment_author, :vote_author
User
when :board
Board
when :post_status
PostStatus
when :comment
Comment
else
nil
end
end
end