diff --git a/slack-api-model/src/main/java/com/slack/api/model/block/AlertBlock.java b/slack-api-model/src/main/java/com/slack/api/model/block/AlertBlock.java
new file mode 100644
index 000000000..80003adb3
--- /dev/null
+++ b/slack-api-model/src/main/java/com/slack/api/model/block/AlertBlock.java
@@ -0,0 +1,41 @@
+package com.slack.api.model.block;
+
+import com.slack.api.model.block.composition.TextObject;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * https://docs.slack.dev/reference/block-kit/blocks/alert-block
+ *
+ * Displays an inline alert message. Alert blocks are currently only supported in modals.
+ */
+@Data
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class AlertBlock implements LayoutBlock {
+ public static final String TYPE = "alert";
+ private final String type = TYPE;
+
+ /**
+ * The message content of the alert, as a plain_text or mrkdwn text object.
+ * Maximum length for the text in this field is 200 characters.
+ */
+ private TextObject text;
+
+ /**
+ * The severity level of the alert. One of default, info, warning, error, or success.
+ * Will be default if omitted.
+ */
+ private String level;
+
+ /**
+ * A string acting as a unique identifier for a block. If not specified, one will be generated.
+ * Maximum length for this field is 255 characters.
+ * block_id should be unique for each message and each iteration of a message.
+ * If a message is updated, use a new block_id.
+ */
+ private String blockId;
+}
diff --git a/slack-api-model/src/main/java/com/slack/api/model/block/Blocks.java b/slack-api-model/src/main/java/com/slack/api/model/block/Blocks.java
index fd451d8d2..0ef675042 100644
--- a/slack-api-model/src/main/java/com/slack/api/model/block/Blocks.java
+++ b/slack-api-model/src/main/java/com/slack/api/model/block/Blocks.java
@@ -129,4 +129,10 @@ public static ShareShortcutBlock shareShortcut() {
return ShareShortcutBlock.builder().build();
}
+ // AlertBlock
+
+ public static AlertBlock alert(ModelConfigurator configurator) {
+ return configurator.configure(AlertBlock.builder()).build();
+ }
+
}
diff --git a/slack-api-model/src/main/java/com/slack/api/util/json/GsonLayoutBlockFactory.java b/slack-api-model/src/main/java/com/slack/api/util/json/GsonLayoutBlockFactory.java
index 9286e6b51..4c4533808 100644
--- a/slack-api-model/src/main/java/com/slack/api/util/json/GsonLayoutBlockFactory.java
+++ b/slack-api-model/src/main/java/com/slack/api/util/json/GsonLayoutBlockFactory.java
@@ -61,6 +61,8 @@ private Class extends LayoutBlock> getLayoutClassInstance(String typeName) {
return RichTextBlock.class;
case ShareShortcutBlock.TYPE:
return ShareShortcutBlock.class;
+ case AlertBlock.TYPE:
+ return AlertBlock.class;
default:
if (failOnUnknownProperties) {
throw new JsonParseException("Unsupported layout block type: " + typeName);
diff --git a/slack-api-model/src/test/java/test_locally/api/model/block/BlockKitTest.java b/slack-api-model/src/test/java/test_locally/api/model/block/BlockKitTest.java
index 1fc12d58d..eff72529a 100644
--- a/slack-api-model/src/test/java/test_locally/api/model/block/BlockKitTest.java
+++ b/slack-api-model/src/test/java/test_locally/api/model/block/BlockKitTest.java
@@ -1742,6 +1742,63 @@ public void parseVideoBlocks() {
assertEquals("https://www.youtube.com/embed/RRxQQxiM7AA?feature=oembed&autoplay=1", block.getVideoUrl());
}
+ @Test
+ public void parseAlertBlocks() {
+ // https://docs.slack.dev/reference/block-kit/blocks/alert-block
+ String json = "{\n" +
+ " \"blocks\": [\n" +
+ " {\n" +
+ " \"type\": \"alert\",\n" +
+ " \"block_id\": \"alert-1\",\n" +
+ " \"text\": {\n" +
+ " \"type\": \"mrkdwn\",\n" +
+ " \"text\": \"Something went *wrong*.\"\n" +
+ " },\n" +
+ " \"level\": \"error\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"type\": \"alert\",\n" +
+ " \"text\": {\n" +
+ " \"type\": \"plain_text\",\n" +
+ " \"text\": \"A plain text alert with no markup.\"\n" +
+ " }\n" +
+ " }\n" +
+ " ]\n" +
+ "}";
+ View view = GsonFactory.createSnakeCase().fromJson(json, View.class);
+ assertNotNull(view);
+ assertEquals(2, view.getBlocks().size());
+
+ AlertBlock errorAlert = (AlertBlock) view.getBlocks().get(0);
+ assertEquals("alert", errorAlert.getType());
+ assertEquals("alert-1", errorAlert.getBlockId());
+ assertEquals("error", errorAlert.getLevel());
+ assertEquals("mrkdwn", errorAlert.getText().getType());
+ assertEquals("Something went *wrong*.", errorAlert.getText().getText());
+
+ AlertBlock defaultAlert = (AlertBlock) view.getBlocks().get(1);
+ assertEquals("plain_text", defaultAlert.getText().getType());
+ assertNull(defaultAlert.getLevel());
+ assertNull(defaultAlert.getBlockId());
+ }
+
+ @Test
+ public void buildAlertBlock() {
+ AlertBlock block = alert(a -> a
+ .blockId("alert-1")
+ .level("info")
+ .text(plainText("Heads up!")));
+ assertNotNull(block);
+ assertEquals("alert", block.getType());
+
+ Gson gson = GsonFactory.createSnakeCase();
+ String output = gson.toJson(block);
+ AlertBlock parsed = gson.fromJson(output, AlertBlock.class);
+ assertEquals("alert-1", parsed.getBlockId());
+ assertEquals("info", parsed.getLevel());
+ assertEquals("Heads up!", parsed.getText().getText());
+ }
+
@Test
public void parseLinkTriggerMessages() {
// https://tools.slack.dev/deno-slack-sdk/