diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 44e39e6a..3d0f96b9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -34,8 +34,8 @@ class ApplicationController < ActionController::Base redirect_to setup_index_path unless User.exists? end - def button_title(title: 'Submit', disabled_with: 'Submitting', icon: nil) - render_to_string(partial: 'shared/button_title', locals: { title:, disabled_with:, icon: }) + def button_title(title: 'Submit', disabled_with: 'Submitting', icon: nil, icon_disabled: nil) + render_to_string(partial: 'shared/button_title', locals: { title:, disabled_with:, icon:, icon_disabled: }) end def svg_icon(icon_name, class: '') diff --git a/app/controllers/submit_form_controller.rb b/app/controllers/submit_form_controller.rb index 57188d98..dea2bb87 100644 --- a/app/controllers/submit_form_controller.rb +++ b/app/controllers/submit_form_controller.rb @@ -17,11 +17,8 @@ class SubmitFormController < ApplicationController def update submitter = Submitter.find_by!(slug: params[:slug]) - submitter.values.merge!(normalized_values) - submitter.completed_at = Time.current if params[:completed] == 'true' - submitter.opened_at ||= Time.current - submitter.save! + update_submitter!(submitter) Submissions.update_template_fields!(submitter.submission) if submitter.submission.template_fields.blank? @@ -30,6 +27,10 @@ class SubmitFormController < ApplicationController if submitter.completed_at? GenerateSubmitterResultAttachmentsJob.perform_later(submitter) + if submitter.account.encrypted_configs.exists?(key: EncryptedConfig::WEBHOOK_URL_KEY) + SendWebhookRequestJob.perform_later(submitter) + end + submitter.submission.template.account.users.active.each do |user| SubmitterMailer.completed_email(submitter, user).deliver_later! end @@ -44,6 +45,16 @@ class SubmitFormController < ApplicationController private + def update_submitter!(submitter) + submitter.values.merge!(normalized_values) + submitter.completed_at = Time.current if params[:completed] == 'true' + submitter.opened_at ||= Time.current + + submitter.save! + + submitter + end + def normalized_values params.fetch(:values, {}).to_unsafe_h.transform_values do |v| if params[:cast_boolean] == 'true' diff --git a/app/controllers/webhook_settings_controller.rb b/app/controllers/webhook_settings_controller.rb new file mode 100644 index 00000000..4d0cc119 --- /dev/null +++ b/app/controllers/webhook_settings_controller.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +class WebhookSettingsController < ApplicationController + def show + @encrypted_config = + current_account.encrypted_configs.find_or_initialize_by(key: EncryptedConfig::WEBHOOK_URL_KEY) + end + + def create + @encrypted_config = + current_account.encrypted_configs.find_or_initialize_by(key: EncryptedConfig::WEBHOOK_URL_KEY) + + @encrypted_config.update!(encrypted_config_params) + + redirect_back(fallback_location: settings_webhooks_path, notice: 'Webhook URL has been saved.') + end + + def update + submitter = current_account.submitters.where.not(completed_at: nil).order(:id).last + + SendWebhookRequestJob.perform_later(submitter) + + redirect_back(fallback_location: settings_webhooks_path, notice: 'Webhook request has been sent.') + end + + private + + def encrypted_config_params + params.require(:encrypted_config).permit(:value) + end +end diff --git a/app/jobs/send_webhook_request_job.rb b/app/jobs/send_webhook_request_job.rb new file mode 100644 index 00000000..0ca7c919 --- /dev/null +++ b/app/jobs/send_webhook_request_job.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +class SendWebhookRequestJob < ApplicationJob + USER_AGENT = 'DocuSeal.co Webhook' + + def perform(submitter) + config = submitter.submission.account.encrypted_configs.find_by(key: EncryptedConfig::WEBHOOK_URL_KEY) + + return if config.blank? || config.value.blank? + + Submissions::EnsureResultGenerated.call(submitter) + + ActiveStorage::Current.url_options = Docuseal.default_url_options + + Faraday.post(config.value, + { + event_type: 'form.submitted', + timestamp: Time.current.iso8601, + data: Submitters::SerializeForWebhook.call(submitter) + }.to_json, + 'Content-Type' => 'application/json', + 'User-Agent' => USER_AGENT) + end +end diff --git a/app/models/account.rb b/app/models/account.rb index 60d03ebd..96a1d9f3 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -15,6 +15,8 @@ class Account < ApplicationRecord has_many :users, dependent: :destroy has_many :encrypted_configs, dependent: :destroy has_many :templates, dependent: :destroy + has_many :submissions, through: :templates + has_many :submitters, through: :submissions has_many :active_users, -> { active }, dependent: :destroy, inverse_of: :account, class_name: 'User' diff --git a/app/models/encrypted_config.rb b/app/models/encrypted_config.rb index e06e5f52..e3600bb0 100644 --- a/app/models/encrypted_config.rb +++ b/app/models/encrypted_config.rb @@ -25,6 +25,7 @@ class EncryptedConfig < ApplicationRecord EMAIL_SMTP_KEY = 'action_mailer_smtp' ESIGN_CERTS_KEY = 'esign_certs' APP_URL_KEY = 'app_url' + WEBHOOK_URL_KEY = 'webhook_url' belongs_to :account diff --git a/app/models/submission.rb b/app/models/submission.rb index 116ade07..c7f3e0c2 100644 --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -26,6 +26,7 @@ # class Submission < ApplicationRecord belongs_to :template + has_one :account, through: :template belongs_to :created_by_user, class_name: 'User', optional: true has_many :submitters, dependent: :destroy diff --git a/app/models/submitter.rb b/app/models/submitter.rb index 35c1a3e6..d09a1288 100644 --- a/app/models/submitter.rb +++ b/app/models/submitter.rb @@ -30,6 +30,8 @@ # class Submitter < ApplicationRecord belongs_to :submission + has_one :template, through: :submission + has_one :account, through: :template attribute :values, :string, default: -> { {} } attribute :slug, :string, default: -> { SecureRandom.base58(14) } diff --git a/app/views/api_settings/index.html.erb b/app/views/api_settings/index.html.erb index 4ef20920..489f2b1e 100644 --- a/app/views/api_settings/index.html.erb +++ b/app/views/api_settings/index.html.erb @@ -5,9 +5,9 @@
curl --location '<%= api_submissions_url %>' \
+ <% text = capture do %>curl --location '<%= api_submissions_url %>' \
--header 'X-Auth-Token: <%= jwt %>' \
--data-raw '{
- "template_id": <%= current_account.templates.last.id %>,
+ "template_id": <%= current_account.templates.last&.id || 1 %>,
"emails": "<%= current_user.email.sub('@', '+test@') %>, <%= current_user.email.sub('@', '+test2@') %>"
- }'
+ }'<% end.to_str %>
+
+ <%= render 'shared/clipboard_copy', icon: 'copy', text:, class: 'btn btn-ghost text-white', icon_class: 'w-6 h-6 text-white', copy_title: 'Copy', copied_title: 'Copied' %>
+
+ <%= text %>
curl --location '<%= api_submissions_url %>' \
+ <% text = capture do %>curl --location '<%= api_submissions_url %>' \
--header 'X-Auth-Token: <%= jwt %>' \
--data-raw '{
- "template_id": <%= current_account.templates.last.id %>,
+ "template_id": <%= current_account.templates.last&.id || 1 %>,
"submission": [
{
"submitters": [
- { "name": "<%= current_account.templates.last.submitters.first['name'] %>", "email": "<%= current_user.email.sub('@', '+test@') %>" },
+ { "name": "<%= current_account.templates.last ? current_account.templates.last.submitters.first['name'] : 'First Submitter' %>", "email": "<%= current_user.email.sub('@', '+test@') %>" },
{ "name": "Second Submitter", "email": "<%= current_user.email.sub('@', '+test2@') %>" }
]
}
]
- }'
+ }'<% end.to_str %>
+
+ <%= render 'shared/clipboard_copy', icon: 'copy', text:, class: 'btn btn-ghost text-white', icon_class: 'w-6 h-6 text-white', copy_title: 'Copy', copied_title: 'Copied' %>
+
+ <%= text %>