Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
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
26 changes: 26 additions & 0 deletions json-logs/samples/api/blocks.validate.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"ok": false,
"error": "",
"response_metadata": {
"messages": [
""
]
},
"needed": "",
"provided": "",
"errors": [
{
"code": "",
"message": "",
"pointer": "",
"constraint": {
"type": "",
"expected": [
""
],
"got": ""
}
}
],
"warning": ""
}
1 change: 1 addition & 0 deletions metadata/web-api/rate_limit_tiers.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@
"auth.revoke": "Tier3",
"auth.teams.list": "Tier2",
"auth.test": "SpecialTier_auth_test",
"blocks.validate": "SpecialTier_blocks_validate",
"bookmarks.add": "Tier2",
"bookmarks.edit": "Tier2",
"bookmarks.list": "Tier3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import com.slack.api.methods.request.auth.AuthRevokeRequest;
import com.slack.api.methods.request.auth.AuthTestRequest;
import com.slack.api.methods.request.auth.teams.AuthTeamsListRequest;
import com.slack.api.methods.request.blocks.BlocksValidateRequest;
import com.slack.api.methods.request.bookmarks.BookmarksAddRequest;
import com.slack.api.methods.request.bookmarks.BookmarksEditRequest;
import com.slack.api.methods.request.bookmarks.BookmarksListRequest;
Expand Down Expand Up @@ -193,6 +194,7 @@
import com.slack.api.methods.response.auth.AuthRevokeResponse;
import com.slack.api.methods.response.auth.AuthTestResponse;
import com.slack.api.methods.response.auth.teams.AuthTeamsListResponse;
import com.slack.api.methods.response.blocks.BlocksValidateResponse;
import com.slack.api.methods.response.bookmarks.BookmarksAddResponse;
import com.slack.api.methods.response.bookmarks.BookmarksEditResponse;
import com.slack.api.methods.response.bookmarks.BookmarksListResponse;
Expand Down Expand Up @@ -911,6 +913,14 @@ CompletableFuture<AdminConversationsWhitelistListGroupsLinkedToChannelResponse>

CompletableFuture<AuthTeamsListResponse> authTeamsList(RequestConfigurator<AuthTeamsListRequest.AuthTeamsListRequestBuilder> req);

// ------------------------------
// blocks
// ------------------------------

CompletableFuture<BlocksValidateResponse> blocksValidate(BlocksValidateRequest req);

CompletableFuture<BlocksValidateResponse> blocksValidate(RequestConfigurator<BlocksValidateRequest.BlocksValidateRequestBuilder> req);

// ------------------------------
// bookmarks
// ------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,12 @@ private Methods() {

public static final String AUTH_TEAMS_LIST = "auth.teams.list";

// ------------------------------
// blocks
// ------------------------------

public static final String BLOCKS_VALIDATE = "blocks.validate";

