1. Add WebhookDeliveryJob

This job is responsible for delivering a payload for one webhook event only. It allows the action to run asynchronously (and not slow down the calling process).
This commit is contained in:
David Cook
2022-09-15 21:41:05 +10:00
parent 718ac0ab80
commit 9d19f37fec
2 changed files with 78 additions and 0 deletions

View File

@@ -0,0 +1,31 @@
# frozen_string_literal: true
require "faraday"
# Deliver a webhook payload
# As a delayed job, it can run asynchronously and handle retries.
class WebhookDeliveryJob < ApplicationJob
queue_as :default
def perform(url, event, payload)
body = {
id: job_id,
at: Time.zone.now.to_s,
event: event,
data: payload,
}
notify_endpoint(url, body)
end
def notify_endpoint(url, body)
connection = Faraday.new(
request: { timeout: 30 },
headers: {
'User-Agent' => 'openfoodnetwork_webhook/1.0',
'Content-Type' => 'application/json',
}
)
connection.post(url, body.to_json)
end
end

View File

@@ -0,0 +1,47 @@
# frozen_string_literal: true
require 'spec_helper'
describe WebhookDeliveryJob do
subject { WebhookDeliveryJob.new(url, event, data) }
let(:url) { 'https://test/endpoint' }
let(:event) { 'order_cycle.opened' }
let(:data) {
{
order_cycle_id: 123, name: "Order cycle 1", open_at: 1.minute.ago.to_s, tags: ["tag1", "tag2"]
}
}
before do
stub_request(:post, url)
end
it "sends a request to specified url" do
subject.perform_now
expect(a_request(:post, url)).to have_been_made.once
end
it "delivers a payload" do
Timecop.freeze(Time.zone.now) do
expected_body = {
id: /.+/,
at: Time.zone.now.to_s,
event: event,
data: data,
}
subject.perform_now
expect(a_request(:post, url).with(body: expected_body)).
to have_been_made.once
end
end
# To be implemented in following commits
pending "can't access local secrets" # see https://medium.com/in-the-weeds/all-about-paperclips-cve-2017-0889-server-side-request-forgery-ssrf-vulnerability-8cb2b1c96fe8
describe "retrying" do
pending "doesn't retry on internal failure"
pending "retries after external failure"
pending "stops retrying after a while"
end
end