Skip to content

Commit b08ba12

Browse files
authored
feat(model): add feedback_buttons and icon_button blocks as context_actions block elements (#1524)
1 parent 5e677f0 commit b08ba12

File tree

18 files changed

+451
-3
lines changed

18 files changed

+451
-3
lines changed

slack-api-client/src/main/java/com/slack/api/util/json/GsonFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import com.slack.api.model.File;
1010
import com.slack.api.model.admin.AppWorkflow;
1111
import com.slack.api.model.block.ContextBlockElement;
12+
import com.slack.api.model.block.ContextActionsBlockElement;
1213
import com.slack.api.model.block.LayoutBlock;
1314
import com.slack.api.model.block.composition.TextObject;
1415
import com.slack.api.model.block.element.BlockElement;
@@ -75,6 +76,7 @@ public static void registerTypeAdapters(GsonBuilder builder, boolean failOnUnkno
7576
.registerTypeAdapter(LayoutBlock.class, new GsonLayoutBlockFactory(failOnUnknownProps))
7677
.registerTypeAdapter(TextObject.class, new GsonTextObjectFactory(failOnUnknownProps))
7778
.registerTypeAdapter(ContextBlockElement.class, new GsonContextBlockElementFactory(failOnUnknownProps))
79+
.registerTypeAdapter(ContextActionsBlockElement.class, new GsonContextActionsBlockElementFactory(failOnUnknownProps))
7880
.registerTypeAdapter(BlockElement.class, new GsonBlockElementFactory(failOnUnknownProps))
7981
.registerTypeAdapter(RichTextElement.class, new GsonRichTextElementFactory(failOnUnknownProps))
8082
.registerTypeAdapter(FunctionExecutedEvent.InputValue.class, new GsonFunctionExecutedEventInputValueFactory())

slack-api-client/src/test/java/test_with_remote_apis/methods/chat_Test.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@
3838
import static com.slack.api.model.Attachments.asAttachments;
3939
import static com.slack.api.model.Attachments.attachment;
4040
import static com.slack.api.model.block.Blocks.*;
41+
import static com.slack.api.model.block.composition.BlockCompositions.confirmationDialog;
42+
import static com.slack.api.model.block.composition.BlockCompositions.feedbackButton;
4143
import static com.slack.api.model.block.composition.BlockCompositions.markdownText;
4244
import static com.slack.api.model.block.composition.BlockCompositions.plainText;
4345
import static com.slack.api.model.block.element.BlockElements.*;
@@ -1072,7 +1074,42 @@ public void streamMessages() throws IOException, SlackApiException {
10721074
assertThat(appends.getError(), is(nullValue()));
10731075
ChatStopStreamResponse stops = slack.methods(botToken).chatStopStream(r -> r
10741076
.channel(randomChannelId)
1075-
.ts(streamer.getTs()));
1077+
.ts(streamer.getTs())
1078+
.blocks(
1079+
asBlocks(
1080+
contextActions(a -> a.
1081+
elements(
1082+
asContextActionsElements(
1083+
feedbackButtons(b -> b
1084+
.positiveButton(
1085+
feedbackButton(c -> c
1086+
.text(plainText(":+1:"))
1087+
.value("+1")
1088+
)
1089+
)
1090+
.negativeButton(
1091+
feedbackButton(c -> c
1092+
.text(plainText(":-1:"))
1093+
.value("-1")
1094+
)
1095+
)
1096+
),
1097+
iconButton(b -> b
1098+
.icon("trash")
1099+
.text(plainText("Remove"))
1100+
.confirm(
1101+
confirmationDialog(c -> c
1102+
.title(plainText("Oops"))
1103+
.text(plainText("This response might've been just alright..."))
1104+
.style("danger")
1105+
)
1106+
)
1107+
)
1108+
)
1109+
)
1110+
)
1111+
)
1112+
));
10761113
assertThat(stops.isOk(), is(true));
10771114
assertThat(stops.getError(), is(nullValue()));
10781115
}

slack-api-model/src/main/java/com/slack/api/model/block/Blocks.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ public static ContextBlock context(String blockId, List<ContextBlockElement> ele
4343
return ContextBlock.builder().blockId(blockId).elements(elements).build();
4444
}
4545

46+
// ContextActionsBlock
47+
48+
public static ContextActionsBlock contextActions(ModelConfigurator<ContextActionsBlock.ContextActionsBlockBuilder> configurator) {
49+
return configurator.configure(ContextActionsBlock.builder()).build();
50+
}
51+
52+
public static ContextActionsBlock contextActions(List<ContextActionsBlockElement> elements) {
53+
return ContextActionsBlock.builder().elements(elements).build();
54+
}
55+
56+
public static ContextActionsBlock contextActions(String blockId, List<ContextActionsBlockElement> elements) {
57+
return ContextActionsBlock.builder().blockId(blockId).elements(elements).build();
58+
}
59+
4660
// DividerBlock
4761

4862
public static DividerBlock divider(ModelConfigurator<DividerBlock.DividerBlockBuilder> configurator) {
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.slack.api.model.block;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
11+
/**
12+
* Displays actions as contextual info, which can include both feedback buttons and icon buttons.
13+
* https://docs.slack.dev/reference/block-kit/blocks/context-actions-block
14+
*/
15+
@Data
16+
@Builder
17+
@NoArgsConstructor
18+
@AllArgsConstructor
19+
public class ContextActionsBlock implements LayoutBlock {
20+
public static final String TYPE = "context_actions";
21+
private final String type = TYPE;
22+
@Builder.Default
23+
private List<ContextActionsBlockElement> elements = new ArrayList<>();
24+
private String blockId;
25+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.slack.api.model.block;
2+
3+
import com.slack.api.model.block.element.FeedbackButtonsElement;
4+
import com.slack.api.model.block.element.IconButtonElement;
5+
6+
/**
7+
* Specific interface to make context actions layout blocks' {@link ContextActionsBlock} elements type-safe,
8+
* because ContextActionsBlock can only contain {@link FeedbackButtonsElement} and {@link IconButtonElement} elements.
9+
* <p>
10+
* Slack Block Kit Reference: <a href="https://docs.slack.dev/reference/block-kit/blocks/context-actions-block">Context Actions Block's elements</a>
11+
*/
12+
public interface ContextActionsBlockElement {
13+
14+
String getType();
15+
16+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.slack.api.model.block;
2+
3+
import lombok.AllArgsConstructor;
4+
import lombok.Builder;
5+
import lombok.Data;
6+
import lombok.NoArgsConstructor;
7+
8+
@Data
9+
@Builder
10+
@NoArgsConstructor
11+
@AllArgsConstructor
12+
public class UnknownContextActionsBlockElement implements ContextActionsBlockElement {
13+
private String type;
14+
}

slack-api-model/src/main/java/com/slack/api/model/block/composition/BlockCompositions.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,15 @@ public static DispatchActionConfig dispatchActionConfig(ModelConfigurator<Dispat
7676
return configurator.configure(DispatchActionConfig.builder()).build();
7777
}
7878

79+
// FeedbackButtonsObject
80+
81+
public static FeedbackButtonObject feedbackButton(ModelConfigurator<FeedbackButtonObject.FeedbackButtonObjectBuilder> configurator) {
82+
return configurator.configure(FeedbackButtonObject.builder()).build();
83+
}
84+
7985
// SlackFileObject
8086

8187
public static SlackFileObject slackFile(ModelConfigurator<SlackFileObject.SlackFileObjectBuilder> configurator) {
8288
return configurator.configure(SlackFileObject.builder()).build();
8389
}
84-
8590
}
86-

slack-api-model/src/main/java/com/slack/api/model/block/composition/ConfirmationDialogObject.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,34 @@
66
import lombok.NoArgsConstructor;
77

88
/**
9+
* Defines a dialog that adds a confirmation step to interactive elements.
10+
*
11+
* https://docs.slack.dev/reference/block-kit/composition-objects/confirmation-dialog-object/
912
* https://docs.slack.dev/messaging/migrating-outmoded-message-compositions-to-blocks
1013
*/
1114
@Data
1215
@Builder
1316
@NoArgsConstructor
1417
@AllArgsConstructor
1518
public class ConfirmationDialogObject {
19+
/**
20+
* A plain_text text object that defines the dialog's title. Maximum length for this field is 100 characters.
21+
*/
1622
private PlainTextObject title;
23+
/**
24+
* A plain_text text object that defines the explanatory text that appears in the confirm dialog. Maximum length for the text in this field is 300 characters.
25+
*/
1726
private TextObject text;
27+
/**
28+
* A plain_text text object to define the text of the button that confirms the action. Maximum length for the text in this field is 30 characters.
29+
*/
1830
private PlainTextObject confirm;
31+
/**
32+
* A plain_text text object to define the text of the button that cancels the action. Maximum length for the text in this field is 30 characters.
33+
*/
1934
private PlainTextObject deny;
35+
/**
36+
* Defines the color scheme applied to the confirm button. A value of danger will display the button with a red background on desktop, or red text on mobile. A value of primary will display the button with a green background on desktop, or blue text on mobile. If this field is not provided, the default value will be primary.
37+
*/
2038
private String style;
2139
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.slack.api.model.block.composition;
2+
3+
import com.slack.api.model.block.composition.PlainTextObject;
4+
5+
import lombok.AllArgsConstructor;
6+
import lombok.Builder;
7+
import lombok.Data;
8+
import lombok.NoArgsConstructor;
9+
10+
/**
11+
* Defines an object containing a feedback button to be used within the {@link FeedbackButtonsElement} block.
12+
*/
13+
@Data
14+
@Builder
15+
@NoArgsConstructor
16+
@AllArgsConstructor
17+
public class FeedbackButtonObject {
18+
/**
19+
* A text object that defines the button's text. Can only be of type: plain_text. Maximum length for the text in this field is 75 characters.
20+
*/
21+
private PlainTextObject text;
22+
/**
23+
* The value to send along with the interaction payload. Maximum length is 2000 characters.
24+
*/
25+
private String value;
26+
/**
27+
* A label for longer descriptive text about a button element. This label will be read out by screen readers instead of the button text object. Maximum length is 75 characters.
28+
*/
29+
private String accessibilityLabel;
30+
}

slack-api-model/src/main/java/com/slack/api/model/block/element/BlockElements.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.slack.api.model.ModelConfigurator;
44
import com.slack.api.model.block.ContextBlockElement;
5+
import com.slack.api.model.block.ContextActionsBlockElement;
56

67
import java.util.Arrays;
78
import java.util.List;
@@ -19,6 +20,10 @@ public static List<ContextBlockElement> asContextElements(ContextBlockElement...
1920
return Arrays.asList(elements);
2021
}
2122

23+
public static List<ContextActionsBlockElement> asContextActionsElements(ContextActionsBlockElement... elements) {
24+
return Arrays.asList(elements);
25+
}
26+
2227
public static List<RichTextElement> asRichTextElements(RichTextElement... elements) {
2328
return Arrays.asList(elements);
2429
}
@@ -93,6 +98,18 @@ public static DatetimePickerElement datetimePicker(ModelConfigurator<DatetimePic
9398
return configurator.configure(DatetimePickerElement.builder()).build();
9499
}
95100

101+
// FeedbackButtonsElement
102+
103+
public static FeedbackButtonsElement feedbackButtons(ModelConfigurator<FeedbackButtonsElement.FeedbackButtonsElementBuilder> configurator) {
104+
return configurator.configure(FeedbackButtonsElement.builder()).build();
105+
}
106+
107+
// IconButtonElement
108+
109+
public static IconButtonElement iconButton(ModelConfigurator<IconButtonElement.IconButtonElementBuilder> configurator) {
110+
return configurator.configure(IconButtonElement.builder()).build();
111+
}
112+
96113
// ImageElement
97114

98115
public static ImageElement image(ModelConfigurator<ImageElement.ImageElementBuilder> configurator) {

0 commit comments

Comments
 (0)