mirror of https://github.com/docusealco/docuseal
				
				
				
			
							parent
							
								
									7bc8e194df
								
							
						
					
					
						commit
						534c3a2e10
					
				@ -0,0 +1,52 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module Api
 | 
				
			||||||
 | 
					  class SubmissionEventsController < ApiBaseController
 | 
				
			||||||
 | 
					    load_and_authorize_resource :submission, parent: false
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def index
 | 
				
			||||||
 | 
					      submissions = build_completed_query(@submissions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      params[:after] = Time.zone.at(params[:after].to_i) if params[:after].present?
 | 
				
			||||||
 | 
					      params[:before] = Time.zone.at(params[:before].to_i) if params[:before].present?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      submissions = paginate(submissions.preload(
 | 
				
			||||||
 | 
					                               :created_by_user, :submission_events,
 | 
				
			||||||
 | 
					                               template: :folder,
 | 
				
			||||||
 | 
					                               submitters: { documents_attachments: :blob, attachments_attachments: :blob },
 | 
				
			||||||
 | 
					                               audit_trail_attachment: :blob
 | 
				
			||||||
 | 
					                             ),
 | 
				
			||||||
 | 
					                             field: :completed_at)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      render json: {
 | 
				
			||||||
 | 
					        data: submissions.map do |s|
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  event_type: 'submission.completed',
 | 
				
			||||||
 | 
					                  timestamp: s.completed_at,
 | 
				
			||||||
 | 
					                  data: Submissions::SerializeForApi.call(s, s.submitters)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              end,
 | 
				
			||||||
 | 
					        pagination: {
 | 
				
			||||||
 | 
					          count: submissions.size,
 | 
				
			||||||
 | 
					          next: submissions.last&.completed_at&.to_i,
 | 
				
			||||||
 | 
					          prev: submissions.first&.completed_at&.to_i
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def build_completed_query(submissions)
 | 
				
			||||||
 | 
					      submissions = submissions.where(
 | 
				
			||||||
 | 
					        Submitter.where(completed_at: nil).where(
 | 
				
			||||||
 | 
					          Submitter.arel_table[:submission_id].eq(Submission.arel_table[:id])
 | 
				
			||||||
 | 
					        ).select(1).arel.exists.not
 | 
				
			||||||
 | 
					      )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      submissions.joins(:submitters)
 | 
				
			||||||
 | 
					                 .group(:id)
 | 
				
			||||||
 | 
					                 .select(Submission.arel_table[Arel.star],
 | 
				
			||||||
 | 
					                         Submitter.arel_table[:completed_at].maximum.as('completed_at'))
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					# frozen_string_literal: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SendSubmissionCompletedWebhookRequestJob
 | 
				
			||||||
 | 
					  include Sidekiq::Job
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  sidekiq_options queue: :webhooks
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  USER_AGENT = 'DocuSeal.co Webhook'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  MAX_ATTEMPTS = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  def perform(params = {})
 | 
				
			||||||
 | 
					    submission = Submission.find(params['submission_id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    attempt = params['attempt'].to_i
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    webhook_url = submission.account.webhook_urls.find(params['webhook_url_id'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    url = webhook_url.url if webhook_url.events.include?('submission.completed')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return if url.blank?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    resp = begin
 | 
				
			||||||
 | 
					      Faraday.post(url,
 | 
				
			||||||
 | 
					                   {
 | 
				
			||||||
 | 
					                     event_type: 'submission.completed',
 | 
				
			||||||
 | 
					                     timestamp: Time.current,
 | 
				
			||||||
 | 
					                     data: Submissions::SerializeForApi.call(submission)
 | 
				
			||||||
 | 
					                   }.to_json,
 | 
				
			||||||
 | 
					                   **EncryptedConfig.find_or_initialize_by(account_id: submission.account_id,
 | 
				
			||||||
 | 
					                                                           key: EncryptedConfig::WEBHOOK_SECRET_KEY)&.value.to_h,
 | 
				
			||||||
 | 
					                   '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))
 | 
				
			||||||
 | 
					      SendSubmissionCompletedWebhookRequestJob.perform_in((2**attempt).minutes, {
 | 
				
			||||||
 | 
					                                                            **params,
 | 
				
			||||||
 | 
					                                                            'attempt' => attempt + 1,
 | 
				
			||||||
 | 
					                                                            'last_status' => resp&.status.to_i
 | 
				
			||||||
 | 
					                                                          })
 | 
				
			||||||
 | 
					    end
 | 
				
			||||||
 | 
					  end
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
					Loading…
					
					
				
		Reference in new issue