Commit efe2d96a authored by Tiago Botelho's avatar Tiago Botelho

adds initial microsoft teams integration

parent d4349ba6
...@@ -116,6 +116,7 @@ class Project < ActiveRecord::Base ...@@ -116,6 +116,7 @@ class Project < ActiveRecord::Base
has_one :mock_ci_service, dependent: :destroy has_one :mock_ci_service, dependent: :destroy
has_one :mock_deployment_service, dependent: :destroy has_one :mock_deployment_service, dependent: :destroy
has_one :mock_monitoring_service, dependent: :destroy has_one :mock_monitoring_service, dependent: :destroy
has_one :microsoft_teams_service, dependent: :destroy
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id" has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
has_one :forked_from_project, through: :forked_project_link has_one :forked_from_project, through: :forked_project_link
......
...@@ -10,6 +10,7 @@ module ChatMessage ...@@ -10,6 +10,7 @@ module ChatMessage
def initialize(params) def initialize(params)
params = HashWithIndifferentAccess.new(params) params = HashWithIndifferentAccess.new(params)
@user_name = params[:user][:username] @user_name = params[:user][:username]
@user_avatar = params[:user][:avatar]
@project_name = params[:project_name] @project_name = params[:project_name]
@project_url = params[:project_url] @project_url = params[:project_url]
...@@ -18,7 +19,6 @@ module ChatMessage ...@@ -18,7 +19,6 @@ module ChatMessage
@note = obj_attr[:note] @note = obj_attr[:note]
@note_url = obj_attr[:url] @note_url = obj_attr[:url]
noteable_type = obj_attr[:noteable_type] noteable_type = obj_attr[:noteable_type]
case noteable_type case noteable_type
when "Commit" when "Commit"
create_commit_note(HashWithIndifferentAccess.new(params[:commit])) create_commit_note(HashWithIndifferentAccess.new(params[:commit]))
......
...@@ -8,6 +8,7 @@ module ChatMessage ...@@ -8,6 +8,7 @@ module ChatMessage
attr_reader :ref attr_reader :ref
attr_reader :ref_type attr_reader :ref_type
attr_reader :user_name attr_reader :user_name
attr_reader :user_avatar
def initialize(params) def initialize(params)
@after = params[:after] @after = params[:after]
...@@ -18,16 +19,27 @@ module ChatMessage ...@@ -18,16 +19,27 @@ module ChatMessage
@ref_type = Gitlab::Git.tag_ref?(params[:ref]) ? 'tag' : 'branch' @ref_type = Gitlab::Git.tag_ref?(params[:ref]) ? 'tag' : 'branch'
@ref = Gitlab::Git.ref_name(params[:ref]) @ref = Gitlab::Git.ref_name(params[:ref])
@user_name = params[:user_name] @user_name = params[:user_name]
@user_avatar = params[:user_avatar]
@format = params[:format]
end
def activity
{
title: activity_title,
subtitle: "to: #{project_link}",
text: compare_link,
image: params[:user_avatar]
}
end end
def pretext def pretext
format(message) @format ? format(message) : message
end end
def attachments def attachments
return [] if new_branch? || removed_branch? return [] if new_branch? || removed_branch?
commit_message_attachments @format ? commit_message_attachments : commit_messages
end end
private private
...@@ -59,7 +71,7 @@ module ChatMessage ...@@ -59,7 +71,7 @@ module ChatMessage
end end
def commit_messages def commit_messages
commits.map { |commit| compose_commit_message(commit) }.join("\n") commits.map { |commit| compose_commit_message(commit) }.join("\n\n")
end end
def commit_message_attachments def commit_message_attachments
...@@ -103,6 +115,19 @@ module ChatMessage ...@@ -103,6 +115,19 @@ module ChatMessage
"[Compare changes](#{compare_url})" "[Compare changes](#{compare_url})"
end end
def activity_title
action =
if new_branch?
"created"
elsif removed_branch?
"removed"
else
"pushed to"
end
"#{user_name} #{action} #{ref_type}"
end
def attachment_color def attachment_color
'#345' '#345'
end end
......
...@@ -51,7 +51,8 @@ class ChatNotificationService < Service ...@@ -51,7 +51,8 @@ class ChatNotificationService < Service
data = data.merge( data = data.merge(
project_url: project_url, project_url: project_url,
project_name: project_name project_name: project_name,
format: true
) )
# WebHook events often have an 'update' event that follows a 'open' or # WebHook events often have an 'update' event that follows a 'open' or
......
class MicrosoftTeamsService < ChatNotificationService
def title
'Microsoft Teams Notification'
end
def description
'Receive event notifications in Microsoft Team'
end
def self.to_param
'microsoft_teams'
end
#TODO: Setup the description accordingly
def help
'This service sends notifications about projects events to Microsoft Teams channels.<br />
To set up this service:
<ol>
<li><a href="https://msdn.microsoft.com/en-us/microsoft-teams/connectors">Getting started with 365 Office Connectors For Microsoft Teams</a>.</li>
<li>Paste the <strong>Webhook URL</strong> into the field below.</li>
<li>Select events below to enable notifications.</li>
</ol>'
end
def default_channel_placeholder
"Channel name (e.g. general)"
end
def webhook_placeholder
'https://outlook.office.com/webhook/…'
end
def event_field(event)
end
def default_fields
[
{ type: 'text', name: 'webhook', placeholder: "e.g. #{webhook_placeholder}" },
{ type: 'checkbox', name: 'notify_only_broken_pipelines' },
{ type: 'checkbox', name: 'notify_only_default_branch' },
]
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,
format: false
)
message = get_message(object_kind, data)
return false unless message
MicrosoftTeams::Notifier.new(webhook).ping({
title: message.project_name,
activity: message.activity,
attachments: message.attachments,
})
end
end
...@@ -237,6 +237,7 @@ class Service < ActiveRecord::Base ...@@ -237,6 +237,7 @@ class Service < ActiveRecord::Base
slack_slash_commands slack_slash_commands
slack slack
teamcity teamcity
microsoft_teams
] ]
if Rails.env.development? if Rails.env.development?
service_names += %w[mock_ci mock_deployment mock_monitoring] service_names += %w[mock_ci mock_deployment mock_monitoring]
......
module MicrosoftTeams
class Notifier
def initialize(webhook)
@webhook = webhook
end
def ping(options = {})
HTTParty.post(
@webhook.to_str,
headers: { 'Content-type' => 'application/json' },
body: body(options)
)
end
private
def body(options = {})
result = { 'sections' => [] }
result['title'] = options[:title] if options[:title]
result['summary'] = options[:activity][:title]
result['sections'] << {
'activityTitle' => options[:activity][:title],
'activitySubtitle' => options[:activity][:subtitle],
'activityText' => options[:activity][:text],
'activityImage' => options[:activity][:image]
}
result['sections'] << { 'title' => 'Details', 'facts' => attachments(options[:attachments]) } if options[:attachments]
result.to_json
end
def attachments(content)
[{ 'name' => 'Attachments', 'value' => content }]
end
end
end
...@@ -143,6 +143,7 @@ project: ...@@ -143,6 +143,7 @@ project:
- asana_service - asana_service
- gemnasium_service - gemnasium_service
- slack_service - slack_service
- microsoft_teams_service
- mattermost_service - mattermost_service
- buildkite_service - buildkite_service
- bamboo_service - bamboo_service
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment