debian-mirror-gitlab/app/workers/integrations/slack_event_worker.rb
2023-07-09 08:55:56 +05:30

54 lines
1.6 KiB
Ruby

# frozen_string_literal: true
module Integrations
class SlackEventWorker
include ApplicationWorker
EVENTS = {
'app_home_opened' => SlackEvents::AppHomeOpenedService
}.freeze
feature_category :integrations
data_consistency :delayed
urgency :low
deduplicate :until_executed
idempotent!
worker_has_external_dependencies!
def self.event?(slack_event)
EVENTS.key?(slack_event)
end
def perform(args)
args = args.with_indifferent_access
log_extra_metadata_on_done(:slack_event, args[:slack_event])
log_extra_metadata_on_done(:slack_user_id, args.dig(:params, :event, :user))
log_extra_metadata_on_done(:slack_workspace_id, args.dig(:params, :team_id))
unless self.class.event?(args[:slack_event])
Sidekiq.logger.error(
message: 'Unknown slack_event',
slack_event: args[:slack_event]
)
return
end
# Ensure idempotency by taking out an exclusive lease keyed to `params.event_id`.
# The `event_id` is "a unique identifier for this specific event, globally unique
# across all workspaces" and guaranteed to be present as part of the Slack event JSON schema.
# See https://api.slack.com/types/event.
lease = Gitlab::ExclusiveLease.new("slack_event:#{args[:params][:event_id]}", timeout: 1.hour.to_i)
return unless lease.try_obtain
service_class = EVENTS[args[:slack_event]]
response = service_class.new(args[:params]).execute
lease.cancel if response.error?
rescue StandardError => e
lease.cancel
raise e
end
end
end