add submission created webhook event
This commit is contained in:
@@ -22,7 +22,7 @@ module Api
|
|||||||
audit_trail_attachment: :blob))
|
audit_trail_attachment: :blob))
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
data: submissions.as_json(serialize_params),
|
data: submissions.as_json(Submissions::SerializeForApi::SERIALIZE_PARAMS),
|
||||||
pagination: {
|
pagination: {
|
||||||
count: submissions.size,
|
count: submissions.size,
|
||||||
next: submissions.last&.id,
|
next: submissions.last&.id,
|
||||||
@@ -44,29 +44,7 @@ module Api
|
|||||||
@submission.audit_trail_attachment = Submissions::GenerateAuditTrail.call(@submission)
|
@submission.audit_trail_attachment = Submissions::GenerateAuditTrail.call(@submission)
|
||||||
end
|
end
|
||||||
|
|
||||||
serialized_submitters = submitters.map { |submitter| Submitters::SerializeForApi.call(submitter) }
|
render json: Submissions::SerializeForApi.call(@submission, submitters)
|
||||||
|
|
||||||
json = @submission.as_json(
|
|
||||||
serialize_params.deep_merge(
|
|
||||||
include: { submission_events: { only: %i[id submitter_id event_type event_timestamp] } }
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if submitters.all?(&:completed_at?)
|
|
||||||
last_submitter = submitters.max_by(&:completed_at)
|
|
||||||
|
|
||||||
json[:documents] = serialized_submitters.find { |e| e['id'] == last_submitter.id }['documents']
|
|
||||||
json[:status] = 'completed'
|
|
||||||
json[:completed_at] = last_submitter.completed_at
|
|
||||||
else
|
|
||||||
json[:documents] = []
|
|
||||||
json[:status] = 'pending'
|
|
||||||
json[:completed_at] = nil
|
|
||||||
end
|
|
||||||
|
|
||||||
json[:submitters] = serialized_submitters
|
|
||||||
|
|
||||||
render json:
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@@ -85,6 +63,10 @@ module Api
|
|||||||
|
|
||||||
submissions = create_submissions(@template, params)
|
submissions = create_submissions(@template, params)
|
||||||
|
|
||||||
|
submissions.each do |submission|
|
||||||
|
SendSubmissionCreatedWebhookRequestJob.perform_later(submission)
|
||||||
|
end
|
||||||
|
|
||||||
Submissions.send_signature_requests(submissions)
|
Submissions.send_signature_requests(submissions)
|
||||||
|
|
||||||
submissions.each do |submission|
|
submissions.each do |submission|
|
||||||
@@ -153,22 +135,6 @@ module Api
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def serialize_params
|
|
||||||
{
|
|
||||||
only: %i[id source submitters_order created_at updated_at archived_at],
|
|
||||||
methods: %i[audit_log_url],
|
|
||||||
include: {
|
|
||||||
submitters: { only: %i[id slug uuid name email phone
|
|
||||||
completed_at opened_at sent_at
|
|
||||||
created_at updated_at external_id metadata],
|
|
||||||
methods: %i[status application_key] },
|
|
||||||
template: { only: %i[id name external_id created_at updated_at],
|
|
||||||
methods: %i[folder_name] },
|
|
||||||
created_by_user: { only: %i[id email first_name last_name] }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
def submissions_params
|
def submissions_params
|
||||||
permitted_attrs = [
|
permitted_attrs = [
|
||||||
:send_email, :send_sms, :bcc_completed, :completed_redirect_url, :reply_to, :go_to_last,
|
:send_email, :send_sms, :bcc_completed, :completed_redirect_url, :reply_to, :go_to_last,
|
||||||
|
|||||||
@@ -33,7 +33,11 @@ class StartFormController < ApplicationController
|
|||||||
|
|
||||||
assign_submission_attributes(@submitter, @template) if @submitter.new_record?
|
assign_submission_attributes(@submitter, @template) if @submitter.new_record?
|
||||||
|
|
||||||
|
is_new_record = @submitter.new_record?
|
||||||
|
|
||||||
if @submitter.save
|
if @submitter.save
|
||||||
|
SendSubmissionCreatedWebhookRequestJob.perform_later(@submitter.submission) if is_new_record
|
||||||
|
|
||||||
redirect_to submit_form_path(@submitter.slug)
|
redirect_to submit_form_path(@submitter.slug)
|
||||||
else
|
else
|
||||||
render :show
|
render :show
|
||||||
|
|||||||
@@ -44,6 +44,10 @@ class SubmissionsController < ApplicationController
|
|||||||
params: params.merge('send_completed_email' => true))
|
params: params.merge('send_completed_email' => true))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
submissions.each do |submission|
|
||||||
|
SendSubmissionCreatedWebhookRequestJob.perform_later(submission)
|
||||||
|
end
|
||||||
|
|
||||||
Submissions.send_signature_requests(submissions)
|
Submissions.send_signature_requests(submissions)
|
||||||
|
|
||||||
redirect_to template_path(@template), notice: 'New recipients have been added'
|
redirect_to template_path(@template), notice: 'New recipients have been added'
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ class WebhookPreferencesController < ApplicationController
|
|||||||
form.completed
|
form.completed
|
||||||
template.created
|
template.created
|
||||||
template.updated
|
template.updated
|
||||||
|
submission.created
|
||||||
submission.archived
|
submission.archived
|
||||||
].freeze
|
].freeze
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class SendSubmissionCreatedWebhookRequestJob < ApplicationJob
|
||||||
|
USER_AGENT = 'DocuSeal.co Webhook'
|
||||||
|
|
||||||
|
MAX_ATTEMPTS = 10
|
||||||
|
|
||||||
|
def perform(submission, params = {})
|
||||||
|
attempt = params[:attempt].to_i
|
||||||
|
url = Accounts.load_webhook_url(submission.account)
|
||||||
|
|
||||||
|
return if url.blank?
|
||||||
|
|
||||||
|
preferences = Accounts.load_webhook_preferences(submission.account)
|
||||||
|
|
||||||
|
return if preferences['submission.created'].blank?
|
||||||
|
|
||||||
|
resp = begin
|
||||||
|
Faraday.post(url,
|
||||||
|
{
|
||||||
|
event_type: 'submission.created',
|
||||||
|
timestamp: Time.current,
|
||||||
|
data: Submissions::SerializeForApi.call(submission)
|
||||||
|
}.to_json,
|
||||||
|
'Content-Type' => 'application/json',
|
||||||
|
'User-Agent' => USER_AGENT)
|
||||||
|
rescue Faraday::Error
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if (resp.nil? || resp.status.to_i >= 400) && attempt <= MAX_ATTEMPTS &&
|
||||||
|
(!Docuseal.multitenant? || submission.account.account_configs.exists?(key: :plan))
|
||||||
|
SendSubmissionCreatedWebhookRequestJob.set(wait: (2**attempt).minutes)
|
||||||
|
.perform_later(submission, {
|
||||||
|
attempt: attempt + 1,
|
||||||
|
last_status: resp&.status.to_i
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -15,22 +15,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% preference = current_account.account_configs.find_by(key: AccountConfig::WEBHOOK_PREFERENCES_KEY)&.value || {} %>
|
<% preference = current_account.account_configs.find_by(key: AccountConfig::WEBHOOK_PREFERENCES_KEY)&.value || {} %>
|
||||||
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 mt-2 gap-y-2">
|
<% WebhookPreferencesController::EVENTS.group_by { |e| e.include?('form') }.each do |_, events| %>
|
||||||
<% WebhookPreferencesController::EVENTS.each do |event| %>
|
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 mt-2 gap-y-2">
|
||||||
<%= form_for '', url: webhook_preferences_path, method: :post do |f| %>
|
<% events.each do |event| %>
|
||||||
<%= f.hidden_field :event, value: event %>
|
<%= form_for '', url: webhook_preferences_path, method: :post do |f| %>
|
||||||
<% uuid = SecureRandom.uuid %>
|
<%= f.hidden_field :event, value: event %>
|
||||||
<div class="flex">
|
<% uuid = SecureRandom.uuid %>
|
||||||
<label for="<%= uuid %>" class="flex items-center space-x-2">
|
<div class="flex">
|
||||||
<%= f.check_box :value, class: 'base-checkbox', checked: preference[event] || (!preference.key?(event) && event.starts_with?('form.')), onchange: 'this.form.requestSubmit()', id: uuid %>
|
<label for="<%= uuid %>" class="flex items-center space-x-2">
|
||||||
<span>
|
<%= f.check_box :value, class: 'base-checkbox', checked: preference[event] || (!preference.key?(event) && event.starts_with?('form.')), onchange: 'this.form.requestSubmit()', id: uuid %>
|
||||||
<%= event %>
|
<span>
|
||||||
</span>
|
<%= event %>
|
||||||
</label>
|
</span>
|
||||||
</div>
|
</label>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
</div>
|
||||||
</div>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<% submitter = current_account.submitters.where.not(completed_at: nil).order(:id).last %>
|
<% submitter = current_account.submitters.where.not(completed_at: nil).order(:id).last %>
|
||||||
|
|||||||
@@ -0,0 +1,49 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Submissions
|
||||||
|
module SerializeForApi
|
||||||
|
SERIALIZE_PARAMS = {
|
||||||
|
only: %i[id source submitters_order created_at updated_at archived_at],
|
||||||
|
methods: %i[audit_log_url],
|
||||||
|
include: {
|
||||||
|
submitters: { only: %i[id slug uuid name email phone
|
||||||
|
completed_at opened_at sent_at
|
||||||
|
created_at updated_at external_id metadata],
|
||||||
|
methods: %i[status application_key] },
|
||||||
|
template: { only: %i[id name external_id created_at updated_at],
|
||||||
|
methods: %i[folder_name] },
|
||||||
|
created_by_user: { only: %i[id email first_name last_name] }
|
||||||
|
}
|
||||||
|
}.freeze
|
||||||
|
|
||||||
|
module_function
|
||||||
|
|
||||||
|
def call(submission, submitters = nil)
|
||||||
|
submitters ||= submission.submitters.preload(documents_attachments: :blob, attachments_attachments: :blob)
|
||||||
|
|
||||||
|
serialized_submitters = submitters.map { |submitter| Submitters::SerializeForApi.call(submitter) }
|
||||||
|
|
||||||
|
json = submission.as_json(
|
||||||
|
SERIALIZE_PARAMS.deep_merge(
|
||||||
|
include: { submission_events: { only: %i[id submitter_id event_type event_timestamp] } }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if submitters.all?(&:completed_at?)
|
||||||
|
last_submitter = submitters.max_by(&:completed_at)
|
||||||
|
|
||||||
|
json[:documents] = serialized_submitters.find { |e| e['id'] == last_submitter.id }['documents']
|
||||||
|
json[:status] = 'completed'
|
||||||
|
json[:completed_at] = last_submitter.completed_at
|
||||||
|
else
|
||||||
|
json[:documents] = []
|
||||||
|
json[:status] = 'pending'
|
||||||
|
json[:completed_at] = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
json[:submitters] = serialized_submitters
|
||||||
|
|
||||||
|
json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user