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

176 lines
4.6 KiB
Ruby

# frozen_string_literal: true
module Integrations
class GitlabSlackApplication < BaseSlackNotification
attribute :alert_events, default: false
attribute :commit_events, default: false
attribute :confidential_issues_events, default: false
attribute :confidential_note_events, default: false
attribute :deployment_events, default: false
attribute :issues_events, default: false
attribute :job_events, default: false
attribute :merge_requests_events, default: false
attribute :note_events, default: false
attribute :pipeline_events, default: false
attribute :push_events, default: false
attribute :tag_push_events, default: false
attribute :vulnerability_events, default: false
attribute :wiki_page_events, default: false
has_one :slack_integration, foreign_key: :integration_id, inverse_of: :integration
delegate :bot_access_token, :bot_user_id, to: :slack_integration, allow_nil: true
def update_active_status
update(active: !!slack_integration)
end
def title
s_('Integrations|GitLab for Slack app')
end
def description
s_('Integrations|Enable slash commands and notifications for a Slack workspace.')
end
def self.to_param
'gitlab_slack_application'
end
override :show_active_box?
def show_active_box?
false
end
override :test
def test(_data)
failures = test_notification_channels
{ success: failures.blank?, result: failures }
end
# The form fields of this integration are editable only after the Slack App installation
# flow has been completed, which causes the integration to become activated/enabled.
override :editable?
def editable?
activated?
end
override :fields
def fields
return [] unless editable?
super
end
override :sections
def sections
return [] unless editable?
[
{
type: SECTION_TYPE_TRIGGER,
title: s_('Integrations|Trigger'),
description: s_('Integrations|An event will be triggered when one of the following items happen.')
},
{
type: SECTION_TYPE_CONFIGURATION,
title: s_('Integrations|Notification settings'),
description: s_('Integrations|Configure the scope of notifications.')
}
]
end
override :configurable_events
def configurable_events
return [] unless editable?
super
end
override :requires_webhook?
def requires_webhook?
false
end
def upgrade_needed?
slack_integration.present? && slack_integration.upgrade_needed?
end
private
override :notify
def notify(message, opts)
channels = Array(opts[:channel])
return false if channels.empty?
payload = {
attachments: message.attachments,
text: message.pretext,
unfurl_links: false,
unfurl_media: false
}
successes = channels.map do |channel|
notify_slack_channel!(channel, payload)
end
successes.any?
end
def notify_slack_channel!(channel, payload)
response = api_client.post(
'chat.postMessage',
payload.merge(channel: channel)
)
log_error('Slack API error when notifying', api_response: response.parsed_response) unless response['ok']
response['ok']
rescue *Gitlab::HTTP::HTTP_ERRORS => e
Gitlab::ErrorTracking.track_and_raise_for_dev_exception(e,
{
integration_id: id,
slack_integration_id: slack_integration.id
}
)
false
end
def api_client
@slack_api ||= ::Slack::API.new(slack_integration)
end
def test_notification_channels
return if unique_channels.empty?
return s_('Integrations|GitLab for Slack app must be reinstalled to enable notifications') unless bot_access_token
test_payload = {
text: 'Test',
user: bot_user_id
}
not_found_channels = unique_channels.first(10).select do |channel|
test_payload[:channel] = channel
response = ::Slack::API.new(slack_integration).post('chat.postEphemeral', test_payload)
response['error'] == 'channel_not_found'
end
return if not_found_channels.empty?
format(
s_(
'Integrations|Unable to post to %{channel_list}, ' \
'please add the GitLab Slack app to any private Slack channels'
),
channel_list: not_found_channels.to_sentence
)
end
override :metrics_key_prefix
def metrics_key_prefix
'i_integrations_gitlab_for_slack_app'
end
end
end