1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
# frozen_string_literal: true
module Integrations
class Campfire < Integration
include ActionView::Helpers::UrlHelper
prop_accessor :token, :subdomain, :room
validates :token, presence: true, if: :activated?
def title
'Campfire'
end
def description
'Send notifications about push events to Campfire chat rooms.'
end
def help
docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('api/services', anchor: 'campfire'), target: '_blank', rel: 'noopener noreferrer'
s_('CampfireService|Send notifications about push events to Campfire chat rooms. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
def self.to_param
'campfire'
end
def fields
[
{
type: 'text',
name: 'token',
title: _('Campfire token'),
placeholder: '',
help: s_('CampfireService|API authentication token from Campfire.'),
required: true
},
{
type: 'text',
name: 'subdomain',
title: _('Campfire subdomain (optional)'),
placeholder: '',
help: s_('CampfireService|The %{code_open}.campfirenow.com%{code_close} subdomain.') % { code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
},
{
type: 'text',
name: 'room',
title: _('Campfire room ID (optional)'),
placeholder: '123456',
help: s_('CampfireService|From the end of the room URL.')
}
]
end
def self.supported_events
%w(push)
end
def execute(data)
return unless supported_events.include?(data[:object_kind])
message = build_message(data)
speak(self.room, message, auth)
end
private
def base_uri
@base_uri ||= "https://#{subdomain}.campfirenow.com"
end
def auth
# use a dummy password, as explained in the Campfire API doc:
# https://github.com/basecamp/campfire-api#authentication
@auth ||= {
basic_auth: {
username: token,
password: 'X'
}
}
end
# Post a message into a room, returns the message Hash in case of success.
# Returns nil otherwise.
# https://github.com/basecamp/campfire-api/blob/master/sections/messages.md#create-message
def speak(room_name, message, auth)
room = rooms(auth).find { |r| r["name"] == room_name }
return unless room
path = "/room/#{room["id"]}/speak.json"
body = {
body: {
message: {
type: 'TextMessage',
body: message
}
}
}
res = Gitlab::HTTP.post(path, base_uri: base_uri, **auth.merge(body))
res.code == 201 ? res : nil
end
# Returns a list of rooms, or [].
# https://github.com/basecamp/campfire-api/blob/master/sections/rooms.md#get-rooms
def rooms(auth)
res = Gitlab::HTTP.get("/rooms.json", base_uri: base_uri, **auth)
res.code == 200 ? res["rooms"] : []
end
def build_message(push)
ref = Gitlab::Git.ref_name(push[:ref])
before = push[:before]
after = push[:after]
message = []
message << "[#{project.full_name}] "
message << "#{push[:user_name]} "
if Gitlab::Git.blank_ref?(before)
message << "pushed new branch #{ref} \n"
elsif Gitlab::Git.blank_ref?(after)
message << "removed branch #{ref} \n"
else
message << "pushed #{push[:total_commits_count]} commits to #{ref}. "
message << "#{project.web_url}/compare/#{before}...#{after}"
end
message.join
end
end
end
|