// ------------------------------
// bookmarks
// ------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
import com.slack.api.methods.request.auth.AuthRevokeRequest;
import com.slack.api.methods.request.auth.AuthTestRequest;
import com.slack.api.methods.request.auth.teams.AuthTeamsListRequest;
import com.slack.api.methods.request.blocks.BlocksValidateRequest;
import com.slack.api.methods.request.bookmarks.BookmarksAddRequest;
import com.slack.api.methods.request.bookmarks.BookmarksEditRequest;
import com.slack.api.methods.request.bookmarks.BookmarksListRequest;
Expand Down Expand Up @@ -212,6 +213,7 @@
import com.slack.api.methods.response.auth.AuthRevokeResponse;
import com.slack.api.methods.response.auth.AuthTestResponse;
import com.slack.api.methods.response.auth.teams.AuthTeamsListResponse;
import com.slack.api.methods.response.blocks.BlocksValidateResponse;
import com.slack.api.methods.response.bookmarks.BookmarksAddResponse;
import com.slack.api.methods.response.bookmarks.BookmarksEditResponse;
import com.slack.api.methods.response.bookmarks.BookmarksListResponse;
Expand Down Expand Up @@ -1377,6 +1379,16 @@ AuthTestResponse authTest(RequestConfigurator<AuthTestRequest.AuthTestRequestBui
AuthTeamsListResponse authTeamsList(RequestConfigurator<AuthTeamsListRequest.AuthTeamsListRequestBuilder> req)
throws IOException, SlackApiException;

// ------------------------------
// blocks
// ------------------------------

BlocksValidateResponse blocksValidate(BlocksValidateRequest req) throws IOException, SlackApiException;

BlocksValidateResponse blocksValidate(
RequestConfigurator<BlocksValidateRequest.BlocksValidateRequestBuilder> req)
throws IOException, SlackApiException;

// ------------------------------
// bookmarks
// ------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,13 @@ public enum MethodsRateLimitTier {
/**
* This method allows hundreds of requests per minute. Use it as often as is reasonably required.
*/
SpecialTier_chat_getPermalink;
SpecialTier_chat_getPermalink,

/**
* blocks.validate requires no token, so it has special rate limiting conditions rather than a
* standard tier. See https://docs.slack.dev/reference/methods/blocks.validate.
*/
SpecialTier_blocks_validate;

// --------------------------------------------------------------------------------------------

Expand All @@ -72,6 +78,7 @@ public enum MethodsRateLimitTier {
allowedRequestsPerMinute.put(MethodsRateLimitTier.SpecialTier_chat_getPermalink, 600);
allowedRequestsPerMinute.put(MethodsRateLimitTier.SpecialTier_chat_postMessage, 60); // per channel
allowedRequestsPerMinute.put(MethodsRateLimitTier.SpecialTier_assistant_threads_setStatus, 60); // per DM
allowedRequestsPerMinute.put(MethodsRateLimitTier.SpecialTier_blocks_validate, 60);
}

public static Integer getAllowedRequestsPerMinute(MethodsRateLimitTier tier) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,8 @@ public static void setRateLimitTier(String methodName, MethodsRateLimitTier tier
setRateLimitTier(AUTH_TEST, SpecialTier_auth_test);
setRateLimitTier(AUTH_TEAMS_LIST, Tier2);

setRateLimitTier(BLOCKS_VALIDATE, SpecialTier_blocks_validate);

setRateLimitTier(BOOKMARKS_ADD, Tier2);
setRateLimitTier(BOOKMARKS_EDIT, Tier2);
setRateLimitTier(BOOKMARKS_LIST, Tier3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
import com.slack.api.methods.request.auth.AuthRevokeRequest;
import com.slack.api.methods.request.auth.AuthTestRequest;
import com.slack.api.methods.request.auth.teams.AuthTeamsListRequest;
import com.slack.api.methods.request.blocks.BlocksValidateRequest;
import com.slack.api.methods.request.bookmarks.BookmarksAddRequest;
import com.slack.api.methods.request.bookmarks.BookmarksEditRequest;
import com.slack.api.methods.request.bookmarks.BookmarksListRequest;
Expand Down Expand Up @@ -1242,6 +1243,35 @@ public static FormBody.Builder toForm(AuthTeamsListRequest req) {
return form;
}

public static FormBody.Builder toForm(BlocksValidateRequest req) {
FormBody.Builder form = new FormBody.Builder();
if (req.getBlocksAsString() != null) {
form.add("blocks", req.getBlocksAsString());
} else if (req.getBlocks() != null) {
form.add("blocks", getJsonWithGsonAnonymInnerClassHandling(req.getBlocks()));
}
if (req.getBlocksAsString() != null && req.getBlocks() != null) {
log.warn("Although you set both blocksAsString and blocks, only blocksAsString was used.");
}
if (req.getMessageAsString() != null) {
form.add("message", req.getMessageAsString());
} else if (req.getMessage() != null) {
form.add("message", GSON.toJson(req.getMessage()));
}
if (req.getMessageAsString() != null && req.getMessage() != null) {
log.warn("Although you set both messageAsString and message, only messageAsString was used.");
}
if (req.getViewAsString() != null) {
form.add("view", req.getViewAsString());
} else if (req.getView() != null) {
form.add("view", GSON.toJson(req.getView()));
}
if (req.getViewAsString() != null && req.getView() != null) {
log.warn("Although you set both viewAsString and view, only viewAsString was used.");
}
return form;
}

public static FormBody.Builder toForm(BookmarksAddRequest req) {
FormBody.Builder form = new FormBody.Builder();
setIfNotNull("channel_id", req.getChannelId(), form);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import com.slack.api.methods.request.auth.AuthRevokeRequest;
import com.slack.api.methods.request.auth.AuthTestRequest;
import com.slack.api.methods.request.auth.teams.AuthTeamsListRequest;
import com.slack.api.methods.request.blocks.BlocksValidateRequest;
import com.slack.api.methods.request.bookmarks.BookmarksAddRequest;
import com.slack.api.methods.request.bookmarks.BookmarksEditRequest;
import com.slack.api.methods.request.bookmarks.BookmarksListRequest;
Expand Down Expand Up @@ -198,6 +199,7 @@
import com.slack.api.methods.response.auth.AuthRevokeResponse;
import com.slack.api.methods.response.auth.AuthTestResponse;
import com.slack.api.methods.response.auth.teams.AuthTeamsListResponse;
import com.slack.api.methods.response.blocks.BlocksValidateResponse;
import com.slack.api.methods.response.bookmarks.BookmarksAddResponse;
import com.slack.api.methods.response.bookmarks.BookmarksEditResponse;
import com.slack.api.methods.response.bookmarks.BookmarksListResponse;
Expand Down Expand Up @@ -1504,6 +1506,16 @@ public CompletableFuture<AuthTeamsListResponse> authTeamsList(RequestConfigurato
return authTeamsList(req.configure(AuthTeamsListRequest.builder()).build());
}

@Override
public CompletableFuture<BlocksValidateResponse> blocksValidate(BlocksValidateRequest req) {
return executor.execute(BLOCKS_VALIDATE, toMap(req), () -> methods.blocksValidate(req));
}

@Override
public CompletableFuture<BlocksValidateResponse> blocksValidate(RequestConfigurator<BlocksValidateRequest.BlocksValidateRequestBuilder> req) {
return blocksValidate(req.configure(BlocksValidateRequest.builder()).build());
}

@Override
public CompletableFuture<BookmarksAddResponse> bookmarksAdd(BookmarksAddRequest req) {
return executor.execute(BOOKMARKS_ADD, toMap(req), () -> methods.bookmarksAdd(req));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
import com.slack.api.methods.request.auth.AuthRevokeRequest;
import com.slack.api.methods.request.auth.AuthTestRequest;
import com.slack.api.methods.request.auth.teams.AuthTeamsListRequest;
import com.slack.api.methods.request.blocks.BlocksValidateRequest;
import com.slack.api.methods.request.bookmarks.BookmarksAddRequest;
import com.slack.api.methods.request.bookmarks.BookmarksEditRequest;
import com.slack.api.methods.request.bookmarks.BookmarksListRequest;
Expand Down Expand Up @@ -214,6 +215,7 @@
import com.slack.api.methods.response.auth.AuthRevokeResponse;
import com.slack.api.methods.response.auth.AuthTestResponse;
import com.slack.api.methods.response.auth.teams.AuthTeamsListResponse;
import com.slack.api.methods.response.blocks.BlocksValidateResponse;
import com.slack.api.methods.response.bookmarks.BookmarksAddResponse;
import com.slack.api.methods.response.bookmarks.BookmarksEditResponse;
import com.slack.api.methods.response.bookmarks.BookmarksListResponse;
Expand Down Expand Up @@ -1582,6 +1584,16 @@ public AuthTeamsListResponse authTeamsList(RequestConfigurator<AuthTeamsListRequ
return authTeamsList(req.configure(AuthTeamsListRequest.builder()).build());
}

@Override
public BlocksValidateResponse blocksValidate(BlocksValidateRequest req) throws IOException, SlackApiException {
return postFormAndParseResponse(toForm(req), Methods.BLOCKS_VALIDATE, BlocksValidateResponse.class);
}

@Override
public BlocksValidateResponse blocksValidate(RequestConfigurator<BlocksValidateRequest.BlocksValidateRequestBuilder> req) throws IOException, SlackApiException {
return blocksValidate(req.configure(BlocksValidateRequest.builder()).build());
}

@Override
public BookmarksAddResponse bookmarksAdd(BookmarksAddRequest req) throws IOException, SlackApiException {
return postFormWithTokenAndParseResponse(toForm(req), Methods.BOOKMARKS_ADD, getToken(req), BookmarksAddResponse.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package com.slack.api.methods.request.blocks;

import com.slack.api.methods.SlackApiRequest;
import com.slack.api.model.Attachment;
import com.slack.api.model.block.LayoutBlock;
import com.slack.api.model.view.View;
import lombok.Builder;
import lombok.Data;

import java.util.List;

/**
* https://docs.slack.dev/reference/methods/blocks.validate
*/
@Data
@Builder
public class BlocksValidateRequest implements SlackApiRequest {

/**
* An array of blocks to validate.
*/
private List<LayoutBlock> blocks;

/**
* An array of blocks to validate, as a JSON-encoded string.
*/
private String blocksAsString;

/**
* A message payload to validate.
*/
private MessagePayload message;

/**
* A message payload to validate, as a JSON-encoded string.
*/
private String messageAsString;

/**
* A view payload to validate.
*/
private View view;

/**
* A view payload to validate, as a JSON-encoded string.
*/
private String viewAsString;

@Override
public String getToken() {
return null;
}

@Data
@Builder
public static class MessagePayload {
private List<LayoutBlock> blocks;
private List<Attachment> attachments;
}
Comment on lines +54 to +59

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👁️‍🗨️ note: This is added to the request class for blocks.validate to bring matching arguments for:

  • blocks: blocksAsString
  • message: messageAsString
  • view: viewsAsString

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.slack.api.methods.response.blocks;

import com.google.gson.JsonElement;
import com.slack.api.methods.SlackApiTextResponse;
import com.slack.api.model.ResponseMetadata;
import lombok.Data;

import java.util.List;
import java.util.Map;

@Data
public class BlocksValidateResponse implements SlackApiTextResponse {

private boolean ok;
private String warning;
private String error;
private String needed;
private String provided;
private transient Map<String, List<String>> httpResponseHeaders;

private ResponseMetadata responseMetadata;
private List<Error> errors;

// https://docs.slack.dev/reference/methods/blocks.validate#validation-errors
@Data
public static class Error {
private String pointer;
private String code;
private String message;
private Constraint constraint;

// expected/got are JsonElement because their shape varies by constraint type
// (a string array for "enum", a number for length/count constraints, or absent).
@Data
public static class Constraint {
private String type;
private JsonElement expected;
private JsonElement got;
Comment on lines +37 to +38

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📣 note: These can be handled with a typecheck in calling code but for now we avoid parsing responses into particular types here.

}
}
}
Loading
Loading