Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import com.slack.api.model.File;
import com.slack.api.model.admin.AppWorkflow;
import com.slack.api.model.block.ContextBlockElement;
import com.slack.api.model.block.ContextActionsBlockElement;
import com.slack.api.model.block.LayoutBlock;
import com.slack.api.model.block.composition.TextObject;
import com.slack.api.model.block.element.BlockElement;
Expand Down Expand Up @@ -75,6 +76,7 @@ public static void registerTypeAdapters(GsonBuilder builder, boolean failOnUnkno
.registerTypeAdapter(LayoutBlock.class, new GsonLayoutBlockFactory(failOnUnknownProps))
.registerTypeAdapter(TextObject.class, new GsonTextObjectFactory(failOnUnknownProps))
.registerTypeAdapter(ContextBlockElement.class, new GsonContextBlockElementFactory(failOnUnknownProps))
.registerTypeAdapter(ContextActionsBlockElement.class, new GsonContextActionsBlockElementFactory(failOnUnknownProps))
.registerTypeAdapter(BlockElement.class, new GsonBlockElementFactory(failOnUnknownProps))
.registerTypeAdapter(RichTextElement.class, new GsonRichTextElementFactory(failOnUnknownProps))
.registerTypeAdapter(FunctionExecutedEvent.InputValue.class, new GsonFunctionExecutedEventInputValueFactory())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@
import static com.slack.api.model.Attachments.asAttachments;
import static com.slack.api.model.Attachments.attachment;
import static com.slack.api.model.block.Blocks.*;
import static com.slack.api.model.block.composition.BlockCompositions.confirmationDialog;
import static com.slack.api.model.block.composition.BlockCompositions.feedbackButton;
import static com.slack.api.model.block.composition.BlockCompositions.markdownText;
import static com.slack.api.model.block.composition.BlockCompositions.plainText;
import static com.slack.api.model.block.element.BlockElements.*;
Expand Down Expand Up @@ -1072,7 +1074,42 @@ public void streamMessages() throws IOException, SlackApiException {
assertThat(appends.getError(), is(nullValue()));
ChatStopStreamResponse stops = slack.methods(botToken).chatStopStream(r -> r
.channel(randomChannelId)
.ts(streamer.getTs()));
.ts(streamer.getTs())
.blocks(
asBlocks(
contextActions(a -> a.
elements(
asContextActionsElements(
feedbackButtons(b -> b
.positiveButton(
feedbackButton(c -> c
.text(plainText(":+1:"))
.value("+1")
)
)
.negativeButton(
feedbackButton(c -> c
.text(plainText(":-1:"))
.value("-1")
)
)
),
iconButton(b -> b
.icon("trash")
.text(plainText("Remove"))
.confirm(
confirmationDialog(c -> c
.title(plainText("Oops"))
.text(plainText("This response might've been just alright..."))
.style("danger")
)
)
)
)
)
)
)
));
assertThat(stops.isOk(), is(true));
assertThat(stops.getError(), is(nullValue()));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ public static ContextBlock context(String blockId, List<ContextBlockElement> ele
return ContextBlock.builder().blockId(blockId).elements(elements).build();
}

// ContextActionsBlock

public static ContextActionsBlock contextActions(ModelConfigurator<ContextActionsBlock.ContextActionsBlockBuilder> configurator) {
return configurator.configure(ContextActionsBlock.builder()).build();
}

public static ContextActionsBlock contextActions(List<ContextActionsBlockElement> elements) {
return ContextActionsBlock.builder().elements(elements).build();
}

public static ContextActionsBlock contextActions(String blockId, List<ContextActionsBlockElement> elements) {
return ContextActionsBlock.builder().blockId(blockId).elements(elements).build();
}

// DividerBlock

public static DividerBlock divider(ModelConfigurator<DividerBlock.DividerBlockBuilder> configurator) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.slack.api.model.block;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.List;

/**
* Displays actions as contextual info, which can include both feedback buttons and icon buttons.
* https://docs.slack.dev/reference/block-kit/blocks/context-actions-block
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ContextActionsBlock implements LayoutBlock {
public static final String TYPE = "context_actions";
private final String type = TYPE;
@Builder.Default
private List<ContextActionsBlockElement> elements = new ArrayList<>();
private String blockId;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.slack.api.model.block;

import com.slack.api.model.block.element.FeedbackButtonsElement;
import com.slack.api.model.block.element.IconButtonElement;

/**
* Specific interface to make context actions layout blocks' {@link ContextActionsBlock} elements type-safe,
* because ContextActionsBlock can only contain {@link FeedbackButtonsElement} and {@link IconButtonElement} elements.
* <p>
* Slack Block Kit Reference: <a href="https://docs.slack.dev/reference/block-kit/blocks/context-actions-block">Context Actions Block's elements</a>
*/
public interface ContextActionsBlockElement {

String getType();

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.slack.api.model.block;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UnknownContextActionsBlockElement implements ContextActionsBlockElement {
private String type;
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,15 @@ public static DispatchActionConfig dispatchActionConfig(ModelConfigurator<Dispat
return configurator.configure(DispatchActionConfig.builder()).build();
}

// FeedbackButtonsObject

public static FeedbackButtonObject feedbackButton(ModelConfigurator<FeedbackButtonObject.FeedbackButtonObjectBuilder> configurator) {
return configurator.configure(FeedbackButtonObject.builder()).build();
}

// SlackFileObject

public static SlackFileObject slackFile(ModelConfigurator<SlackFileObject.SlackFileObjectBuilder> configurator) {
return configurator.configure(SlackFileObject.builder()).build();
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,34 @@
import lombok.NoArgsConstructor;

/**
* Defines a dialog that adds a confirmation step to interactive elements.
*
* https://docs.slack.dev/reference/block-kit/composition-objects/confirmation-dialog-object/
* https://docs.slack.dev/messaging/migrating-outmoded-message-compositions-to-blocks
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ConfirmationDialogObject {
/**
* A plain_text text object that defines the dialog's title. Maximum length for this field is 100 characters.
*/
private PlainTextObject title;
/**
* 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.
*/
private TextObject text;
/**
* 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.
*/
private PlainTextObject confirm;
/**
* 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.
*/
private PlainTextObject deny;
/**
* 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.
*/
private String style;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.slack.api.model.block.composition;

import com.slack.api.model.block.composition.PlainTextObject;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* Defines an object containing a feedback button to be used within the {@link FeedbackButtonsElement} block.
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class FeedbackButtonObject {
/**
* 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.
*/
private PlainTextObject text;
/**
* The value to send along with the interaction payload. Maximum length is 2000 characters.
*/
private String value;
/**
* 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.
*/
private String accessibilityLabel;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.slack.api.model.ModelConfigurator;
import com.slack.api.model.block.ContextBlockElement;
import com.slack.api.model.block.ContextActionsBlockElement;

import java.util.Arrays;
import java.util.List;
Expand All @@ -19,6 +20,10 @@ public static List<ContextBlockElement> asContextElements(ContextBlockElement...
return Arrays.asList(elements);
}

public static List<ContextActionsBlockElement> asContextActionsElements(ContextActionsBlockElement... elements) {
return Arrays.asList(elements);
}

public static List<RichTextElement> asRichTextElements(RichTextElement... elements) {
return Arrays.asList(elements);
}
Expand Down Expand Up @@ -93,6 +98,18 @@ public static DatetimePickerElement datetimePicker(ModelConfigurator<DatetimePic
return configurator.configure(DatetimePickerElement.builder()).build();
}

// FeedbackButtonsElement

public static FeedbackButtonsElement feedbackButtons(ModelConfigurator<FeedbackButtonsElement.FeedbackButtonsElementBuilder> configurator) {
return configurator.configure(FeedbackButtonsElement.builder()).build();
}

// IconButtonElement

public static IconButtonElement iconButton(ModelConfigurator<IconButtonElement.IconButtonElementBuilder> configurator) {
return configurator.configure(IconButtonElement.builder()).build();
}

// ImageElement

public static ImageElement image(ModelConfigurator<ImageElement.ImageElementBuilder> configurator) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.slack.api.model.block.element;

import com.slack.api.model.block.ContextActionsBlockElement;
import com.slack.api.model.block.composition.FeedbackButtonObject;

import lombok.*;

/**
* Buttons to indicate positive or negative feedback.
* https://docs.slack.dev/reference/block-kit/block-elements/feedback-buttons-element
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class FeedbackButtonsElement extends BlockElement implements ContextActionsBlockElement {
public static final String TYPE = "feedback_buttons";
private final String type = TYPE;

/**
* An identifier for the action triggered when a menu option is selected.
* You can use this when you receive an interaction payload to identify the source of the action.
* Should be unique among all other action_ids used elsewhere by your app.
* Maximum length for this field is 255 characters.
*/
private String actionId;

/**
* A button to indicate positive feedback.
*/
private FeedbackButtonObject positiveButton;

/**
* A button to indicate negative feedback.
*/
private FeedbackButtonObject negativeButton;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package com.slack.api.model.block.element;

import com.slack.api.model.Confirmation;
import com.slack.api.model.block.ContextActionsBlockElement;
import com.slack.api.model.block.composition.ConfirmationDialogObject;
import com.slack.api.model.block.composition.PlainTextObject;

import lombok.*;

import java.util.List;

/**
* An icon button to perform actions.
* https://docs.slack.dev/reference/block-kit/block-elements/icon-button-element
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class IconButtonElement extends BlockElement implements ContextActionsBlockElement {
public static final String TYPE = "icon_button";
private final String type = TYPE;

/**
* An identifier for the action triggered when a menu option is selected.
* You can use this when you receive an interaction payload to identify the source of the action.
* Should be unique among all other action_ids used elsewhere by your app.
* Maximum length for this field is 255 characters.
*/
private String actionId;

/**
* The icon to show (e.g., "trash").
*/
private String icon;

/*
* A text object that defines the button's text. Can only be of type: plain_text.
*/
private PlainTextObject text;

/**
* The value to send along with the interaction payload. Maximum length is 2000 characters.
*/
private String value;

/**
* A confirm object that defines an optional confirmation dialog after the button is clicked.
*/
private ConfirmationDialogObject confirm;

/**
* 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.
*/
private String accessibilityLabel;

/**
* An array of user IDs for which the icon button appears. If not provided, the button is visible to all users.
*/
private List<String> visibleToUserIds;
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ private Class<? extends BlockElement> getContextBlockElementClassInstance(String
switch (typeName) {
case ButtonElement.TYPE:
return ButtonElement.class;
case FeedbackButtonsElement.TYPE:
return FeedbackButtonsElement.class;
case IconButtonElement.TYPE:
return IconButtonElement.class;
case ImageElement.TYPE:
return ImageElement.class;
case ChannelsSelectElement.TYPE:
Expand Down
Loading