From bb20c2bb1aa0d76cf6fe1b15c619cee9061729e1 Mon Sep 17 00:00:00 2001 From: Hyeonmin Park Date: Thu, 19 Sep 2024 20:52:15 +0900 Subject: [PATCH 1/6] Speedup slow tests due to rate limit (#1377) --- .../java/test_locally/api/methods/TeamTest.java | 17 +++++++++++++++++ .../methods_admin_api/AdminApiAsyncTest.java | 16 ++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/slack-api-client/src/test/java/test_locally/api/methods/TeamTest.java b/slack-api-client/src/test/java/test_locally/api/methods/TeamTest.java index 2ae094e66..3f51a20a0 100644 --- a/slack-api-client/src/test/java/test_locally/api/methods/TeamTest.java +++ b/slack-api-client/src/test/java/test_locally/api/methods/TeamTest.java @@ -2,11 +2,15 @@ import com.slack.api.Slack; import com.slack.api.SlackConfig; +import com.slack.api.methods.MethodsConfig; +import com.slack.api.methods.MethodsCustomRateLimitResolver; import org.junit.After; import org.junit.Before; import org.junit.Test; import util.MockSlackApiServer; +import java.util.Optional; + import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static util.MockSlackApi.ValidToken; @@ -21,6 +25,19 @@ public class TeamTest { public void setup() throws Exception { server.start(); config.setMethodsEndpointUrlPrefix(server.getMethodsEndpointPrefix()); + MethodsConfig methodsConfig = new MethodsConfig(); + methodsConfig.setCustomRateLimitResolver(new MethodsCustomRateLimitResolver() { + @Override + public Optional getCustomAllowedRequestsPerMinute(String teamId, String methodName) { + return Optional.of(20); + } + + @Override + public Optional getCustomAllowedRequestsForChatPostMessagePerMinute(String teamId, String channel) { + return Optional.empty(); + } + }); + config.setMethodsConfig(methodsConfig); } @After diff --git a/slack-api-client/src/test/java/test_locally/api/methods_admin_api/AdminApiAsyncTest.java b/slack-api-client/src/test/java/test_locally/api/methods_admin_api/AdminApiAsyncTest.java index cc64feea3..d4042a0f8 100644 --- a/slack-api-client/src/test/java/test_locally/api/methods_admin_api/AdminApiAsyncTest.java +++ b/slack-api-client/src/test/java/test_locally/api/methods_admin_api/AdminApiAsyncTest.java @@ -3,6 +3,8 @@ import com.slack.api.Slack; import com.slack.api.SlackConfig; import com.slack.api.methods.AsyncMethodsClient; +import com.slack.api.methods.MethodsConfig; +import com.slack.api.methods.MethodsCustomRateLimitResolver; import com.slack.api.model.admin.AppConfig; import org.junit.After; import org.junit.Before; @@ -11,6 +13,7 @@ import java.lang.reflect.Array; import java.util.Arrays; +import java.util.Optional; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -26,6 +29,19 @@ public class AdminApiAsyncTest { public void setup() throws Exception { server.start(); config.setMethodsEndpointUrlPrefix(server.getMethodsEndpointPrefix()); + MethodsConfig methodsConfig = new MethodsConfig(); + methodsConfig.setCustomRateLimitResolver(new MethodsCustomRateLimitResolver() { + @Override + public Optional getCustomAllowedRequestsPerMinute(String teamId, String methodName) { + return Optional.of(50); + } + + @Override + public Optional getCustomAllowedRequestsForChatPostMessagePerMinute(String teamId, String channel) { + return Optional.empty(); + } + }); + config.setMethodsConfig(methodsConfig); } @After From 8d83942f2601c93cd821756a3c13719a917af5e0 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Fri, 20 Sep 2024 07:44:38 +0900 Subject: [PATCH 2/6] Fix #1147 Improve the logic to extract the requestUserId for context objects (#1375) --- .../bolt/request/builtin/EventRequest.java | 32 ++- .../request/EventRequestTest.java | 249 ++++++++++++++++++ 2 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 bolt/src/test/java/test_locally/request/EventRequestTest.java diff --git a/bolt/src/main/java/com/slack/api/bolt/request/builtin/EventRequest.java b/bolt/src/main/java/com/slack/api/bolt/request/builtin/EventRequest.java index 98fee2a7e..58112e11b 100644 --- a/bolt/src/main/java/com/slack/api/bolt/request/builtin/EventRequest.java +++ b/bolt/src/main/java/com/slack/api/bolt/request/builtin/EventRequest.java @@ -83,6 +83,8 @@ public EventRequest( } this.getContext().setEnterpriseId(enterpriseId); this.getContext().setTeamId(teamId); + this.getContext().setRequestUserId(extractRequestUserId(payload)); + // set retry related header values to the context if (this.headers != null && this.headers.getNames().size() > 0) { for (String name : this.headers.getNames()) { @@ -119,7 +121,35 @@ public EventRequest( } } - private EventContext context = new EventContext(); + private static String extractRequestUserId(JsonObject payload) { + if (payload.get("user") != null) { + if (payload.get("user").isJsonPrimitive()) { + return payload.get("user").getAsString(); + } else if (payload.get("user").isJsonObject()) { + JsonElement userId = payload.get("user").getAsJsonObject().get("id"); + if (userId != null) { + return userId.getAsString(); + } + } + } + if (payload.get("user_id") != null) { + return payload.get("user_id").getAsString(); + } + if (payload.get("event") != null) { + return extractRequestUserId(payload.get("event").getAsJsonObject()); + } + if (payload.get("message") != null) { + // message_changed: body["event"]["message"] + return extractRequestUserId(payload.get("message").getAsJsonObject()); + } + if (payload.get("previous_message") != null) { + // message_deleted: body["event"]["previous_message"] + return extractRequestUserId(payload.get("previous_message").getAsJsonObject()); + } + return null; + } + + private final EventContext context = new EventContext(); @Override public EventContext getContext() { diff --git a/bolt/src/test/java/test_locally/request/EventRequestTest.java b/bolt/src/test/java/test_locally/request/EventRequestTest.java new file mode 100644 index 000000000..8f11a751c --- /dev/null +++ b/bolt/src/test/java/test_locally/request/EventRequestTest.java @@ -0,0 +1,249 @@ +package test_locally.request; + +import com.slack.api.bolt.request.RequestHeaders; +import com.slack.api.bolt.request.builtin.EventRequest; +import org.junit.Test; + +import java.util.HashMap; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +public class EventRequestTest { + + String appMentionPayload = "{\n" + + " \"token\": \"legacy-fixed-value\",\n" + + " \"team_id\": \"T123\",\n" + + " \"api_app_id\": \"A123\",\n" + + " \"event\": {\n" + + " \"client_msg_id\": \"3fd13273-5a6a-4b5c-bd6f-109fd697038c\",\n" + + " \"type\": \"app_mention\",\n" + + " \"text\": \"<@U123> test\",\n" + + " \"user\": \"UUUUUXXXXX\",\n" + + " \"ts\": \"1583636399.000700\",\n" + + " \"team\": \"T123\",\n" + + " \"blocks\": [\n" + + " {\n" + + " \"type\": \"rich_text\",\n" + + " \"block_id\": \"FMAzp\",\n" + + " \"elements\": [\n" + + " {\n" + + " \"type\": \"rich_text_section\",\n" + + " \"elements\": [\n" + + " {\n" + + " \"type\": \"user\",\n" + + " \"user_id\": \"U123\"\n" + + " },\n" + + " {\n" + + " \"type\": \"text\",\n" + + " \"text\": \" test\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"channel\": \"C123\",\n" + + " \"event_ts\": \"1583636399.000700\"\n" + + " },\n" + + " \"type\": \"event_callback\",\n" + + " \"event_id\": \"EvV1KV8BM3\",\n" + + " \"event_time\": 1583636399,\n" + + " \"authed_users\": [\n" + + " \"U123\"\n" + + " ]\n" + + "}"; + String appMentionPayloadWithSubtype = "{\n" + + " \"token\": \"legacy-fixed-value\",\n" + + " \"team_id\": \"T123\",\n" + + " \"api_app_id\": \"A123\",\n" + + " \"event\": {\n" + + " \"client_msg_id\": \"3fd13273-5a6a-4b5c-bd6f-109fd697038c\",\n" + + " \"type\": \"app_mention\",\n" + + " \"subtype\": \"bot_message\",\n" + + " \"text\": \"<@U123> test\",\n" + + " \"bot_id\": \"B123\",\n" + + " \"ts\": \"1583636399.000700\",\n" + + " \"team\": \"T123\",\n" + + " \"blocks\": [\n" + + " {\n" + + " \"type\": \"rich_text\",\n" + + " \"block_id\": \"FMAzp\",\n" + + " \"elements\": [\n" + + " {\n" + + " \"type\": \"rich_text_section\",\n" + + " \"elements\": [\n" + + " {\n" + + " \"type\": \"user\",\n" + + " \"user_id\": \"U123\"\n" + + " },\n" + + " {\n" + + " \"type\": \"text\",\n" + + " \"text\": \" test\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"channel\": \"C123\",\n" + + " \"event_ts\": \"1583636399.000700\"\n" + + " },\n" + + " \"type\": \"event_callback\",\n" + + " \"event_id\": \"EvV1KV8BM3\",\n" + + " \"event_time\": 1583636399,\n" + + " \"authed_users\": [\n" + + " \"U123\"\n" + + " ]\n" + + "}"; + String messagePayload = "{\n" + + " \"token\": \"legacy-fixed-value\",\n" + + " \"team_id\": \"T123\",\n" + + " \"api_app_id\": \"A123\",\n" + + " \"event\": {\n" + + " \"client_msg_id\": \"3fd13273-5a6a-4b5c-bd6f-109fd697038c\",\n" + + " \"type\": \"message\",\n" + + " \"text\": \"<@U123> test\",\n" + + " \"user\": \"UUUUUXXXXX\",\n" + + " \"ts\": \"1583636399.000700\",\n" + + " \"team\": \"T123\",\n" + + " \"blocks\": [\n" + + " {\n" + + " \"type\": \"rich_text\",\n" + + " \"block_id\": \"FMAzp\",\n" + + " \"elements\": [\n" + + " {\n" + + " \"type\": \"rich_text_section\",\n" + + " \"elements\": [\n" + + " {\n" + + " \"type\": \"user\",\n" + + " \"user_id\": \"U123\"\n" + + " },\n" + + " {\n" + + " \"type\": \"text\",\n" + + " \"text\": \" test\"\n" + + " }\n" + + " ]\n" + + " }\n" + + " ]\n" + + " }\n" + + " ],\n" + + " \"channel\": \"C123\",\n" + + " \"event_ts\": \"1583636399.000700\",\n" + + " \"channel_type\": \"channel\"\n" + + " },\n" + + " \"type\": \"event_callback\",\n" + + " \"event_id\": \"EvV1KA7U3A\",\n" + + " \"event_time\": 1583636399,\n" + + " \"authed_users\": [\n" + + " \"U123\"\n" + + " ]\n" + + "}"; + + String appMentionPayloadInSlackConnect = "{\n" + + " \"token\": \"fixed-value\",\n" + + " \"team_id\": \"T_INSTALLED\",\n" + + " \"enterprise_id\": \"E_INSTALLED\",\n" + + " \"api_app_id\": \"A111\",\n" + + " \"event\": {\n" + + " \"client_msg_id\": \"ae6d418a-ff0e-433f-ba10-915cebb1bb94\",\n" + + " \"type\": \"app_mention\",\n" + + " \"text\": \"<@U123> hey\",\n" + + " \"user\": \"UUUUUXXXXX\",\n" + + " \"ts\": \"1605835902.008000\",\n" + + " \"team\": \"T_INSTALLED\",\n" + + " \"channel\": \"C111\",\n" + + " \"event_ts\": \"1605835902.008000\"\n" + + " },\n" + + " \"type\": \"event_callback\",\n" + + " \"event_id\": \"Ev01FC50TXB6\",\n" + + " \"event_time\": 1605835902,\n" + + " \"authorizations\": [\n" + + " {\n" + + " \"enterprise_id\": \"E_INSTALLED\",\n" + + " \"team_id\": \"T_INSTALLED\",\n" + + " \"user_id\": \"U234\",\n" + + " \"is_bot\": true,\n" + + " \"is_enterprise_install\": false\n" + + " }\n" + + " ],\n" + + " \"is_ext_shared_channel\": true,\n" + + " \"event_context\": \"1-app_mention-T_INSTALLED-C111\"\n" + + "}"; + + String messagePayloadInSlackConnect = "{\n" + + " \"token\": \"fixed-value\",\n" + + " \"team_id\": \"T_SOURCE\",\n" + + " \"api_app_id\": \"A111\",\n" + + " \"event\": {\n" + + " \"bot_id\": \"B123\",\n" + + " \"type\": \"message\",\n" + + " \"text\": \"Hi there!\",\n" + + " \"user\": \"UUUUUXXXXX\",\n" + + " \"ts\": \"1605835904.008100\",\n" + + " \"team\": \"T_INSTALLED\",\n" + + " \"bot_profile\": {\n" + + " \"id\": \"B123\",\n" + + " \"deleted\": false,\n" + + " \"name\": \"events-api-oauth-app\",\n" + + " \"updated\": 1605835851,\n" + + " \"app_id\": \"A111\",\n" + + " \"icons\": {\n" + + " \"image_36\": \"https://a.slack-edge.com/80588/img/plugins/app/bot_36.png\",\n" + + " \"image_48\": \"https://a.slack-edge.com/80588/img/plugins/app/bot_48.png\",\n" + + " \"image_72\": \"https://a.slack-edge.com/80588/img/plugins/app/service_72.png\"\n" + + " },\n" + + " \"team_id\": \"T_INSTALLED\"\n" + + " },\n" + + " \"channel\": \"C111\",\n" + + " \"event_ts\": \"1605835904.008100\",\n" + + " \"channel_type\": \"channel\"\n" + + " },\n" + + " \"type\": \"event_callback\",\n" + + " \"event_id\": \"Ev01F66ATNKV\",\n" + + " \"event_time\": 1605835904,\n" + + " \"authorizations\": [\n" + + " {\n" + + " \"enterprise_id\": \"E_INSTALLED\",\n" + + " \"team_id\": \"T_INSTALLED\",\n" + + " \"user_id\": \"U234\",\n" + + " \"is_bot\": true,\n" + + " \"is_enterprise_install\": false\n" + + " }\n" + + " ],\n" + + " \"is_ext_shared_channel\": true,\n" + + " \"event_context\": \"1-message-T_SOURCE-C111\"\n" + + "}"; + + String userTokenRevokedEvent = "{\n" + + " \"token\": \"fixed-value\",\n" + + " \"team_id\": \"T111\",\n" + + " \"enterprise_id\": \"E111\",\n" + + " \"api_app_id\": \"A111\",\n" + + " \"event\": {\n" + + " \"type\": \"tokens_revoked\",\n" + + " \"tokens\": {\n" + + " \"oauth\": [\n" + + " \"W111\"\n" + + " ],\n" + + " \"bot\": []\n" + + " },\n" + + " \"event_ts\": \"1614847360.131900\"\n" + + " },\n" + + " \"type\": \"event_callback\",\n" + + " \"event_id\": \"Ev111\",\n" + + " \"event_time\": 1614847360\n" + + "}"; + + @Test + public void test() { + RequestHeaders headers = new RequestHeaders(new HashMap<>()); + assertThat(new EventRequest(appMentionPayload, headers).getContext().getRequestUserId(), is("UUUUUXXXXX")); + assertThat(new EventRequest(appMentionPayloadWithSubtype, headers).getContext().getRequestUserId(), is(nullValue())); + assertThat(new EventRequest(messagePayload, headers).getContext().getRequestUserId(), is("UUUUUXXXXX")); + assertThat(new EventRequest(appMentionPayloadInSlackConnect, headers).getContext().getRequestUserId(), is("UUUUUXXXXX")); + assertThat(new EventRequest(messagePayloadInSlackConnect, headers).getContext().getRequestUserId(), is("UUUUUXXXXX")); + assertThat(new EventRequest(userTokenRevokedEvent, headers).getContext().getRequestUserId(), is(nullValue())); + } +} From 51a93d73cc8aa78969ecdfa5780148e7ef18aebb Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Fri, 20 Sep 2024 08:43:27 +0900 Subject: [PATCH 3/6] Run all the integration tests - 2024-09-19 PT --- bolt-http4k/pom.xml | 2 +- json-logs/raw/audit/v1/actions.json | 4 +++- json-logs/samples/api/conversations.list.json | 3 +-- json-logs/samples/api/users.list.json | 3 ++- .../src/main/java/com/slack/api/audit/Actions.java | 2 ++ 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/bolt-http4k/pom.xml b/bolt-http4k/pom.xml index 82aa237f0..ea5801814 100644 --- a/bolt-http4k/pom.xml +++ b/bolt-http4k/pom.xml @@ -10,7 +10,7 @@ - 5.30.0.0 + 5.31.0.0 11 11 diff --git a/json-logs/raw/audit/v1/actions.json b/json-logs/raw/audit/v1/actions.json index 450a626ab..8e134cb8d 100644 --- a/json-logs/raw/audit/v1/actions.json +++ b/json-logs/raw/audit/v1/actions.json @@ -380,7 +380,9 @@ "message_activity_viewed", "message_flag_dismissed", "sales_home_notification_forwarded", - "record_shared" + "record_shared", + "message_flag_assignment", + "message_flag_unassignment" ], "barrier": [ "barrier_created", diff --git a/json-logs/samples/api/conversations.list.json b/json-logs/samples/api/conversations.list.json index 18d60b0ca..f638d6632 100644 --- a/json-logs/samples/api/conversations.list.json +++ b/json-logs/samples/api/conversations.list.json @@ -62,8 +62,7 @@ "" ], "user": [ - "W00000000", - "U00000000" + "W00000000" ] }, "threads_restricted_to": { diff --git a/json-logs/samples/api/users.list.json b/json-logs/samples/api/users.list.json index 68123e3d4..6bc3d9727 100644 --- a/json-logs/samples/api/users.list.json +++ b/json-logs/samples/api/users.list.json @@ -75,7 +75,8 @@ "is_admin": false, "is_owner": false, "teams": [ - "" + "", + "T00000000" ], "is_primary_owner": false }, diff --git a/slack-api-client/src/main/java/com/slack/api/audit/Actions.java b/slack-api-client/src/main/java/com/slack/api/audit/Actions.java index 887298088..ef1ea4928 100644 --- a/slack-api-client/src/main/java/com/slack/api/audit/Actions.java +++ b/slack-api-client/src/main/java/com/slack/api/audit/Actions.java @@ -404,6 +404,8 @@ private Message() { public static final String message_flag_dismissed = "message_flag_dismissed"; public static final String sales_home_notification_forwarded = "sales_home_notification_forwarded"; public static final String record_shared = "record_shared"; + public static final String message_flag_assignment = "message_flag_assignment"; + public static final String message_flag_unassignment = "message_flag_unassignment"; } public static class WorkflowBuilder { From 534866871080ba076d532f0f70b5227a52db1922 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Fri, 20 Sep 2024 09:06:58 +0900 Subject: [PATCH 4/6] version 1.43.1 --- bolt-aws-lambda/pom.xml | 4 ++-- bolt-docker-examples/echo-command-app/build.gradle | 2 +- bolt-google-cloud-functions/pom.xml | 4 ++-- bolt-helidon/pom.xml | 4 ++-- bolt-http4k/pom.xml | 4 ++-- bolt-jakarta-jetty/pom.xml | 4 ++-- bolt-jakarta-servlet/pom.xml | 4 ++-- bolt-jakarta-socket-mode/pom.xml | 4 ++-- bolt-jetty/pom.xml | 4 ++-- bolt-kotlin-examples/pom.xml | 4 ++-- bolt-ktor/pom.xml | 4 ++-- bolt-micronaut/pom.xml | 4 ++-- bolt-quarkus-examples/pom.xml | 4 ++-- bolt-servlet/pom.xml | 4 ++-- bolt-socket-mode/pom.xml | 4 ++-- bolt/pom.xml | 4 ++-- .../main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java | 2 +- docs/version-config.yml | 2 +- pom.xml | 2 +- slack-api-client-kotlin-extension/pom.xml | 4 ++-- slack-api-client/pom.xml | 4 ++-- .../java/com/slack/api/meta/SlackApiClientLibraryVersion.java | 2 +- slack-api-model-kotlin-extension/pom.xml | 4 ++-- slack-api-model/pom.xml | 4 ++-- .../java/com/slack/api/meta/SlackApiModelLibraryVersion.java | 2 +- slack-app-backend/pom.xml | 4 ++-- slack-jakarta-socket-mode-client/pom.xml | 4 ++-- 27 files changed, 48 insertions(+), 48 deletions(-) diff --git a/bolt-aws-lambda/pom.xml b/bolt-aws-lambda/pom.xml index 5ce51208a..7ca47f6e0 100644 --- a/bolt-aws-lambda/pom.xml +++ b/bolt-aws-lambda/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -14,7 +14,7 @@ bolt-aws-lambda - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-docker-examples/echo-command-app/build.gradle b/bolt-docker-examples/echo-command-app/build.gradle index 81cee9077..7b380d99b 100644 --- a/bolt-docker-examples/echo-command-app/build.gradle +++ b/bolt-docker-examples/echo-command-app/build.gradle @@ -10,7 +10,7 @@ repositories { dependencies { implementation(platform("org.jetbrains.kotlin:kotlin-bom")) implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") - implementation("com.slack.api:bolt-jetty:1.43.0") + implementation("com.slack.api:bolt-jetty:1.43.1") implementation("ch.qos.logback:logback-classic:1.5.6") implementation('net.logstash.logback:logstash-logback-encoder:7.4') } diff --git a/bolt-google-cloud-functions/pom.xml b/bolt-google-cloud-functions/pom.xml index 46d25b340..a2058e162 100644 --- a/bolt-google-cloud-functions/pom.xml +++ b/bolt-google-cloud-functions/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -17,7 +17,7 @@ bolt-google-cloud-functions - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-helidon/pom.xml b/bolt-helidon/pom.xml index fc92ff563..b962752d1 100644 --- a/bolt-helidon/pom.xml +++ b/bolt-helidon/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -18,7 +18,7 @@ bolt-helidon - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-http4k/pom.xml b/bolt-http4k/pom.xml index ea5801814..34a28d8d2 100644 --- a/bolt-http4k/pom.xml +++ b/bolt-http4k/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -17,7 +17,7 @@ bolt-http4k - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-jakarta-jetty/pom.xml b/bolt-jakarta-jetty/pom.xml index 74f072565..4c281ee63 100644 --- a/bolt-jakarta-jetty/pom.xml +++ b/bolt-jakarta-jetty/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 bolt-jakarta-jetty - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-jakarta-servlet/pom.xml b/bolt-jakarta-servlet/pom.xml index 7527339bc..fd2a2cae5 100644 --- a/bolt-jakarta-servlet/pom.xml +++ b/bolt-jakarta-servlet/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 bolt-jakarta-servlet - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-jakarta-socket-mode/pom.xml b/bolt-jakarta-socket-mode/pom.xml index 8069fcd5c..3192e4ac0 100644 --- a/bolt-jakarta-socket-mode/pom.xml +++ b/bolt-jakarta-socket-mode/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -15,7 +15,7 @@ bolt-jakarta-socket-mode - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-jetty/pom.xml b/bolt-jetty/pom.xml index ab3b75719..1740a9a57 100644 --- a/bolt-jetty/pom.xml +++ b/bolt-jetty/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -14,7 +14,7 @@ bolt-jetty - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-kotlin-examples/pom.xml b/bolt-kotlin-examples/pom.xml index ea7c2f694..dba175b98 100644 --- a/bolt-kotlin-examples/pom.xml +++ b/bolt-kotlin-examples/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 bolt-kotlin-examples - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-ktor/pom.xml b/bolt-ktor/pom.xml index 97179abfe..4f0f4372c 100644 --- a/bolt-ktor/pom.xml +++ b/bolt-ktor/pom.xml @@ -5,11 +5,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 bolt-ktor - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-micronaut/pom.xml b/bolt-micronaut/pom.xml index ec3fe367e..15c418d35 100644 --- a/bolt-micronaut/pom.xml +++ b/bolt-micronaut/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -26,7 +26,7 @@ bolt-micronaut - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-quarkus-examples/pom.xml b/bolt-quarkus-examples/pom.xml index 6c038730b..8b5c2293b 100644 --- a/bolt-quarkus-examples/pom.xml +++ b/bolt-quarkus-examples/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -24,7 +24,7 @@ bolt-quarkus-examples - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-servlet/pom.xml b/bolt-servlet/pom.xml index 9dc31035c..ff8c03707 100644 --- a/bolt-servlet/pom.xml +++ b/bolt-servlet/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -15,7 +15,7 @@ bolt-servlet - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt-socket-mode/pom.xml b/bolt-socket-mode/pom.xml index 5f00d1270..93376c635 100644 --- a/bolt-socket-mode/pom.xml +++ b/bolt-socket-mode/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 @@ -17,7 +17,7 @@ bolt-socket-mode - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt/pom.xml b/bolt/pom.xml index 048d5b67d..d8ee4576c 100644 --- a/bolt/pom.xml +++ b/bolt/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 bolt - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/bolt/src/main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java b/bolt/src/main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java index c514f8d5c..295e6054b 100644 --- a/bolt/src/main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java +++ b/bolt/src/main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java @@ -5,7 +5,7 @@ private BoltLibraryVersion() { } public static final String get() { - return "1.43.1-SNAPSHOT"; + return "1.43.1"; } } diff --git a/docs/version-config.yml b/docs/version-config.yml index f8642d0e1..93cbef76a 100644 --- a/docs/version-config.yml +++ b/docs/version-config.yml @@ -1,4 +1,4 @@ -sdkLatestVersion: 1.43.0 +sdkLatestVersion: 1.43.1 okhttpVersion: 4.10.0 slf4jApiVersion: 1.7.36 kotlinVersion: 1.7.21 diff --git a/pom.xml b/pom.xml index 6df922d92..3677ce803 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 pom Java Slack SDK Project diff --git a/slack-api-client-kotlin-extension/pom.xml b/slack-api-client-kotlin-extension/pom.xml index 891f035bb..1c4967094 100644 --- a/slack-api-client-kotlin-extension/pom.xml +++ b/slack-api-client-kotlin-extension/pom.xml @@ -5,11 +5,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 slack-api-client-kotlin-extension - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/slack-api-client/pom.xml b/slack-api-client/pom.xml index 72368f0d6..df9ad4d06 100644 --- a/slack-api-client/pom.xml +++ b/slack-api-client/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 slack-api-client - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/slack-api-client/src/main/java/com/slack/api/meta/SlackApiClientLibraryVersion.java b/slack-api-client/src/main/java/com/slack/api/meta/SlackApiClientLibraryVersion.java index 12f408077..b2b763f3b 100644 --- a/slack-api-client/src/main/java/com/slack/api/meta/SlackApiClientLibraryVersion.java +++ b/slack-api-client/src/main/java/com/slack/api/meta/SlackApiClientLibraryVersion.java @@ -5,7 +5,7 @@ private SlackApiClientLibraryVersion() { } public static final String get() { - return "1.43.1-SNAPSHOT"; + return "1.43.1"; } } diff --git a/slack-api-model-kotlin-extension/pom.xml b/slack-api-model-kotlin-extension/pom.xml index 6e56fc78e..60a59dbf2 100644 --- a/slack-api-model-kotlin-extension/pom.xml +++ b/slack-api-model-kotlin-extension/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 slack-api-model-kotlin-extension - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/slack-api-model/pom.xml b/slack-api-model/pom.xml index aa0acc593..a3ac1fcc1 100644 --- a/slack-api-model/pom.xml +++ b/slack-api-model/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 slack-api-model - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/slack-api-model/src/main/java/com/slack/api/meta/SlackApiModelLibraryVersion.java b/slack-api-model/src/main/java/com/slack/api/meta/SlackApiModelLibraryVersion.java index cfb4301d6..582026417 100644 --- a/slack-api-model/src/main/java/com/slack/api/meta/SlackApiModelLibraryVersion.java +++ b/slack-api-model/src/main/java/com/slack/api/meta/SlackApiModelLibraryVersion.java @@ -5,7 +5,7 @@ private SlackApiModelLibraryVersion() { } public static final String get() { - return "1.43.1-SNAPSHOT"; + return "1.43.1"; } } diff --git a/slack-app-backend/pom.xml b/slack-app-backend/pom.xml index f2b44cef9..a62a5392d 100644 --- a/slack-app-backend/pom.xml +++ b/slack-app-backend/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 slack-app-backend - 1.43.1-SNAPSHOT + 1.43.1 jar diff --git a/slack-jakarta-socket-mode-client/pom.xml b/slack-jakarta-socket-mode-client/pom.xml index f5e1caa93..272fb1441 100644 --- a/slack-jakarta-socket-mode-client/pom.xml +++ b/slack-jakarta-socket-mode-client/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1-SNAPSHOT + 1.43.1 slack-jakarta-socket-mode-client - 1.43.1-SNAPSHOT + 1.43.1 jar From e5565e70e089206a6c4eef840a6c02b00653a74c Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Fri, 20 Sep 2024 09:07:28 +0900 Subject: [PATCH 5/6] Start new version --- bolt-aws-lambda/pom.xml | 4 ++-- bolt-google-cloud-functions/pom.xml | 4 ++-- bolt-helidon/pom.xml | 4 ++-- bolt-http4k/pom.xml | 4 ++-- bolt-jakarta-jetty/pom.xml | 4 ++-- bolt-jakarta-servlet/pom.xml | 4 ++-- bolt-jakarta-socket-mode/pom.xml | 4 ++-- bolt-jetty/pom.xml | 4 ++-- bolt-kotlin-examples/pom.xml | 4 ++-- bolt-ktor/pom.xml | 4 ++-- bolt-micronaut/pom.xml | 4 ++-- bolt-quarkus-examples/pom.xml | 4 ++-- bolt-servlet/pom.xml | 4 ++-- bolt-socket-mode/pom.xml | 4 ++-- bolt/pom.xml | 4 ++-- .../main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java | 2 +- pom.xml | 2 +- slack-api-client-kotlin-extension/pom.xml | 4 ++-- slack-api-client/pom.xml | 4 ++-- .../java/com/slack/api/meta/SlackApiClientLibraryVersion.java | 2 +- slack-api-model-kotlin-extension/pom.xml | 4 ++-- slack-api-model/pom.xml | 4 ++-- .../java/com/slack/api/meta/SlackApiModelLibraryVersion.java | 2 +- slack-app-backend/pom.xml | 4 ++-- slack-jakarta-socket-mode-client/pom.xml | 4 ++-- 25 files changed, 46 insertions(+), 46 deletions(-) diff --git a/bolt-aws-lambda/pom.xml b/bolt-aws-lambda/pom.xml index 7ca47f6e0..a2952a64f 100644 --- a/bolt-aws-lambda/pom.xml +++ b/bolt-aws-lambda/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -14,7 +14,7 @@ bolt-aws-lambda - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-google-cloud-functions/pom.xml b/bolt-google-cloud-functions/pom.xml index a2058e162..5cca86ca3 100644 --- a/bolt-google-cloud-functions/pom.xml +++ b/bolt-google-cloud-functions/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -17,7 +17,7 @@ bolt-google-cloud-functions - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-helidon/pom.xml b/bolt-helidon/pom.xml index b962752d1..da36bbea0 100644 --- a/bolt-helidon/pom.xml +++ b/bolt-helidon/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -18,7 +18,7 @@ bolt-helidon - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-http4k/pom.xml b/bolt-http4k/pom.xml index 34a28d8d2..911a817fd 100644 --- a/bolt-http4k/pom.xml +++ b/bolt-http4k/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -17,7 +17,7 @@ bolt-http4k - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-jakarta-jetty/pom.xml b/bolt-jakarta-jetty/pom.xml index 4c281ee63..6dfb019f4 100644 --- a/bolt-jakarta-jetty/pom.xml +++ b/bolt-jakarta-jetty/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT bolt-jakarta-jetty - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-jakarta-servlet/pom.xml b/bolt-jakarta-servlet/pom.xml index fd2a2cae5..40e7e78bc 100644 --- a/bolt-jakarta-servlet/pom.xml +++ b/bolt-jakarta-servlet/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT bolt-jakarta-servlet - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-jakarta-socket-mode/pom.xml b/bolt-jakarta-socket-mode/pom.xml index 3192e4ac0..76d7cd136 100644 --- a/bolt-jakarta-socket-mode/pom.xml +++ b/bolt-jakarta-socket-mode/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -15,7 +15,7 @@ bolt-jakarta-socket-mode - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-jetty/pom.xml b/bolt-jetty/pom.xml index 1740a9a57..a8642ded7 100644 --- a/bolt-jetty/pom.xml +++ b/bolt-jetty/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -14,7 +14,7 @@ bolt-jetty - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-kotlin-examples/pom.xml b/bolt-kotlin-examples/pom.xml index dba175b98..6f6f0bb40 100644 --- a/bolt-kotlin-examples/pom.xml +++ b/bolt-kotlin-examples/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT bolt-kotlin-examples - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-ktor/pom.xml b/bolt-ktor/pom.xml index 4f0f4372c..28b316274 100644 --- a/bolt-ktor/pom.xml +++ b/bolt-ktor/pom.xml @@ -5,11 +5,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT bolt-ktor - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-micronaut/pom.xml b/bolt-micronaut/pom.xml index 15c418d35..691f5ab5c 100644 --- a/bolt-micronaut/pom.xml +++ b/bolt-micronaut/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -26,7 +26,7 @@ bolt-micronaut - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-quarkus-examples/pom.xml b/bolt-quarkus-examples/pom.xml index 8b5c2293b..a97adba58 100644 --- a/bolt-quarkus-examples/pom.xml +++ b/bolt-quarkus-examples/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -24,7 +24,7 @@ bolt-quarkus-examples - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-servlet/pom.xml b/bolt-servlet/pom.xml index ff8c03707..bcd27d8d6 100644 --- a/bolt-servlet/pom.xml +++ b/bolt-servlet/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -15,7 +15,7 @@ bolt-servlet - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt-socket-mode/pom.xml b/bolt-socket-mode/pom.xml index 93376c635..c3bfd339f 100644 --- a/bolt-socket-mode/pom.xml +++ b/bolt-socket-mode/pom.xml @@ -6,7 +6,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT @@ -17,7 +17,7 @@ bolt-socket-mode - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt/pom.xml b/bolt/pom.xml index d8ee4576c..2434d8173 100644 --- a/bolt/pom.xml +++ b/bolt/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT bolt - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/bolt/src/main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java b/bolt/src/main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java index 295e6054b..d77c4b066 100644 --- a/bolt/src/main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java +++ b/bolt/src/main/java/com/slack/api/bolt/meta/BoltLibraryVersion.java @@ -5,7 +5,7 @@ private BoltLibraryVersion() { } public static final String get() { - return "1.43.1"; + return "1.44.0-SNAPSHOT"; } } diff --git a/pom.xml b/pom.xml index 3677ce803..687e49add 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT pom Java Slack SDK Project diff --git a/slack-api-client-kotlin-extension/pom.xml b/slack-api-client-kotlin-extension/pom.xml index 1c4967094..9e63795cd 100644 --- a/slack-api-client-kotlin-extension/pom.xml +++ b/slack-api-client-kotlin-extension/pom.xml @@ -5,11 +5,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT slack-api-client-kotlin-extension - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/slack-api-client/pom.xml b/slack-api-client/pom.xml index df9ad4d06..d2699f10c 100644 --- a/slack-api-client/pom.xml +++ b/slack-api-client/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT slack-api-client - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/slack-api-client/src/main/java/com/slack/api/meta/SlackApiClientLibraryVersion.java b/slack-api-client/src/main/java/com/slack/api/meta/SlackApiClientLibraryVersion.java index b2b763f3b..5ec2daca7 100644 --- a/slack-api-client/src/main/java/com/slack/api/meta/SlackApiClientLibraryVersion.java +++ b/slack-api-client/src/main/java/com/slack/api/meta/SlackApiClientLibraryVersion.java @@ -5,7 +5,7 @@ private SlackApiClientLibraryVersion() { } public static final String get() { - return "1.43.1"; + return "1.44.0-SNAPSHOT"; } } diff --git a/slack-api-model-kotlin-extension/pom.xml b/slack-api-model-kotlin-extension/pom.xml index 60a59dbf2..3c9944ccc 100644 --- a/slack-api-model-kotlin-extension/pom.xml +++ b/slack-api-model-kotlin-extension/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT slack-api-model-kotlin-extension - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/slack-api-model/pom.xml b/slack-api-model/pom.xml index a3ac1fcc1..945457d26 100644 --- a/slack-api-model/pom.xml +++ b/slack-api-model/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT slack-api-model - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/slack-api-model/src/main/java/com/slack/api/meta/SlackApiModelLibraryVersion.java b/slack-api-model/src/main/java/com/slack/api/meta/SlackApiModelLibraryVersion.java index 582026417..0f3a2b61f 100644 --- a/slack-api-model/src/main/java/com/slack/api/meta/SlackApiModelLibraryVersion.java +++ b/slack-api-model/src/main/java/com/slack/api/meta/SlackApiModelLibraryVersion.java @@ -5,7 +5,7 @@ private SlackApiModelLibraryVersion() { } public static final String get() { - return "1.43.1"; + return "1.44.0-SNAPSHOT"; } } diff --git a/slack-app-backend/pom.xml b/slack-app-backend/pom.xml index a62a5392d..b292fafe6 100644 --- a/slack-app-backend/pom.xml +++ b/slack-app-backend/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT slack-app-backend - 1.43.1 + 1.44.0-SNAPSHOT jar diff --git a/slack-jakarta-socket-mode-client/pom.xml b/slack-jakarta-socket-mode-client/pom.xml index 272fb1441..96b7ed2a1 100644 --- a/slack-jakarta-socket-mode-client/pom.xml +++ b/slack-jakarta-socket-mode-client/pom.xml @@ -6,11 +6,11 @@ com.slack.api slack-sdk-parent - 1.43.1 + 1.44.0-SNAPSHOT slack-jakarta-socket-mode-client - 1.43.1 + 1.44.0-SNAPSHOT jar From c442278789d3b22759f9d8fd8c1d238cf9f92702 Mon Sep 17 00:00:00 2001 From: Hyeonmin Park Date: Fri, 20 Sep 2024 10:02:39 +0900 Subject: [PATCH 6/6] Add RichTextBlock support to Block Kit Kotlin DSL builder (#1376) Co-authored-by: Kazuhiro Sera --- json-logs/samples/api/views.open.json | 15 +- json-logs/samples/api/views.publish.json | 15 +- json-logs/samples/api/views.push.json | 15 +- json-logs/samples/api/views.update.json | 15 +- .../block/RichTextBlockBuilder.kt | 43 ++ .../container/MultiRichTextObjectContainer.kt | 81 +++ .../composition/dsl/RichTextObjectDsl.kt | 75 +++ .../container/MultiLayoutBlockContainer.kt | 6 +- .../block/dsl/LayoutBlockDsl.kt | 10 + .../block/element/BroadcastRange.kt | 26 + .../block/element/ListStyle.kt | 13 + .../element/RichTextListElementBuilder.kt | 75 +++ .../RichTextPreformattedElementBuilder.kt | 41 ++ .../element/RichTextQuoteElementBuilder.kt | 41 ++ .../element/RichTextSectionElementBuilder.kt | 29 + .../MultiRichTextElementContainer.kt | 31 + .../MultiRichTextSectionElementContainer.kt | 16 + .../block/element/dsl/RichTextElementDsl.kt | 20 + .../element/dsl/RichTextListElementDsl.kt | 11 + .../test_locally/block/RichTextBlockTest.kt | 580 ++++++++++++++++++ .../validation/BlockBuilderValidationTest.kt | 7 +- .../BlockElementBuilderValidationTest.kt | 22 +- .../block/element/RichTextQuoteElement.java | 1 + 23 files changed, 1165 insertions(+), 23 deletions(-) create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/RichTextBlockBuilder.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/composition/container/MultiRichTextObjectContainer.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/composition/dsl/RichTextObjectDsl.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/BroadcastRange.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/ListStyle.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextListElementBuilder.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextPreformattedElementBuilder.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextQuoteElementBuilder.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextSectionElementBuilder.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/container/MultiRichTextElementContainer.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/container/MultiRichTextSectionElementContainer.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/dsl/RichTextElementDsl.kt create mode 100644 slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/dsl/RichTextListElementDsl.kt create mode 100644 slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/RichTextBlockTest.kt diff --git a/json-logs/samples/api/views.open.json b/json-logs/samples/api/views.open.json index 7431d33f6..a38a4ac55 100644 --- a/json-logs/samples/api/views.open.json +++ b/json-logs/samples/api/views.open.json @@ -449,7 +449,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1003,7 +1004,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1554,7 +1556,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1691,7 +1694,8 @@ } ] } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -2104,7 +2108,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", diff --git a/json-logs/samples/api/views.publish.json b/json-logs/samples/api/views.publish.json index 7431d33f6..a38a4ac55 100644 --- a/json-logs/samples/api/views.publish.json +++ b/json-logs/samples/api/views.publish.json @@ -449,7 +449,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1003,7 +1004,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1554,7 +1556,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1691,7 +1694,8 @@ } ] } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -2104,7 +2108,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", diff --git a/json-logs/samples/api/views.push.json b/json-logs/samples/api/views.push.json index 7431d33f6..a38a4ac55 100644 --- a/json-logs/samples/api/views.push.json +++ b/json-logs/samples/api/views.push.json @@ -449,7 +449,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1003,7 +1004,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1554,7 +1556,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1691,7 +1694,8 @@ } ] } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -2104,7 +2108,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", diff --git a/json-logs/samples/api/views.update.json b/json-logs/samples/api/views.update.json index 7431d33f6..a38a4ac55 100644 --- a/json-logs/samples/api/views.update.json +++ b/json-logs/samples/api/views.update.json @@ -449,7 +449,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1003,7 +1004,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1554,7 +1556,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -1691,7 +1694,8 @@ } ] } - ] + ], + "border": 123 }, { "type": "rich_text_section", @@ -2104,7 +2108,8 @@ }, "unicode": "" } - ] + ], + "border": 123 }, { "type": "rich_text_section", diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/RichTextBlockBuilder.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/RichTextBlockBuilder.kt new file mode 100644 index 000000000..8b2ea131f --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/RichTextBlockBuilder.kt @@ -0,0 +1,43 @@ +package com.slack.api.model.kotlin_extension.block + +import com.slack.api.model.block.RichTextBlock +import com.slack.api.model.kotlin_extension.block.element.container.MultiRichTextElementContainer +import com.slack.api.model.kotlin_extension.block.element.dsl.RichTextElementDsl + +@BlockLayoutBuilder +class RichTextBlockBuilder private constructor( + private val elementsContainer: MultiRichTextElementContainer +) : Builder, RichTextElementDsl by elementsContainer { + private var blockId: String? = null + + constructor() : this(MultiRichTextElementContainer()) + + /** + * A string acting as a unique identifier for a block. You can use this `block_id` when you receive an interaction + * payload to identify the source of the action. 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`. + * + * @see Rich text block documentation + */ + fun blockId(id: String) { + blockId = id + } + + /** + * An array of rich text objects - `rich_text_section`, `rich_text_list`, `rich_text_preformatted`, + * and `rich_text_quote`. + * + * @see Rich text block documentation + */ + fun elements(builder: RichTextElementDsl.() -> Unit) { + elementsContainer.apply(builder) + } + + override fun build(): RichTextBlock { + return RichTextBlock.builder() + .blockId(blockId) + .elements(elementsContainer.underlying) + .build() + } +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/composition/container/MultiRichTextObjectContainer.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/composition/container/MultiRichTextObjectContainer.kt new file mode 100644 index 000000000..5330cd72a --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/composition/container/MultiRichTextObjectContainer.kt @@ -0,0 +1,81 @@ +package com.slack.api.model.kotlin_extension.block.composition.container + +import com.slack.api.model.block.element.RichTextElement +import com.slack.api.model.block.element.RichTextSectionElement +import com.slack.api.model.block.element.RichTextSectionElement.LimitedTextStyle +import com.slack.api.model.block.element.RichTextSectionElement.TextStyle +import com.slack.api.model.kotlin_extension.block.composition.dsl.RichTextObjectDsl +import com.slack.api.model.kotlin_extension.block.element.BroadcastRange + +class MultiRichTextObjectContainer : RichTextObjectDsl { + val underlying = mutableListOf() + + override fun broadcast(range: BroadcastRange, style: LimitedTextStyle?) { + underlying += RichTextSectionElement.Broadcast.builder() + .range(range.value) + .style(style) + .build() + } + + override fun color(value: String, style: LimitedTextStyle?) { + underlying += RichTextSectionElement.Color.builder() + .value(value) + .style(style) + .build() + } + + override fun channel(channelId: String, style: LimitedTextStyle?) { + underlying += RichTextSectionElement.Channel.builder() + .channelId(channelId) + .style(style) + .build() + } + + override fun date(timestamp: Int, format: String, style: TextStyle?, url: String?, fallback: String?) { + underlying += RichTextSectionElement.Date.builder() + .timestamp(timestamp) + .format(format) + .style(style) + .url(url) + .fallback(fallback) + .build() + } + + override fun emoji(name: String, skinTone: Int?, style: LimitedTextStyle?) { + underlying += RichTextSectionElement.Emoji.builder() + .name(name) + .skinTone(skinTone) + .style(style) + .build() + } + + override fun link(url: String, text: String?, unsafe: Boolean?, style: TextStyle?) { + underlying += RichTextSectionElement.Link.builder() + .url(url) + .text(text) + .unsafe(unsafe) + .style(style) + .build() + } + + override fun text(text: String, style: TextStyle?) { + underlying += RichTextSectionElement.Text.builder() + .text(text) + .style(style) + .build() + } + + override fun user(userId: String, style: LimitedTextStyle?) { + underlying += RichTextSectionElement.User.builder() + .userId(userId) + .style(style) + .build() + } + + override fun usergroup(usergroupId: String, style: LimitedTextStyle?) { + underlying += RichTextSectionElement.UserGroup.builder() + .usergroupId(usergroupId) + .style(style) + .build() + } +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/composition/dsl/RichTextObjectDsl.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/composition/dsl/RichTextObjectDsl.kt new file mode 100644 index 000000000..14096623a --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/composition/dsl/RichTextObjectDsl.kt @@ -0,0 +1,75 @@ +package com.slack.api.model.kotlin_extension.block.composition.dsl + +import com.slack.api.model.block.element.RichTextSectionElement.LimitedTextStyle +import com.slack.api.model.block.element.RichTextSectionElement.TextStyle +import com.slack.api.model.kotlin_extension.block.BlockLayoutBuilder +import com.slack.api.model.kotlin_extension.block.element.BroadcastRange + +@BlockLayoutBuilder +interface RichTextObjectDsl { + + /** + * @param range The range of the broadcast. + * @see Rich text object documentation + */ + fun broadcast(range: BroadcastRange, style: LimitedTextStyle? = null) + + /** + * @param value The hex value for the color. + * @see Rich text object documentation + */ + fun color(value: String, style: LimitedTextStyle? = null) + + /** + * @param channelId The ID of the channel to be mentioned. + * @param style An object of six optional boolean properties that dictate style: bold, italic, strike, highlight, client_highlight, and unlink. + * @see Rich text object documentation + */ + fun channel(channelId: String, style: LimitedTextStyle? = null) + + /** + * @param timestamp A Unix timestamp for the date to be displayed in seconds. + * @param format A template string containing curly-brace-enclosed tokens to substitute your provided timestamp. + * @param url URL to link the entire format string to. + * @param fallback Text to display in place of the date should parsing, formatting or displaying fail. + * @see Rich text object documentation + */ + fun date(timestamp: Int, format: String, style: TextStyle? = null, url: String? = null, fallback: String? = null) + + /** + * @param name The name of the emoji; i.e. "wave" or "wave::skin-tone-2". + * @see Rich text object documentation + */ + fun emoji(name: String, skinTone: Int? = null, style: LimitedTextStyle? = null) + + /** + * @param url The link's url. + * @param text The text shown to the user (instead of the url). If no text is provided, the url is used. + * @param unsafe Indicates whether the link is safe. + * @param style An object containing four boolean properties: bold, italic, strike, and code. + * @see Rich text object documentation + */ + fun link(url: String, text: String? = null, unsafe: Boolean? = null, style: TextStyle? = null) + + /** + * @param text The text shown to the user. + * @param style An object containing four boolean fields, none of which are required: bold, italic, strike, and code. + * @see Rich text object documentation + */ + fun text(text: String, style: TextStyle? = null) + + /** + * @param userId The ID of the user to be mentioned. + * @param style An object of six optional boolean properties that dictate style: bold, italic, strike, highlight, client_highlight, and unlink. + * @see Rich text object documentation + */ + fun user(userId: String, style: LimitedTextStyle? = null) + + /** + * @param usergroupId The ID of the user group to be mentioned. + * @param style An object of six optional boolean properties that dictate style: bold, italic, strike, highlight, client_highlight, and unlink. + * @see Rich text object documentation + */ + fun usergroup(usergroupId: String, style: LimitedTextStyle? = null) + +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/container/MultiLayoutBlockContainer.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/container/MultiLayoutBlockContainer.kt index 4eb7f83f2..9f35b0c67 100644 --- a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/container/MultiLayoutBlockContainer.kt +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/container/MultiLayoutBlockContainer.kt @@ -56,6 +56,10 @@ class MultiLayoutBlockContainer : LayoutBlockDsl { underlying += InputBlockBuilder().apply(builder).build() } + override fun richText(builder: RichTextBlockBuilder.() -> Unit) { + underlying += RichTextBlockBuilder().apply(builder).build() + } + override fun video(builder: VideoBlockBuilder.() -> Unit) { underlying += VideoBlockBuilder().apply(builder).build() } @@ -63,4 +67,4 @@ class MultiLayoutBlockContainer : LayoutBlockDsl { override fun shareShortcut(builder: ShareShortcutBlockBuilder.() -> Unit) { underlying += ShareShortcutBlockBuilder().apply(builder).build() } -} \ No newline at end of file +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/dsl/LayoutBlockDsl.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/dsl/LayoutBlockDsl.kt index 9b8dbea41..32479bf1a 100644 --- a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/dsl/LayoutBlockDsl.kt +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/dsl/LayoutBlockDsl.kt @@ -73,6 +73,16 @@ interface LayoutBlockDsl { */ fun input(builder: InputBlockBuilder.() -> Unit) + /** + * Displays formatted, structured representation of text. It is also the output of the Slack client's WYSIWYG + * message composer, so all messages sent by end-users will have this format. Use this block to include user-defined + * formatted text in your Block Kit payload. While it is possible to format text with mrkdwn, rich_text is + * strongly preferred and allows greater flexibility. + * + * @see Rich text documentation + */ + fun richText(builder: RichTextBlockBuilder.() -> Unit) + /** * A video block is designed to embed videos in all app surfaces (e.g. link unfurls, messages, modals, App Home) * — anywhere you can put blocks! To use the video block within your app, you must have the links.embed:write scope. diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/BroadcastRange.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/BroadcastRange.kt new file mode 100644 index 000000000..11d66dae7 --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/BroadcastRange.kt @@ -0,0 +1,26 @@ +package com.slack.api.model.kotlin_extension.block.element + +enum class BroadcastRange { + /** + * Notifies only the active members of a channel. + */ + HERE { + override val value = "here" + }, + + /** + * Notifies all members of a channel. + */ + CHANNEL { + override val value = "channel" + }, + + /** + * Notifies every person in the #general channel. + */ + EVERYONE { + override val value = "everyone" + }; + + abstract val value: String +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/ListStyle.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/ListStyle.kt new file mode 100644 index 000000000..126c23cb7 --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/ListStyle.kt @@ -0,0 +1,13 @@ +package com.slack.api.model.kotlin_extension.block.element + +enum class ListStyle { + BULLET { + override val value = "bullet" + }, + + ORDERED { + override val value = "ordered" + }; + + abstract val value: String +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextListElementBuilder.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextListElementBuilder.kt new file mode 100644 index 000000000..b2d7052d2 --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextListElementBuilder.kt @@ -0,0 +1,75 @@ +package com.slack.api.model.kotlin_extension.block.element + +import com.slack.api.model.block.element.RichTextListElement +import com.slack.api.model.kotlin_extension.block.BlockLayoutBuilder +import com.slack.api.model.kotlin_extension.block.Builder +import com.slack.api.model.kotlin_extension.block.element.container.MultiRichTextSectionElementContainer +import com.slack.api.model.kotlin_extension.block.element.dsl.RichTextListElementDsl + +@BlockLayoutBuilder +class RichTextListElementBuilder private constructor( + private val elementsContainer: MultiRichTextSectionElementContainer +) : Builder, RichTextListElementDsl by elementsContainer { + private var style: String? = null + private var indent: Int? = null + private var offset: Int? = null + private var border: Int? = null + + constructor() : this(MultiRichTextSectionElementContainer()) + + /** + * Either bullet or ordered, the latter meaning a numbered list. + * + * @see Rich text list element documentation + */ + fun style(style: ListStyle) { + this.style = style.value + } + + /** + * An array of rich_text_section objects containing two properties: type, which is "rich_text_section", + * and elements, which is an array of rich text element objects. + * + * @see Rich text list element documentation + */ + fun elements(builder: RichTextListElementDsl.() -> Unit) { + elementsContainer.apply(builder) + } + + /** + * Number of pixels to indent the list. + * + * @see Rich text list element documentation + */ + fun indent(indent: Int) { + this.indent = indent + } + + /** + * Number of pixels to offset the list. + * + * @see Rich text list element documentation + */ + fun offset(offset: Int) { + this.offset = offset + } + + /** + * Number of pixels of border thickness. + * + * @see Rich text list element documentation + */ + fun border(border: Int) { + this.border = border + } + + override fun build(): RichTextListElement { + return RichTextListElement.builder() + .style(style) + .elements(elementsContainer.underlying) + .indent(indent) + .offset(offset) + .border(border) + .build() + } +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextPreformattedElementBuilder.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextPreformattedElementBuilder.kt new file mode 100644 index 000000000..4794c19d6 --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextPreformattedElementBuilder.kt @@ -0,0 +1,41 @@ +package com.slack.api.model.kotlin_extension.block.element + +import com.slack.api.model.block.element.RichTextPreformattedElement +import com.slack.api.model.kotlin_extension.block.BlockLayoutBuilder +import com.slack.api.model.kotlin_extension.block.Builder +import com.slack.api.model.kotlin_extension.block.composition.container.MultiRichTextObjectContainer +import com.slack.api.model.kotlin_extension.block.composition.dsl.RichTextObjectDsl + +@BlockLayoutBuilder +class RichTextPreformattedElementBuilder private constructor( + private val elementsContainer: MultiRichTextObjectContainer +) : Builder, RichTextObjectDsl by elementsContainer { + private var border: Int? = null + + constructor() : this(MultiRichTextObjectContainer()) + + /** + * An array of rich text elements. + * + * @see Rich text preformatted element documentation + */ + fun elements(builder: RichTextObjectDsl.() -> Unit) { + elementsContainer.apply(builder) + } + + /** + * Number of pixels of border thickness. + * + * @see Rich text preformatted element documentation + */ + fun border(border: Int) { + this.border = border + } + + override fun build(): RichTextPreformattedElement { + return RichTextPreformattedElement.builder() + .elements(elementsContainer.underlying) + .border(border) + .build() + } +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextQuoteElementBuilder.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextQuoteElementBuilder.kt new file mode 100644 index 000000000..d3aa50b8a --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextQuoteElementBuilder.kt @@ -0,0 +1,41 @@ +package com.slack.api.model.kotlin_extension.block.element + +import com.slack.api.model.block.element.RichTextQuoteElement +import com.slack.api.model.kotlin_extension.block.BlockLayoutBuilder +import com.slack.api.model.kotlin_extension.block.Builder +import com.slack.api.model.kotlin_extension.block.composition.container.MultiRichTextObjectContainer +import com.slack.api.model.kotlin_extension.block.composition.dsl.RichTextObjectDsl + +@BlockLayoutBuilder +class RichTextQuoteElementBuilder private constructor( + private val elementsContainer: MultiRichTextObjectContainer +) : Builder, RichTextObjectDsl by elementsContainer { + private var border: Int? = null + + constructor() : this(MultiRichTextObjectContainer()) + + /** + * An array of rich text elements. + * + * @see Rich text quote element documentation + */ + fun elements(builder: RichTextObjectDsl.() -> Unit) { + elementsContainer.apply(builder) + } + + /** + * Number of pixels of border thickness. + * + * @see Rich text quote element documentation + */ + fun border(border: Int) { + this.border = border + } + + override fun build(): RichTextQuoteElement { + return RichTextQuoteElement.builder() + .elements(elementsContainer.underlying) + .border(border) + .build() + } +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextSectionElementBuilder.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextSectionElementBuilder.kt new file mode 100644 index 000000000..0d5795c36 --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/RichTextSectionElementBuilder.kt @@ -0,0 +1,29 @@ +package com.slack.api.model.kotlin_extension.block.element + +import com.slack.api.model.block.element.RichTextSectionElement +import com.slack.api.model.kotlin_extension.block.BlockLayoutBuilder +import com.slack.api.model.kotlin_extension.block.Builder +import com.slack.api.model.kotlin_extension.block.composition.container.MultiRichTextObjectContainer +import com.slack.api.model.kotlin_extension.block.composition.dsl.RichTextObjectDsl + +@BlockLayoutBuilder +class RichTextSectionElementBuilder private constructor( + private val elementsContainer: MultiRichTextObjectContainer +) : Builder, RichTextObjectDsl by elementsContainer { + constructor() : this(MultiRichTextObjectContainer()) + + /** + * An array of rich text elements. + * + * @see Rich text section element documentation + */ + fun elements(builder: RichTextObjectDsl.() -> Unit) { + elementsContainer.apply(builder) + } + + override fun build(): RichTextSectionElement { + return RichTextSectionElement.builder() + .elements(elementsContainer.underlying) + .build() + } +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/container/MultiRichTextElementContainer.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/container/MultiRichTextElementContainer.kt new file mode 100644 index 000000000..32851ec02 --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/container/MultiRichTextElementContainer.kt @@ -0,0 +1,31 @@ +package com.slack.api.model.kotlin_extension.block.element.container + +import com.slack.api.model.block.element.BlockElement +import com.slack.api.model.kotlin_extension.block.element.RichTextListElementBuilder +import com.slack.api.model.kotlin_extension.block.element.RichTextPreformattedElementBuilder +import com.slack.api.model.kotlin_extension.block.element.RichTextQuoteElementBuilder +import com.slack.api.model.kotlin_extension.block.element.RichTextSectionElementBuilder +import com.slack.api.model.kotlin_extension.block.element.dsl.RichTextElementDsl + +/** + * Supports a RichTextElementContainer that can hold one to many rich text elements + */ +class MultiRichTextElementContainer : RichTextElementDsl { + val underlying = mutableListOf() + + override fun richTextSection(builder: RichTextSectionElementBuilder.() -> Unit) { + underlying += RichTextSectionElementBuilder().apply(builder).build() + } + + override fun richTextList(builder: RichTextListElementBuilder.() -> Unit) { + underlying += RichTextListElementBuilder().apply(builder).build() + } + + override fun richTextPreformatted(builder: RichTextPreformattedElementBuilder.() -> Unit) { + underlying += RichTextPreformattedElementBuilder().apply(builder).build() + } + + override fun richTextQuote(builder: RichTextQuoteElementBuilder.() -> Unit) { + underlying += RichTextQuoteElementBuilder().apply(builder).build() + } +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/container/MultiRichTextSectionElementContainer.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/container/MultiRichTextSectionElementContainer.kt new file mode 100644 index 000000000..1ce8453da --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/container/MultiRichTextSectionElementContainer.kt @@ -0,0 +1,16 @@ +package com.slack.api.model.kotlin_extension.block.element.container + +import com.slack.api.model.block.element.RichTextElement +import com.slack.api.model.kotlin_extension.block.element.RichTextSectionElementBuilder +import com.slack.api.model.kotlin_extension.block.element.dsl.RichTextListElementDsl + +/** + * Supports a RichTextSectionElementContainer that can hold one to many rich text section elements + */ +class MultiRichTextSectionElementContainer : RichTextListElementDsl { + val underlying = mutableListOf() + + override fun richTextSection(builder: RichTextSectionElementBuilder.() -> Unit) { + underlying += RichTextSectionElementBuilder().apply(builder).build() + } +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/dsl/RichTextElementDsl.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/dsl/RichTextElementDsl.kt new file mode 100644 index 000000000..8b9517d34 --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/dsl/RichTextElementDsl.kt @@ -0,0 +1,20 @@ +package com.slack.api.model.kotlin_extension.block.element.dsl + +import com.slack.api.model.kotlin_extension.block.BlockLayoutBuilder +import com.slack.api.model.kotlin_extension.block.element.RichTextListElementBuilder +import com.slack.api.model.kotlin_extension.block.element.RichTextPreformattedElementBuilder +import com.slack.api.model.kotlin_extension.block.element.RichTextQuoteElementBuilder +import com.slack.api.model.kotlin_extension.block.element.RichTextSectionElementBuilder + +@BlockLayoutBuilder +interface RichTextElementDsl { + + fun richTextSection(builder: RichTextSectionElementBuilder.() -> Unit) + + fun richTextList(builder: RichTextListElementBuilder.() -> Unit) + + fun richTextPreformatted(builder: RichTextPreformattedElementBuilder.() -> Unit) + + fun richTextQuote(builder: RichTextQuoteElementBuilder.() -> Unit) + +} diff --git a/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/dsl/RichTextListElementDsl.kt b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/dsl/RichTextListElementDsl.kt new file mode 100644 index 000000000..c7e094cc5 --- /dev/null +++ b/slack-api-model-kotlin-extension/src/main/kotlin/com/slack/api/model/kotlin_extension/block/element/dsl/RichTextListElementDsl.kt @@ -0,0 +1,11 @@ +package com.slack.api.model.kotlin_extension.block.element.dsl + +import com.slack.api.model.kotlin_extension.block.BlockLayoutBuilder +import com.slack.api.model.kotlin_extension.block.element.RichTextSectionElementBuilder + +@BlockLayoutBuilder +interface RichTextListElementDsl { + + fun richTextSection(builder: RichTextSectionElementBuilder.() -> Unit) + +} diff --git a/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/RichTextBlockTest.kt b/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/RichTextBlockTest.kt new file mode 100644 index 000000000..49551853e --- /dev/null +++ b/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/RichTextBlockTest.kt @@ -0,0 +1,580 @@ +package test_locally.block + +import com.google.gson.JsonElement +import com.slack.api.SlackConfig +import com.slack.api.model.block.element.RichTextSectionElement.LimitedTextStyle +import com.slack.api.model.block.element.RichTextSectionElement.TextStyle +import com.slack.api.model.kotlin_extension.block.element.BroadcastRange +import com.slack.api.model.kotlin_extension.block.element.ListStyle +import com.slack.api.model.kotlin_extension.block.withBlocks +import com.slack.api.util.json.GsonFactory +import org.junit.Test +import kotlin.test.assertEquals + +class RichTextBlockTest { + + val gson = GsonFactory.createSnakeCase(SlackConfig().apply { isPrettyResponseLoggingEnabled = true }) // FIXME + + @Test + fun kitchenSink() { + val blocks = withBlocks { + richText { + richTextSection { + text("Check out these different block types with paragraph breaks between them:\n\n") + } + richTextPreformatted { + text("Hello there, I am preformatted block!\n\nI can have multiple paragraph breaks within the block.") + } + richTextSection { + text("\nI am rich text with a paragraph break following preformatted text. \n\nI can have multiple paragraph breaks within the block.\n\n") + } + richTextQuote { + text("I am a basic rich text quote, \n\nI can have multiple paragraph breaks within the block.") + } + richTextSection { + text("\nI am rich text with a paragraph after the quote block\n\n") + } + richTextQuote { + text("I am a basic quote block following rich text") + } + richTextSection { + text("\n") + } + richTextPreformatted { + text("I am more preformatted text following a quote block") + } + richTextSection { + text("\n") + } + richTextQuote { + text("I am a basic quote block following preformatted text") + } + richTextSection { + text("\n") + } + richTextList { + style(ListStyle.BULLET) + richTextSection { + text("list item one") + } + richTextSection { + text("list item two") + } + } + richTextSection { + text("\nI am rich text with a paragraph break after a list") + } + } + } + val original = """ +{ + "blocks": [ + { + "type": "rich_text", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "Check out these different block types with paragraph breaks between them:\n\n" + } + ] + }, + { + "type": "rich_text_preformatted", + "elements": [ + { + "type": "text", + "text": "Hello there, I am preformatted block!\n\nI can have multiple paragraph breaks within the block." + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "\nI am rich text with a paragraph break following preformatted text. \n\nI can have multiple paragraph breaks within the block.\n\n" + } + ] + }, + { + "type": "rich_text_quote", + "elements": [ + { + "type": "text", + "text": "I am a basic rich text quote, \n\nI can have multiple paragraph breaks within the block." + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "\nI am rich text with a paragraph after the quote block\n\n" + } + ] + }, + { + "type": "rich_text_quote", + "elements": [ + { + "type": "text", + "text": "I am a basic quote block following rich text" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "\n" + } + ] + }, + { + "type": "rich_text_preformatted", + "elements": [ + { + "type": "text", + "text": "I am more preformatted text following a quote block" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "\n" + } + ] + }, + { + "type": "rich_text_quote", + "elements": [ + { + "type": "text", + "text": "I am a basic quote block following preformatted text" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "\n" + } + ] + }, + { + "type": "rich_text_list", + "style": "bullet", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "list item one" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "list item two" + } + ] + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "text", + "text": "\nI am rich text with a paragraph break after a list" + } + ] + } + ] + } + ] +} + """.trimIndent() + val json = gson.fromJson(original, JsonElement::class.java) + val expected = json.asJsonObject["blocks"] + val actual = gson.toJsonTree(blocks) + assertEquals(expected, actual, "\n" + expected.toString() + "\n" + actual.toString()) + } + + @Test + fun richTextObjects() { + val blocks = withBlocks { + richText { + blockId("rich-text-block") + richTextList { + style(ListStyle.BULLET) + indent(0) + border(0) + richTextSection { + broadcast(BroadcastRange.HERE) + } + richTextSection { + broadcast(BroadcastRange.CHANNEL) + } + richTextSection { + broadcast(BroadcastRange.EVERYONE) + } + } + + richTextList { + style(ListStyle.BULLET) + indent(1) + border(0) + richTextSection { + color("#C0FFEE") + } + } + + richTextList { + style(ListStyle.ORDERED) + indent(0) + border(1) + richTextSection { + channel("C0123456789") + } + richTextSection { + channel("C0123456789", + LimitedTextStyle.builder().bold(true).italic(true).clientHighlight(true).build()) + } + } + + richTextList { + style(ListStyle.BULLET) + offset(0) + richTextSection { + date(1720710212, "{date_num} at {time}", fallback = "timey") + } + } + + richTextSection { + emoji("basketball") + text(" ") + emoji("snowboarder") + text(" ") + emoji("checkered_flag") + } + + richTextQuote { + border(1) + link("https://api.slack.com") + text(" ") + link("https://api.slack.com", "Slack API") + text(" ") + link("https://api.slack.com", unsafe = true) + text(" ") + link("https://api.slack.com", "Slack API", + style = TextStyle.builder().strike(true).code(true).clientHighlight(true).build()) + } + + richTextSection { + user("U12345678") + } + + richTextSection { + usergroup("S0123456789") + } + + richTextPreformatted { + border(1) + text("preformatted") + } + } + } + val original = """ +{ + "blocks": [ + { + "type": "rich_text", + "block_id": "rich-text-block", + "elements": [ + { + "type": "rich_text_list", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "broadcast", + "range": "here" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "broadcast", + "range": "channel" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "broadcast", + "range": "everyone" + } + ] + } + ], + "style": "bullet", + "indent": 0, + "border": 0 + }, + { + "type": "rich_text_list", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "color", + "value": "#C0FFEE" + } + ] + } + ], + "style": "bullet", + "indent": 1, + "border": 0 + }, + { + "type": "rich_text_list", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "channel", + "channel_id": "C0123456789" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "channel", + "channel_id": "C0123456789", + "style": { + "bold": true, + "italic": true, + "strike": false, + "highlight": false, + "client_highlight": true, + "unlink": false + } + } + ] + } + ], + "style": "ordered", + "indent": 0, + "border": 1 + }, + { + "type": "rich_text_list", + "elements": [ + { + "type": "rich_text_section", + "elements": [ + { + "type": "date", + "timestamp": 1720710212, + "format": "{date_num} at {time}", + "fallback": "timey" + } + ] + } + ], + "style": "bullet", + "offset": 0 + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "emoji", + "name": "basketball" + }, + { + "type": "text", + "text": " " + }, + { + "type": "emoji", + "name": "snowboarder" + }, + { + "type": "text", + "text": " " + }, + { + "type": "emoji", + "name": "checkered_flag" + } + ] + }, + { + "type": "rich_text_quote", + "elements": [ + { + "type": "link", + "url": "https://api.slack.com" + }, + { + "type": "text", + "text": " " + }, + { + "type": "link", + "url": "https://api.slack.com", + "text": "Slack API" + }, + { + "type": "text", + "text": " " + }, + { + "type": "link", + "url": "https://api.slack.com", + "unsafe": true + }, + { + "type": "text", + "text": " " + }, + { + "type": "link", + "url": "https://api.slack.com", + "text": "Slack API", + "style": { + "bold": false, + "italic": false, + "strike": true, + "highlight": false, + "client_highlight": true, + "unlink": false, + "code": true + } + } + ], + "border": 1 + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "user", + "user_id": "U12345678" + } + ] + }, + { + "type": "rich_text_section", + "elements": [ + { + "type": "usergroup", + "usergroup_id": "S0123456789" + } + ] + }, + { + "type": "rich_text_preformatted", + "elements": [ + { + "type": "text", + "text": "preformatted" + } + ], + "border": 1 + } + ] + } + ] +} + """.trimIndent() + val json = gson.fromJson(original, JsonElement::class.java) + val expected = json.asJsonObject["blocks"] + val actual = gson.toJsonTree(blocks) + assertEquals(expected, actual, "\n" + expected.toString() + "\n" + actual.toString()) + } + + @Test + fun dslWithElements() { + val blocksWithElements = withBlocks { + richText { + elements { + richTextSection { + elements { + text("section") + } + } + richTextList { + style(ListStyle.BULLET) + elements { + richTextSection { + elements { + text("list") + } + } + } + } + richTextPreformatted { + elements { + text("preformatted") + } + } + richTextQuote { + elements { + text("quote") + } + } + } + } + } + val original = withBlocks { + richText { + richTextSection { + text("section") + } + richTextList { + style(ListStyle.BULLET) + richTextSection { + text("list") + } + } + richTextPreformatted { + text("preformatted") + } + richTextQuote { + text("quote") + } + } + } + val expected = gson.toJsonTree(original) + val actual = gson.toJsonTree(blocksWithElements) + assertEquals(expected, actual, "\n" + expected.toString() + "\n" + actual.toString()) + } + +} diff --git a/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/validation/BlockBuilderValidationTest.kt b/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/validation/BlockBuilderValidationTest.kt index 8abff734f..7a147266a 100644 --- a/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/validation/BlockBuilderValidationTest.kt +++ b/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/validation/BlockBuilderValidationTest.kt @@ -27,9 +27,14 @@ class BlockBuilderValidationTest { validateMethodNames(InputBlock::class.java, InputBlockBuilder::class.java) } + @Test + fun testRichTextBlockBuilder() { + validateMethodNames(RichTextBlock::class.java, RichTextBlockBuilder::class.java) + } + @Test fun testSectionBlockBuilder() { validateMethodNames(SectionBlock::class.java, SectionBlockBuilder::class.java) } -} \ No newline at end of file +} diff --git a/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/validation/BlockElementBuilderValidationTest.kt b/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/validation/BlockElementBuilderValidationTest.kt index f595466eb..922bfa62b 100644 --- a/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/validation/BlockElementBuilderValidationTest.kt +++ b/slack-api-model-kotlin-extension/src/test/kotlin/test_locally/block/validation/BlockElementBuilderValidationTest.kt @@ -82,6 +82,26 @@ class BlockElementBuilderValidationTest { validateMethodNames(RadioButtonsElement::class.java, RadioButtonsElementBuilder::class.java) } + @Test + fun testRichTextListElementBuilder() { + validateMethodNames(RichTextListElement::class.java, RichTextListElementBuilder::class.java) + } + + @Test + fun testRichTextPreformattedElementBuilder() { + validateMethodNames(RichTextPreformattedElement::class.java, RichTextPreformattedElementBuilder::class.java) + } + + @Test + fun testRichTextQuoteElementBuilder() { + validateMethodNames(RichTextQuoteElement::class.java, RichTextQuoteElementBuilder::class.java) + } + + @Test + fun testRichTextSectionElementBuilder() { + validateMethodNames(RichTextSectionElement::class.java, RichTextSectionElementBuilder::class.java) + } + @Test fun testStaticSelectElementBuilder() { validateMethodNames(StaticSelectElement::class.java, StaticSelectElementBuilder::class.java) @@ -92,4 +112,4 @@ class BlockElementBuilderValidationTest { validateMethodNames(UsersSelectElement::class.java, UsersSelectElementBuilder::class.java) } -} \ No newline at end of file +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/block/element/RichTextQuoteElement.java b/slack-api-model/src/main/java/com/slack/api/model/block/element/RichTextQuoteElement.java index bf58135bf..1b87fc453 100644 --- a/slack-api-model/src/main/java/com/slack/api/model/block/element/RichTextQuoteElement.java +++ b/slack-api-model/src/main/java/com/slack/api/model/block/element/RichTextQuoteElement.java @@ -19,5 +19,6 @@ public class RichTextQuoteElement extends BlockElement implements RichTextElemen private final String type = TYPE; @Builder.Default private List elements = new ArrayList<>(); + private Integer border; }