Skip to content

Commit 0c4813f

Browse files
committed
feat(model): add feedback_buttons and icon_button blocks as context_actions block elements
1 parent 1317675 commit 0c4813f

File tree

10 files changed

+262
-3
lines changed

10 files changed

+262
-3
lines changed

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

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -826,7 +826,42 @@ public void streamMessages() throws IOException, SlackApiException {
826826
assertThat(appends.getError(), is(nullValue()));
827827
ChatStopStreamResponse stops = slack.methods(botToken).chatStopStream(r -> r
828828
.channel(randomChannelId)
829-
.ts(streamer.getTs()));
829+
.ts(streamer.getTs())
830+
.blocks(
831+
asBlocks(
832+
contextActions(c -> c.
833+
elements(
834+
asContextActionsElements(
835+
feedbackButtons(b -> b
836+
.positiveButton(
837+
feedbackButton(a -> a
838+
.text(plainText(":+1:"))
839+
.value("+1")
840+
)
841+
)
842+
.negativeButton(
843+
feedbackButton(a -> a
844+
.text(plainText(":-1:"))
845+
.value("-1")
846+
)
847+
)
848+
),
849+
iconButton(b -> b
850+
.icon("trash")
851+
.text(plainText("Remove"))
852+
.confirm(
853+
confirmationDialog(d -> d
854+
.title(plainText("Oops"))
855+
.text(plainText("This response might've been just alright..."))
856+
.style("danger")
857+
)
858+
)
859+
)
860+
)
861+
)
862+
)
863+
)
864+
));
830865
assertThat(stops.isOk(), is(true));
831866
assertThat(stops.getError(), is(nullValue()));
832867
}

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+
}

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) {
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.slack.api.model.block.element;
2+
3+
import com.slack.api.model.block.ContextActionsBlockElement;
4+
import com.slack.api.model.block.composition.FeedbackButtonObject;
5+
6+
import lombok.*;
7+
8+
/**
9+
* Buttons to indicate positive or negative feedback.
10+
* https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element
11+
*/
12+
@Data
13+
@Builder
14+
@NoArgsConstructor
15+
@AllArgsConstructor
16+
@EqualsAndHashCode(callSuper = false)
17+
public class FeedbackButtonsElement extends BlockElement implements ContextActionsBlockElement {
18+
public static final String TYPE = "feedback_buttons";
19+
private final String type = TYPE;
20+
21+
/**
22+
* An identifier for the action triggered when a menu option is selected.
23+
* You can use this when you receive an interaction payload to identify the source of the action.
24+
* Should be unique among all other action_ids used elsewhere by your app.
25+
* Maximum length for this field is 255 characters.
26+
*/
27+
private String actionId;
28+
29+
/**
30+
* A button to indicate positive feedback.
31+
*/
32+
private FeedbackButtonObject positiveButton;
33+
34+
/**
35+
* A button to indicate negative feedback.
36+
*/
37+
private FeedbackButtonObject negativeButton;
38+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package com.slack.api.model.block.element;
2+
3+
import com.slack.api.model.Confirmation;
4+
import com.slack.api.model.block.ContextActionsBlockElement;
5+
import com.slack.api.model.block.composition.ConfirmationDialogObject;
6+
import com.slack.api.model.block.composition.PlainTextObject;
7+
8+
import lombok.*;
9+
10+
import java.util.List;
11+
12+
/**
13+
* An icon button to perform actions.
14+
* https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element
15+
*/
16+
@Data
17+
@Builder
18+
@NoArgsConstructor
19+
@AllArgsConstructor
20+
@EqualsAndHashCode(callSuper = false)
21+
public class IconButtonElement extends BlockElement implements ContextActionsBlockElement {
22+
public static final String TYPE = "icon_button";
23+
private final String type = TYPE;
24+
25+
/**
26+
* An identifier for the action triggered when a menu option is selected.
27+
* You can use this when you receive an interaction payload to identify the source of the action.
28+
* Should be unique among all other action_ids used elsewhere by your app.
29+
* Maximum length for this field is 255 characters.
30+
*/
31+
private String actionId;
32+
33+
/**
34+
* The icon to show (e.g., "trash").
35+
*/
36+
private String icon;
37+
38+
/*
39+
* A text object that defines the button's text. Can only be of type: plain_text.
40+
*/
41+
private PlainTextObject text;
42+
43+
/**
44+
* The value to send along with the interaction payload. Maximum length is 2000 characters.
45+
*/
46+
private String value;
47+
48+
/**
49+
* A confirm object that defines an optional confirmation dialog after the button is clicked.
50+
*/
51+
private ConfirmationDialogObject confirm;
52+
53+
/**
54+
* 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.
55+
*/
56+
private String accessibilityLabel;
57+
58+
/**
59+
* An array of user IDs for which the icon button appears. If not provided, the button is visible to all users.
60+
*/
61+
private List<String> visibleToUserIds;
62+
}

0 commit comments

Comments
 (0)