Watcher: Add support for actions in slack attachments (elastic/x-pack-elasticsearch#3355)
In order to support buttons that can be clicked on within a slack message, this commits adds support for so called actions within attachments. This allows to create buttons, that are clicked and execute a GET request, so actions must be idempotent according to the official slack documentation. Official slack documentation is available at https://api.slack.com/docs/message-attachments#action_fields Original commit: elastic/x-pack-elasticsearch@29ddc90b01
This commit is contained in:
parent
3fc17ab918
commit
992a7af126
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
package org.elasticsearch.xpack.watcher.notification.slack.message;
|
||||
|
||||
import org.elasticsearch.common.ParseField;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
|
||||
import org.elasticsearch.common.xcontent.ToXContent;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplate;
|
||||
import org.elasticsearch.xpack.watcher.common.text.TextTemplateEngine;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class Action implements MessageElement {
|
||||
|
||||
static final ObjectParser<Template, Void> ACTION_PARSER = new ObjectParser<>("action", Template::new);
|
||||
static {
|
||||
ACTION_PARSER.declareField(Template::setType, (p, c) -> new TextTemplate(p.text()), new ParseField("type"), ValueType.STRING);
|
||||
ACTION_PARSER.declareField(Template::setUrl, (p, c) -> new TextTemplate(p.text()), new ParseField("url"), ValueType.STRING);
|
||||
ACTION_PARSER.declareField(Template::setText, (p, c) -> new TextTemplate(p.text()), new ParseField("text"), ValueType.STRING);
|
||||
ACTION_PARSER.declareField(Template::setStyle, (p, c) -> new TextTemplate(p.text()), new ParseField("style"), ValueType.STRING);
|
||||
ACTION_PARSER.declareField(Template::setName, (p, c) -> new TextTemplate(p.text()), new ParseField("name"), ValueType.STRING);
|
||||
}
|
||||
|
||||
private static final ParseField URL = new ParseField("url");
|
||||
private static final ParseField TYPE = new ParseField("type");
|
||||
private static final ParseField TEXT = new ParseField("text");
|
||||
private static final ParseField STYLE = new ParseField("style");
|
||||
private static final ParseField NAME = new ParseField("name");
|
||||
|
||||
private String style;
|
||||
private String name;
|
||||
private String type;
|
||||
private String text;
|
||||
private String url;
|
||||
|
||||
public Action() {
|
||||
}
|
||||
|
||||
public Action(String style, String name, String type, String text, String url) {
|
||||
this.style = style;
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
this.text = text;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Action template = (Action) o;
|
||||
|
||||
return Objects.equals(style, template.style) && Objects.equals(type, template.type) && Objects.equals(url, template.url)
|
||||
&& Objects.equals(text, template.text) && Objects.equals(name, template.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(style, type, url, name, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
return builder.startObject()
|
||||
.field(NAME.getPreferredName(), name)
|
||||
.field(STYLE.getPreferredName(), style)
|
||||
.field(TYPE.getPreferredName(), type)
|
||||
.field(TEXT.getPreferredName(), text)
|
||||
.field(URL.getPreferredName(), url)
|
||||
.endObject();
|
||||
}
|
||||
|
||||
static class Template implements ToXContent {
|
||||
|
||||
private TextTemplate type;
|
||||
private TextTemplate name;
|
||||
private TextTemplate text;
|
||||
private TextTemplate url;
|
||||
private TextTemplate style;
|
||||
|
||||
public Action render(TextTemplateEngine engine, Map<String, Object> model) {
|
||||
String style = engine.render(this.style, model);
|
||||
String type = engine.render(this.type, model);
|
||||
String url = engine.render(this.url, model);
|
||||
String name = engine.render(this.name, model);
|
||||
String text = engine.render(this.text, model);
|
||||
return new Action(style, name, type, text, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Template template = (Template) o;
|
||||
|
||||
return Objects.equals(style, template.style) && Objects.equals(type, template.type) && Objects.equals(url, template.url)
|
||||
&& Objects.equals(text, template.text) && Objects.equals(name, template.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(style, type, url, name, text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
return builder.startObject()
|
||||
.field(NAME.getPreferredName(), name)
|
||||
.field(STYLE.getPreferredName(), style)
|
||||
.field(TYPE.getPreferredName(), type)
|
||||
.field(TEXT.getPreferredName(), text)
|
||||
.field(URL.getPreferredName(), url)
|
||||
.endObject();
|
||||
}
|
||||
|
||||
public TextTemplate getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(TextTemplate type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public TextTemplate getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(TextTemplate name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public TextTemplate getText() {
|
||||
return text;
|
||||
}
|
||||
|
||||
public void setText(TextTemplate text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public TextTemplate getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(TextTemplate url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public TextTemplate getStyle() {
|
||||
return style;
|
||||
}
|
||||
|
||||
public void setStyle(TextTemplate style) {
|
||||
this.style = style;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,10 +35,11 @@ public class Attachment implements MessageElement {
|
|||
final String imageUrl;
|
||||
final String thumbUrl;
|
||||
final String[] markdownSupportedFields;
|
||||
final List<Action> actions;
|
||||
|
||||
public Attachment(String fallback, String color, String pretext, String authorName, String authorLink,
|
||||
String authorIcon, String title, String titleLink, String text, Field[] fields,
|
||||
String imageUrl, String thumbUrl, String[] markdownSupportedFields) {
|
||||
String imageUrl, String thumbUrl, String[] markdownSupportedFields, List<Action> actions) {
|
||||
|
||||
this.fallback = fallback;
|
||||
this.color = color;
|
||||
|
@ -53,6 +54,7 @@ public class Attachment implements MessageElement {
|
|||
this.imageUrl = imageUrl;
|
||||
this.thumbUrl = thumbUrl;
|
||||
this.markdownSupportedFields = markdownSupportedFields;
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -66,14 +68,14 @@ public class Attachment implements MessageElement {
|
|||
Objects.equals(authorLink, that.authorLink) && Objects.equals(authorIcon, that.authorIcon) &&
|
||||
Objects.equals(title, that.title) && Objects.equals(titleLink, that.titleLink) &&
|
||||
Objects.equals(text, that.text) && Objects.equals(imageUrl, that.imageUrl) &&
|
||||
Objects.equals(thumbUrl, that.thumbUrl) &&
|
||||
Objects.equals(thumbUrl, that.thumbUrl) && Objects.equals(actions, that.actions) &&
|
||||
Arrays.equals(markdownSupportedFields, that.markdownSupportedFields) && Arrays.equals(fields, that.fields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(fallback, color, pretext, authorName, authorLink, authorIcon, title, titleLink, text, fields, imageUrl,
|
||||
thumbUrl, markdownSupportedFields);
|
||||
thumbUrl, markdownSupportedFields, actions);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -131,6 +133,13 @@ public class Attachment implements MessageElement {
|
|||
}
|
||||
builder.endArray();
|
||||
}
|
||||
if (actions != null && actions.isEmpty() == false) {
|
||||
builder.startArray("actions");
|
||||
for (Action action : actions) {
|
||||
action.toXContent(builder, params);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
|
||||
return builder.endObject();
|
||||
}
|
||||
|
@ -150,12 +159,12 @@ public class Attachment implements MessageElement {
|
|||
final TextTemplate imageUrl;
|
||||
final TextTemplate thumbUrl;
|
||||
final TextTemplate[] markdownSupportedFields;
|
||||
|
||||
final List<Action.Template> actions;
|
||||
|
||||
Template(TextTemplate fallback, TextTemplate color, TextTemplate pretext, TextTemplate authorName,
|
||||
TextTemplate authorLink, TextTemplate authorIcon, TextTemplate title, TextTemplate titleLink,
|
||||
TextTemplate text, Field.Template[] fields, TextTemplate imageUrl, TextTemplate thumbUrl,
|
||||
TextTemplate[] markdownSupportedFields) {
|
||||
TextTemplate[] markdownSupportedFields, List<Action.Template> actions) {
|
||||
|
||||
this.fallback = fallback;
|
||||
this.color = color;
|
||||
|
@ -170,6 +179,7 @@ public class Attachment implements MessageElement {
|
|||
this.imageUrl = imageUrl;
|
||||
this.thumbUrl = thumbUrl;
|
||||
this.markdownSupportedFields = markdownSupportedFields;
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
public Attachment render(TextTemplateEngine engine, Map<String, Object> model, SlackMessageDefaults.AttachmentDefaults defaults) {
|
||||
|
@ -198,8 +208,15 @@ public class Attachment implements MessageElement {
|
|||
markdownFields[i] = engine.render(this.markdownSupportedFields[i], model);
|
||||
}
|
||||
}
|
||||
List<Action> actions = new ArrayList<>();
|
||||
if (this.actions != null && this.actions.isEmpty() == false) {
|
||||
for (Action.Template action : this.actions) {
|
||||
actions.add(action.render(engine, model));
|
||||
}
|
||||
}
|
||||
|
||||
return new Attachment(fallback, color, pretext, authorName, authorLink, authorIcon, title, titleLink, text, fields, imageUrl,
|
||||
thumbUrl, markdownFields);
|
||||
thumbUrl, markdownFields, actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -209,20 +226,20 @@ public class Attachment implements MessageElement {
|
|||
|
||||
Template template = (Template) o;
|
||||
|
||||
return Objects.equals(fallback, template.fallback) && Objects.equals(color, template.color)
|
||||
&& Objects.equals(pretext, template.pretext) && Objects.equals(authorName, template.authorName)
|
||||
&& Objects.equals(authorLink, template.authorLink) && Objects.equals(authorIcon, template.authorIcon)
|
||||
&& Objects.equals(title, template.title) && Objects.equals(titleLink, template.titleLink)
|
||||
&& Objects.equals(text, template.text) && Objects.equals(imageUrl, template.imageUrl)
|
||||
&& Objects.equals(thumbUrl, template.thumbUrl)
|
||||
&& Arrays.equals(fields, template.fields)
|
||||
&& Arrays.equals(markdownSupportedFields, template.markdownSupportedFields);
|
||||
return Objects.equals(fallback, template.fallback) && Objects.equals(color, template.color) &&
|
||||
Objects.equals(pretext, template.pretext) && Objects.equals(authorName, template.authorName) &&
|
||||
Objects.equals(authorLink, template.authorLink) && Objects.equals(authorIcon, template.authorIcon) &&
|
||||
Objects.equals(title, template.title) && Objects.equals(titleLink, template.titleLink) &&
|
||||
Objects.equals(text, template.text) && Objects.equals(imageUrl, template.imageUrl) &&
|
||||
Objects.equals(thumbUrl, template.thumbUrl) && Objects.equals(actions, template.actions) &&
|
||||
Arrays.equals(fields, template.fields) &&
|
||||
Arrays.equals(markdownSupportedFields, template.markdownSupportedFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(fallback, color, pretext, authorName, authorLink, authorIcon, title, titleLink, text, fields, imageUrl,
|
||||
thumbUrl, markdownSupportedFields);
|
||||
thumbUrl, markdownSupportedFields, actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -275,6 +292,13 @@ public class Attachment implements MessageElement {
|
|||
}
|
||||
builder.endArray();
|
||||
}
|
||||
if (actions != null && actions.isEmpty() == false) {
|
||||
builder.startArray(XField.ACTIONS.getPreferredName());
|
||||
for (Action.Template action : actions) {
|
||||
action.toXContent(builder, params);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
|
||||
return builder.endObject();
|
||||
}
|
||||
|
@ -294,6 +318,7 @@ public class Attachment implements MessageElement {
|
|||
TextTemplate imageUrl = null;
|
||||
TextTemplate thumbUrl = null;
|
||||
TextTemplate[] markdownFields = null;
|
||||
List<Action.Template> actions = new ArrayList<>();
|
||||
|
||||
XContentParser.Token token = null;
|
||||
String currentFieldName = null;
|
||||
|
@ -411,12 +436,16 @@ public class Attachment implements MessageElement {
|
|||
markdownFields = list.toArray(new TextTemplate[list.size()]);
|
||||
} else {
|
||||
try {
|
||||
markdownFields = new TextTemplate[]{ new TextTemplate(parser.text())};
|
||||
markdownFields = new TextTemplate[]{new TextTemplate(parser.text())};
|
||||
} catch (ElasticsearchParseException pe) {
|
||||
throw new ElasticsearchParseException("could not parse message attachment. failed to parse [{}] field", pe,
|
||||
XField.MARKDOWN_IN);
|
||||
}
|
||||
}
|
||||
} else if (XField.ACTIONS.match(currentFieldName)) {
|
||||
if (token == XContentParser.Token.START_OBJECT) {
|
||||
actions.add(Action.ACTION_PARSER.parse(parser, null));
|
||||
}
|
||||
} else {
|
||||
throw new ElasticsearchParseException("could not parse message attachment field. unexpected field [{}]",
|
||||
currentFieldName);
|
||||
|
@ -439,7 +468,7 @@ public class Attachment implements MessageElement {
|
|||
}
|
||||
}
|
||||
return new Template(fallback, color, pretext, authorName, authorLink, authorIcon, title, titleLink, text, fields, imageUrl,
|
||||
thumbUrl, markdownFields);
|
||||
thumbUrl, markdownFields, actions);
|
||||
}
|
||||
|
||||
|
||||
|
@ -462,6 +491,7 @@ public class Attachment implements MessageElement {
|
|||
private TextTemplate imageUrl;
|
||||
private TextTemplate thumbUrl;
|
||||
private List<TextTemplate> markdownFields = new ArrayList<>();
|
||||
private List<Action.Template> actions = new ArrayList<>();
|
||||
|
||||
private Builder() {
|
||||
}
|
||||
|
@ -579,12 +609,17 @@ public class Attachment implements MessageElement {
|
|||
return this;
|
||||
}
|
||||
|
||||
public Builder addAction(Action.Template action) {
|
||||
this.actions.add(action);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Template build() {
|
||||
Field.Template[] fields = this.fields.isEmpty() ? null : this.fields.toArray(new Field.Template[this.fields.size()]);
|
||||
TextTemplate[] markdownFields =
|
||||
this.markdownFields.isEmpty() ? null : this.markdownFields.toArray(new TextTemplate[this.markdownFields.size()]);
|
||||
return new Template(fallback, color, pretext, authorName, authorLink, authorIcon, title, titleLink, text, fields,
|
||||
imageUrl, thumbUrl, markdownFields);
|
||||
return new Template(fallback, color, pretext, authorName, authorLink, authorIcon, title, titleLink, text, fields, imageUrl,
|
||||
thumbUrl, markdownFields, actions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -603,5 +638,6 @@ public class Attachment implements MessageElement {
|
|||
ParseField THUMB_URL = new ParseField("thumb_url");
|
||||
|
||||
ParseField MARKDOWN_IN = new ParseField("mrkdwn_in");
|
||||
ParseField ACTIONS = new ParseField("actions");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,8 +61,12 @@ public class SlackMessageTests extends ESTestCase {
|
|||
String imageUrl = randomBoolean() ? null : randomAlphaOfLength(10);
|
||||
String thumbUrl = randomBoolean() ? null : randomAlphaOfLength(10);
|
||||
String[] markdownFields = randomBoolean() ? null : new String[]{"pretext"};
|
||||
List<Action> actions = new ArrayList<>();
|
||||
if (randomBoolean()) {
|
||||
actions.add(new Action("primary", "action_name", "button", "action_text", "https://elastic.co"));
|
||||
}
|
||||
attachments[i] = new Attachment(fallback, color, pretext, authorName, authorLink, authorIcon, title, titleLink,
|
||||
attachmentText, fields, imageUrl, thumbUrl, markdownFields);
|
||||
attachmentText, fields, imageUrl, thumbUrl, markdownFields, actions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -102,6 +106,13 @@ public class SlackMessageTests extends ESTestCase {
|
|||
}
|
||||
builder.endArray();
|
||||
}
|
||||
if (attachment.actions.isEmpty() == false) {
|
||||
builder.startArray("actions");
|
||||
for (Action action : attachment.actions) {
|
||||
action.toXContent(builder, ToXContent.EMPTY_PARAMS);
|
||||
}
|
||||
builder.endArray();
|
||||
}
|
||||
builder.endObject();
|
||||
}
|
||||
builder.endArray();
|
||||
|
@ -159,6 +170,7 @@ public class SlackMessageTests extends ESTestCase {
|
|||
String imageUrl = null;
|
||||
String thumbUrl = null;
|
||||
String[] markdownSupportedFields = null;
|
||||
List<Action> actions = new ArrayList<>();
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
|
@ -201,6 +213,36 @@ public class SlackMessageTests extends ESTestCase {
|
|||
fieldList.add(new Field(fieldTitle, fieldValue, isShort));
|
||||
}
|
||||
fields = fieldList.toArray(new Field[fieldList.size()]);
|
||||
} else if ("actions".equals(currentFieldName)) {
|
||||
MockTextTemplateEngine engine = new MockTextTemplateEngine();
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_ARRAY) {
|
||||
Action.Template action = new Action.Template();
|
||||
while ((token = parser.nextToken()) != XContentParser.Token.END_OBJECT) {
|
||||
if (token == XContentParser.Token.FIELD_NAME) {
|
||||
currentFieldName = parser.currentName();
|
||||
} else if (token.isValue()) {
|
||||
switch (currentFieldName) {
|
||||
case "url":
|
||||
action.setUrl(new TextTemplate(parser.text()));
|
||||
break;
|
||||
case "name":
|
||||
action.setName(new TextTemplate(parser.text()));
|
||||
break;
|
||||
case "style":
|
||||
action.setStyle(new TextTemplate(parser.text()));
|
||||
break;
|
||||
case "text":
|
||||
action.setText(new TextTemplate(parser.text()));
|
||||
break;
|
||||
case "type":
|
||||
action.setType(new TextTemplate(parser.text()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
actions.add(action.render(engine, Collections.emptyMap()));
|
||||
}
|
||||
} else if ("image_url".equals(currentFieldName)) {
|
||||
imageUrl = parser.text();
|
||||
} else if ("thumb_url".equals(currentFieldName)) {
|
||||
|
@ -214,7 +256,7 @@ public class SlackMessageTests extends ESTestCase {
|
|||
}
|
||||
}
|
||||
list.add(new Attachment(fallback, color, pretext, authorName, authorLink, authorIcon, title, titleLink,
|
||||
attachmentText, fields, imageUrl, thumbUrl, markdownSupportedFields));
|
||||
attachmentText, fields, imageUrl, thumbUrl, markdownSupportedFields, actions));
|
||||
}
|
||||
attachments = list.toArray(new Attachment[list.size()]);
|
||||
}
|
||||
|
@ -345,9 +387,29 @@ public class SlackMessageTests extends ESTestCase {
|
|||
jsonBuilder.endArray();
|
||||
markdownSupportedFields = new TextTemplate[] { new TextTemplate("pretext") };
|
||||
}
|
||||
List<Action.Template> actions = new ArrayList<>();
|
||||
if (randomBoolean()) {
|
||||
jsonBuilder.startArray("actions");
|
||||
jsonBuilder.startObject();
|
||||
jsonBuilder.field("type", "button");
|
||||
jsonBuilder.field("text", "My text");
|
||||
jsonBuilder.field("url", "https://elastic.co");
|
||||
String style = randomFrom("primary", "danger");
|
||||
jsonBuilder.field("style", style);
|
||||
jsonBuilder.field("name", "somebuttonparty");
|
||||
jsonBuilder.endObject();
|
||||
jsonBuilder.endArray();
|
||||
Action.Template action = new Action.Template();
|
||||
action.setName(new TextTemplate("somebuttonparty"));
|
||||
action.setStyle(new TextTemplate(style));
|
||||
action.setText(new TextTemplate("My text"));
|
||||
action.setType(new TextTemplate("button"));
|
||||
action.setUrl(new TextTemplate("https://elastic.co"));
|
||||
actions.add(action);
|
||||
}
|
||||
jsonBuilder.endObject();
|
||||
attachments[i] = new Attachment.Template(fallback, color, pretext, authorName, authorLink, authorIcon, title,
|
||||
titleLink, attachmentText, fields, imageUrl, thumbUrl, markdownSupportedFields);
|
||||
titleLink, attachmentText, fields, imageUrl, thumbUrl, markdownSupportedFields, actions);
|
||||
}
|
||||
jsonBuilder.endArray();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.elasticsearch.xpack.watcher.condition.InternalAlwaysCondition;
|
|||
import org.elasticsearch.xpack.watcher.notification.slack.SentMessages;
|
||||
import org.elasticsearch.xpack.watcher.notification.slack.SlackAccount;
|
||||
import org.elasticsearch.xpack.watcher.notification.slack.SlackService;
|
||||
import org.elasticsearch.xpack.watcher.notification.slack.message.Action;
|
||||
import org.elasticsearch.xpack.watcher.notification.slack.message.Attachment;
|
||||
import org.elasticsearch.xpack.watcher.notification.slack.message.SlackMessage;
|
||||
import org.elasticsearch.xpack.watcher.support.xcontent.XContentSource;
|
||||
|
@ -24,6 +25,8 @@ import org.elasticsearch.xpack.watcher.test.AbstractWatcherIntegrationTestCase;
|
|||
import org.elasticsearch.xpack.watcher.transport.actions.put.PutWatchResponse;
|
||||
import org.joda.time.DateTime;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.ToXContent.EMPTY_PARAMS;
|
||||
|
@ -54,9 +57,14 @@ public class SlackServiceTests extends AbstractWatcherIntegrationTestCase {
|
|||
|
||||
public void testSendMessage() throws Exception {
|
||||
SlackService service = getInstanceFromMaster(SlackService.class);
|
||||
|
||||
// String style, String name, String type, String text, String url
|
||||
Action action = new Action(randomFrom("primary", "danger"), "action name", "button", "Click here to visit Elastic Homepage",
|
||||
"https://elastic.co");
|
||||
List<Action> actions = randomBoolean() ? null : Collections.singletonList(action);
|
||||
Attachment[] attachments = new Attachment[] {
|
||||
new Attachment("fallback", randomFrom("good", "warning", "danger"), "pretext `code` *bold*", "author_name", null, null,
|
||||
"title あいうえお", null, "_text `code` *bold*", null, null, null, new String[] { "text", "pretext" })
|
||||
"title あいうえお", null, "_text `code` *bold*", null, null, null, new String[] { "text", "pretext" }, actions)
|
||||
};
|
||||
SlackMessage message = new SlackMessage(
|
||||
"SlackServiceTests",
|
||||
|
|
Loading…
Reference in New Issue