summaryrefslogtreecommitdiff
path: root/app/models/project_services/slack_service.rb
diff options
context:
space:
mode:
authorFelipe Artur <felipefac@gmail.com>2016-11-25 17:36:37 -0200
committerFelipe Artur <felipefac@gmail.com>2016-12-15 11:09:31 -0200
commit141faaacf9119ce5d765efe73c6509030ba078cd (patch)
tree1f5cf350087ad524273e0ba80c7ddcc3ce640ad8 /app/models/project_services/slack_service.rb
parent2d1dfae9b63d35232e4bf537a0aca9b95e2d5e72 (diff)
downloadgitlab-ce-141faaacf9119ce5d765efe73c6509030ba078cd.tar.gz
Mattermost Notifications Service
Diffstat (limited to 'app/models/project_services/slack_service.rb')
-rw-r--r--app/models/project_services/slack_service.rb174
1 files changed, 19 insertions, 155 deletions
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
index e1b937817f4..0df1743c4ba 100644
--- a/app/models/project_services/slack_service.rb
+++ b/app/models/project_services/slack_service.rb
@@ -1,25 +1,10 @@
-class SlackService < Service
- prop_accessor :webhook, :username, :channel
- boolean_accessor :notify_only_broken_builds, :notify_only_broken_pipelines
- validates :webhook, presence: true, url: true, if: :activated?
-
- def initialize_properties
- # Custom serialized properties initialization
- self.supported_events.each { |event| self.class.prop_accessor(event_channel_name(event)) }
-
- if properties.nil?
- self.properties = {}
- self.notify_only_broken_builds = true
- self.notify_only_broken_pipelines = true
- end
- end
-
+class SlackService < ChatService
def title
- 'Slack'
+ 'Slack notifications'
end
def description
- 'A team communication tool for the 21st century'
+ 'Receive event notifications in Slack'
end
def to_param
@@ -27,150 +12,29 @@ class SlackService < Service
end
def help
- 'This service sends notifications to your Slack channel.<br/>
- To setup this Service you need to create a new <b>"Incoming webhook"</b> in your Slack integration panel,
- and enter the Webhook URL below.'
+ 'This service sends notifications about projects events to Slack channels.<br />
+ To setup this service:
+ <ol>
+ <li><a href="https://slack.com/apps/A0F7XDUAZ-incoming-webhooks">Add an incoming webhook</a> in your Slack team. The default channel can be overridden for each event. </li>
+ <li>Paste the <strong>Webhook URL</strong> into the field below. </li>
+ <li>Select events below to enable notifications. The channel and username are optional. </li>
+ </ol>'
end
def fields
- default_fields =
- [
- { type: 'text', name: 'webhook', placeholder: 'https://hooks.slack.com/services/...' },
- { type: 'text', name: 'username', placeholder: 'username' },
- { type: 'text', name: 'channel', placeholder: "#general" },
- { type: 'checkbox', name: 'notify_only_broken_builds' },
- { type: 'checkbox', name: 'notify_only_broken_pipelines' },
- ]
-
default_fields + build_event_channels
end
- def supported_events
- %w[push issue confidential_issue merge_request note tag_push
- build pipeline wiki_page]
- end
-
- def execute(data)
- return unless supported_events.include?(data[:object_kind])
- return unless webhook.present?
-
- object_kind = data[:object_kind]
-
- data = data.merge(
- project_url: project_url,
- project_name: project_name
- )
-
- # WebHook events often have an 'update' event that follows a 'open' or
- # 'close' action. Ignore update events for now to prevent duplicate
- # messages from arriving.
-
- message = get_message(object_kind, data)
-
- if message
- opt = {}
-
- event_channel = get_channel_field(object_kind) || channel
-
- opt[:channel] = event_channel if event_channel
- opt[:username] = username if username
-
- notifier = Slack::Notifier.new(webhook, opt)
- notifier.ping(message.pretext, attachments: message.attachments, fallback: message.fallback)
-
- true
- else
- false
- end
- end
-
- def event_channel_names
- supported_events.map { |event| event_channel_name(event) }
- end
-
- def event_field(event)
- fields.find { |field| field[:name] == event_channel_name(event) }
+ def default_fields
+ [
+ { type: 'text', name: 'webhook', placeholder: 'https://hooks.slack.com/services/...' },
+ { type: 'text', name: 'username', placeholder: 'username' },
+ { type: 'checkbox', name: 'notify_only_broken_builds' },
+ { type: 'checkbox', name: 'notify_only_broken_pipelines' },
+ ]
end
- def global_fields
- fields.reject { |field| field[:name].end_with?('channel') }
- end
-
- private
-
- def get_message(object_kind, data)
- case object_kind
- when "push", "tag_push"
- PushMessage.new(data)
- when "issue"
- IssueMessage.new(data) unless is_update?(data)
- when "merge_request"
- MergeMessage.new(data) unless is_update?(data)
- when "note"
- NoteMessage.new(data)
- when "build"
- BuildMessage.new(data) if should_build_be_notified?(data)
- when "pipeline"
- PipelineMessage.new(data) if should_pipeline_be_notified?(data)
- when "wiki_page"
- WikiPageMessage.new(data)
- end
- end
-
- def get_channel_field(event)
- field_name = event_channel_name(event)
- self.public_send(field_name)
- end
-
- def build_event_channels
- supported_events.reduce([]) do |channels, event|
- channels << { type: 'text', name: event_channel_name(event), placeholder: "#general" }
- end
- end
-
- def event_channel_name(event)
- "#{event}_channel"
- end
-
- def project_name
- project.name_with_namespace.gsub(/\s/, '')
- end
-
- def project_url
- project.web_url
- end
-
- def is_update?(data)
- data[:object_attributes][:action] == 'update'
- end
-
- def should_build_be_notified?(data)
- case data[:commit][:status]
- when 'success'
- !notify_only_broken_builds?
- when 'failed'
- true
- else
- false
- end
- end
-
- def should_pipeline_be_notified?(data)
- case data[:object_attributes][:status]
- when 'success'
- !notify_only_broken_pipelines?
- when 'failed'
- true
- else
- false
- end
+ def default_channel
+ "#general"
end
end
-
-require "slack_service/issue_message"
-require "slack_service/push_message"
-require "slack_service/merge_message"
-require "slack_service/note_message"
-require "slack_service/build_message"
-require "slack_service/pipeline_message"
-require "slack_service/wiki_page_message"