@@ 34,6 34,7 @@ def log(msg) {
/* Return the URL webhook this issue wants to update, or null if unset. */
def String getWebhookUrl(Issue issue, Long chatWebhookCFId) {
+ return "https://chat.googleapis.com/v1/spaces/AAAAzndUbkU/messages?key=AIzaSyDdI0hCZtE6vySjMm-WEfRq3CPzqKqqsHI&token=tXwRXybHGSWBoY5WqzPjlcWDTDdegfAZUAISlH_tVyM%3D";
def chatWebhookCF = ComponentAccessor.customFieldManager.getCustomFieldObject(chatWebhookCFId);
if (chatWebhookCF) {
def chatWebhookCFVal = issue.getCustomFieldValue(chatWebhookCF);
@@ 58,6 59,7 @@ def debugMessages(IssueEvent event) {
log "--------------------------------------";
log "event: ${event?.getClass()}";
log "event.issue: ${event.issue.getClass()}";
+ log "event.comment: ${event.comment?.body}";
log "event.changeLog: is ${event?.changeLog?.getClass()}";
log "event.comment: is ${event.comment?.getClass()}";
log "Event methods:";
@@ 76,14 78,13 @@ def String getBaseUrl() {
return ComponentAccessor.getApplicationProperties().getString("jira.baseurl");
}
-def messageWebhook(String webhookUrl, IssueEvent event) {
- //debugMessages(event);
+def messageWebhook(String webhookUrl, ChatMessage message) {
+ log "JSON: ${message.toJSON()}";
def threadKey = baseUrl.replaceAll("https://", '') + "-" + event.issue.key;
URIBuilder uriBuilder = new URIBuilder(webhookUrl).addQueryParam("threadKey", threadKey);
log.debug "Built URL ${uriBuilder}";
- Card card = new Card(event);
// https://developers.google.com/hangouts/chat/reference/rest/v1/spaces.messages/create
def http = new HTTPBuilder("${uriBuilder}");
@@ 98,7 99,7 @@ def messageWebhook(String webhookUrl, Is
//body = new JsonBuilder( ['text': messageText] ).toString()
// https://developers.google.com/hangouts/chat/reference/message-formats/cards
- body = card.toJSON();
+ body = message.toJSON();
response.success = { resp, JSON ->
log.warn("Success response: ${JSON}");
@@ 111,17 112,102 @@ def messageWebhook(String webhookUrl, Is
}
}
-/** Create a Google Card JSON representation of an event.
- * https://developers.google.com/hangouts/chat/reference/message-formats/cards
+/** Classes implementing a toJSON() method, generating Hangout Chat message format (https://developers.google.com/hangouts/chat/reference/message-formats/).
+ */
+interface ChatMessage {
+ String toJSON();
+}
+
+/**
+ * Create a GChat 'Simple Text' formatted message, converting from Jira wiki to GChat wiki where possible.
*/
-class Card {
- Issue issue
- IssueEvent event
+class SimpleChatMessage implements ChatMessage {
+ Issue issue;
+ IssueEvent event;
+
+ SimpleChatMessage(event) {
+ this.event = event;
+ this.issue = event.issue;
+ }
+
+ def log(msg) {
+ System.out.println(msg);
+ }
+
+ def getBaseUrl() {
+ // https://community.atlassian.com/t5/Answers-Developer-Questions/How-do-I-programatically-find-JIRA-s-base-URL/qaq-p/519640
+ return ComponentAccessor.getApplicationProperties().getString("jira.baseurl");
+ }
+
+ def getEventType() {
+ def Long eventTypeID = event.getEventTypeId();
+ return ComponentAccessor.eventTypeManager.getEventType(event.getEventTypeId()).getName();
+ }
+
+
+ String keyValue(key, value)
+ {
+ if (value != null) {
+ """`${key}` ${value}"""
+ } else { null }
+ }
+
+ String textPara(key, value)
+ {
+ if (value != null) {
+ """${value}"""
+ } else { null }
+ }
- Card(event) {
- this.event = event;
- this.issue = event.issue;
+ String changeLog() {
+ if (event?.changeLog) {
+ // "changeitems: ${event.changeLog.getRelated('ChildChangeItem').getClass()}";
+ return event.changeLog.getRelated("ChildChangeItem").collect {
+ def ci = it as GenericValue;
+ def field = ci.getString("field");
+ //if (field == "status") return "";
+ def oldval = ci.getString("oldstring");
+ def newval = ci.getString("newstring");
+ keyValue(field, newval + (oldval ? " (was: ${oldval})" : ""));
+ }
+ .join("\n")
+ }
+ }
+ String comment() {
+ if (event.comment) {
+ def formattedComment = event.comment?.body?.replaceAll(~"\\{noformat\\}\\r?", '```')?.replaceAll(~"\\{color[#:0-9a-f]*\\}", "")?.replaceAll(~"^h[1-6]\\. (.*)", '*$1*')?.replaceAll(~'[\n\r]{4}', "\n")?.replaceAll(~'\\[([^|]+)\\|(http[^]]+)\\]', '<$2|$1>')?.replaceAll(~'\\{\\{(.*?)\\}\\}', '`$1`');
+ //log "Pre-formatting: ${event.comment?.body}";
+ //log "Post-formatting: ${formattedComment}";
+ return formattedComment;
}
+ }
+
+ String header() {
+ event.user?.displayName + " " + eventType.replaceAll('Issue Commented', 'commented on').replaceAll("Generic Event", "updated").replaceAll(~/Issue ?/, "").toLowerCase() + " " + (issue.assignee ? "${issue.assignee.displayName}'s" : "unassigned") + " " + issue.issueType?.name + " " + "<${baseUrl}/browse/${issue.key}|${issue.key} - ${issue.summary}> " + (issue.resolution ? "(${issue.status.name} / ${issue.resolution?.name})" : "") + ":\n"
+ }
+
+ String toJSON()
+ {
+ def textField = header() + [
+ changeLog()
+ , comment()
+ ].findResults { it // keyValue() returns null for unset fields.
+ }.join("\n");
+ return '{ "text": "' + textField + '" }';
+ }
+}
+
+/** Create a Google CardChatMessage JSON representation of an event.
+ * Note that cards clip the horizontal space, so in practice the SimpleChatMessage representation works better.
+ */
+class CardChatMessage implements ChatMessage {
+ Issue issue;
+ IssueEvent event;
+
+ CardChatMessage(event) {
+ this.event = event;
+ this.issue = event.issue;
+ }
def log(msg) {
System.out.println(msg);
@@ 230,5 316,7 @@ class Card {
def webhookUrl = getWebhookUrl(event.issue, WEBHOOK_CHAT_CUSTOMFIELD_ID);
if (webhookUrl) {
- messageWebhook(webhookUrl, event);
+ //CardChatMessage card = new CardChatMessage(event);
+ ChatMessage msg = new SimpleChatMessage(event);
+ messageWebhook(webhookUrl, msg);
}