-
Notifications
You must be signed in to change notification settings - Fork 6
/
Script.js
298 lines (251 loc) · 11.5 KB
/
Script.js
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
/* exported Script */
/* globals console, _, s */
/** Global Helpers
*
* console - A normal console instance
* _ - An underscore instance
* s - An underscore string instance
*/
class Script {
/*
* Helper function for logging.
* View logs from Administration -> View Logs
*
* @params {object} message to log to console
*/
do_log = function (message) {
// Uncomment the following line to disable logging.
console.log(message);
}
/**
* @params {object} request
*/
process_incoming_request({request}) {
// request.url.hash
// request.url.search
// request.url.query
// request.url.pathname
// request.url.path
// request.url_raw
// request.url_params
// request.headers
// request.user._id
// request.user.name
// request.user.username
// request.content_raw
// request.content
this.do_log("\n\n------- START REQUEST -------\n");
this.do_log(request.content);
this.do_log("\n--------END REQUEST ------\n\n");
const data = request.content.data;
/*
* Extract author from Taiga event.
*/
var author_name = request.content.by.full_name;
var author_link = request.content.by.permalink;
var author_icon = request.content.by.photo;
var author_anchor = `[${author_name}](${author_link})`
// The author's name and photo is displayed as the 'sender' in Rocket.Chat
var sender_name = author_name;
var sender_icon = author_icon;
// If the event belongs to specific project, display the project's icon & name as sender instead
if (request.content.data.project) {
sender_name = request.content.data.project.name;
sender_icon = request.content.data.project.logo_big_url;
}
/*
* Initialize the message.
*/
var message_emoji = "";
var message_text = "";
var attachment_title = "";
var attachment_link = "";
var attachment_anchor = "";
var attachment_text = ""; // unused for now
var attachment_image = ""; // unused for now
var attachment_thumb = ""; // unused for now
/*
* The metadata is a supplementary information which indicates what exactly was added/changed/deleted.
* If something has changed, the "change" key will be present in the request content:
* {..., "change" : {diff: {some_item: {from: "foo", to: "bar" } }} , ...}
* Sometimes, the type of "diff" is string.
*/
var itemMeta = "";
// Tag the @person if the person assigned to the task/issue/item is available on Rocket.Chat.
// If the users don't share the same username, remove this if-block.
if (data.assigned_to) {
itemMeta = `@${data.assigned_to.username}`;
}
const diff = request.content.change ? request.content.change.diff : null;
if (diff) {
/*
* We parse the keys, do some trimming, formatting, and generate a readable message.
* Note: When the keys "from" or "to" are unavailable, we format the message accordingly.
*
* We skip some of these events to keep the messages simple.,
*/
const ignore_diffs = ['kanban_order', 'description_diff'];
for (var diffKey in diff) {
if (diff.hasOwnProperty(diffKey)) {
this.do_log("KEY: " + diffKey);
if (ignore_diffs.indexOf(diffKey) >= 0) {
continue;
}
var diffValue = diff[diffKey];
var diffKeyFormatted = diffKey.replace('_', ' ');
this.do_log("Value: " + diffValue);
var diffMessageChunk = `\n>`;
var diffFrom = '';
var diffTo = ''
// "diff": {"foobar": {from: "foo", to: "bar"}}
if (typeof diffValue == "object") {
if (diffValue.hasOwnProperty('from')) {
diffFrom = diffValue.from;
if (diffFrom.length > 40) {
diffFrom = diffFrom.substr(0, 35) + "...";
}
}
if (diffValue.hasOwnProperty('to')) {
diffTo = diffValue.to;
if (diffTo.length > 40) {
diffTo = diffTo.substr(0, 35) + "...";
}
}
}
// "diff": {"foobar": "current value"}
else if (typeof diffValue == "string") {
diffTo = diffValue;
if (diffTo.length > 40) {
diffTo = diffTo.substr(0, 35) + "...";
}
}
this.do_log("from: " + diffFrom);
this.do_log("to: " + diffTo);
//
if (diffFrom.length + diffTo.length === 0) {
diffMessageChunk += `[Changed ${diffKey}]`;
} else if (diffFrom.length === 0) {
diffMessageChunk += `[Added ${diffKeyFormatted}] ← ${diffTo}`;
} else if (diffTo.length === 0) {
diffMessageChunk += `[Removed ${diffKey}] → ~${diffFrom}~`;
} else {
diffMessageChunk += `[Changed ${diffKey}] ~${diffFrom}~ → ${diffTo}`;
}
itemMeta += diffMessageChunk;
}
}
}
/*
* In all types (milestone|task|issue|wikipage) there are three events- 'create', 'change' and 'delete'.
* There is a lot of code repetition here, so comments are limited to the first occurrence of a code.
* For each type, create the message and add a link to that item.
*/
switch (request.content.type) {
case 'test':
attachment_title = data.test;
attachment_link = 'https://example.com/';
attachment_anchor = `[${attachment_title}](${attachment_link})`
if (request.content.action === 'test') {
message_emoji = ':bell:';
message_text = `${author_anchor} sent a test message.`;
}
break;
case 'milestone':
attachment_title = data.name;
attachment_link = data.permalink;
attachment_anchor = `[${attachment_title}](${attachment_link})`
// Created
if (request.content.action === 'create') {
message_emoji = ':new:';
message_text = `${author_anchor} added a new milestone ${attachment_anchor}. ${itemMeta}`;
message_text += `\nStart: ${data.estimated_start}, `
message_text += `\nFinish: ${data.estimated_finish}`;
}
// updated
else if (request.content.change) {
message_emoji = ':triangular_flag_on_post:';
message_text = `${author_anchor} updated the milestone ${attachment_anchor} ${itemMeta}`;
}
// Deleted
else {
message_emoji = ':x:';
message_text = `${author_anchor} deleted a milestone ~${data.name}~. ${itemMeta}`;
}
break;
case 'epic':
case 'userstory':
case 'relateduserstory':
case 'task':
case 'issue':
case 'wikipage':
var contentType = request.content.type
.replace('related', 'related ') //added trailing space
.replace('userstory', 'user story')
.replace('wikipage', 'wiki page');
attachment_title = data.subject || data.slug || data.user_story.subject || data.epic.subject;
attachment_link = data.permalink;
attachment_anchor = attachment_title ? `[${attachment_title}](${attachment_link})` : '';
// If there is a mention of another "user_story" or "epic",
// We add the snippet " ...in User Story XYZ" or "in Epic XYZ" in the message
var user_story_or_epic_mention = ".";
if (data.user_story) {
user_story_or_epic_mention = ` (User Story: [${data.user_story.subject}](${data.user_story.permalink}) ) `;
}
if (data.epic) {
user_story_or_epic_mention += ` (Epic: [${data.epic.subject}](${data.epic.permalink}) ) `
}
// Created
if (request.content.action === 'create') {
message_emoji = ':new:';
message_text = `${author_anchor} added a new ${contentType} ${attachment_anchor} ${user_story_or_epic_mention}. ${itemMeta}`;
}
// updated
else if (request.content.change) {
// When a comment is added / edited / deleted, "comment" object has non-empty value.
if (request.content.change.comment) {
// When a comment is deleted, the delete_comment_date is set
if (request.content.change.delete_comment_date) {
message_emoji = ':x:';
message_text = `${author_anchor} deleted their comment on ${contentType}: ${attachment_anchor} ${user_story_or_epic_mention}. ${itemMeta}`;
} else {
message_emoji = ':speech_balloon:';
message_text = `${author_anchor} commented on ${contentType}: ${attachment_anchor} ${user_story_or_epic_mention}. ${itemMeta}`;
}
message_text += `\n> ${request.content.change.comment.split('\n', 1)[0]}`;
}
// Comment is empty, that means something else was changed.
else {
message_emoji = ':triangular_flag_on_post:';
message_text += `${author_anchor} updated the ${contentType}: ${attachment_anchor} ${user_story_or_epic_mention}. ${itemMeta}`;
}
}
// Deleted
else {
message_emoji = ':x:';
message_text = `${author_anchor} deleted the ${contentType}: ~${attachment_title}~ ${user_story_or_epic_mention}. ${itemMeta}`;
}
break;
default:
break;
}
var returnData = {
content: {
// text: `${message_emoji} ${message_text}`,
text: `${message_text}`,
alias: sender_name,
icon_url: sender_icon,
// "attachments": [{
// "color": "#00bb99",
// "title": attachment_title,
// "title_link": attachment_link,
// "text": message_text + "\n" + attachment_text,
// }]
}
};
// Comment in prod.
this.do_log("\n\n------- START MESSAGE -------\n");
this.do_log(returnData);
this.do_log("\n--------END MESSAGE ------\n\n");
return returnData;
}
}