From a3cd493c7be15c922de290b8660c7b72b027bf38 Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Wed, 11 Nov 2026 22:41:20 -0800 Subject: [PATCH 1/2] feat: add admin.slackbot.skills.list method Adds the admin.slackbot.skills.list Web API method to the sync and async clients, with its request and response types, mock fixture, rate limit tier, and tests. Co-Authored-By: Claude --- .../api/admin.slackbot.skills.list.json | 34 ++++++++++ metadata/web-api/rate_limit_tiers.json | 1 + .../slack/api/methods/AsyncMethodsClient.java | 10 +++ .../java/com/slack/api/methods/Methods.java | 6 ++ .../com/slack/api/methods/MethodsClient.java | 11 ++++ .../slack/api/methods/MethodsRateLimits.java | 2 + .../slack/api/methods/RequestFormBuilder.java | 16 +++++ .../methods/impl/AsyncMethodsClientImpl.java | 12 ++++ .../api/methods/impl/MethodsClientImpl.java | 12 ++++ .../AdminSlackbotSkillsListRequest.java | 66 +++++++++++++++++++ .../AdminSlackbotSkillsListResponse.java | 44 +++++++++++++ .../java/test_locally/api/MethodsTest.java | 4 +- .../methods_admin_api/AdminApiAsyncTest.java | 16 +++++ .../api/methods_admin_api/AdminApiTest.java | 15 +++++ .../AdminApi_slackbot_skills_Test.java | 55 ++++++++++++++++ 15 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 json-logs/samples/api/admin.slackbot.skills.list.json create mode 100644 slack-api-client/src/main/java/com/slack/api/methods/request/admin/slackbot/skills/AdminSlackbotSkillsListRequest.java create mode 100644 slack-api-client/src/main/java/com/slack/api/methods/response/admin/slackbot/skills/AdminSlackbotSkillsListResponse.java create mode 100644 slack-api-client/src/test/java/test_with_remote_apis/methods_admin_api/AdminApi_slackbot_skills_Test.java diff --git a/json-logs/samples/api/admin.slackbot.skills.list.json b/json-logs/samples/api/admin.slackbot.skills.list.json new file mode 100644 index 000000000..16b175b2c --- /dev/null +++ b/json-logs/samples/api/admin.slackbot.skills.list.json @@ -0,0 +1,34 @@ +{ + "ok": false, + "error": "", + "needed": "", + "provided": "", + "warning": "", + "response_metadata": { + "messages": [ + "" + ], + "next_cursor": "" + }, + "skills": [ + { + "auto_enabled": { + "permission_type": "", + "usergroup_ids": [ + "S00000000" + ] + }, + "category": "", + "creator_id": "U00000000", + "date_created": 12345, + "date_updated": 12345, + "description": "", + "display_name": "", + "id": "F00000000", + "is_official": false, + "library_count": 12345, + "usage_count": 12345, + "visibility": "" + } + ] +} \ No newline at end of file diff --git a/metadata/web-api/rate_limit_tiers.json b/metadata/web-api/rate_limit_tiers.json index 952a9ffb5..297f02815 100644 --- a/metadata/web-api/rate_limit_tiers.json +++ b/metadata/web-api/rate_limit_tiers.json @@ -62,6 +62,7 @@ "admin.roles.addAssignments": "Tier2", "admin.roles.listAssignments": "Tier3", "admin.roles.removeAssignments": "Tier2", + "admin.slackbot.skills.list": "Tier2", "admin.teams.admins.list": "Tier3", "admin.teams.create": "Tier1", "admin.teams.list": "Tier3", diff --git a/slack-api-client/src/main/java/com/slack/api/methods/AsyncMethodsClient.java b/slack-api-client/src/main/java/com/slack/api/methods/AsyncMethodsClient.java index 921a182c7..4672abedb 100644 --- a/slack-api-client/src/main/java/com/slack/api/methods/AsyncMethodsClient.java +++ b/slack-api-client/src/main/java/com/slack/api/methods/AsyncMethodsClient.java @@ -26,6 +26,7 @@ import com.slack.api.methods.request.admin.roles.AdminRolesAddAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesListAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesRemoveAssignmentsRequest; +import com.slack.api.methods.request.admin.slackbot.skills.AdminSlackbotSkillsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsAdminsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsCreateRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsListRequest; @@ -186,6 +187,7 @@ import com.slack.api.methods.response.admin.roles.AdminRolesAddAssignmentsResponse; import com.slack.api.methods.response.admin.roles.AdminRolesListAssignmentsResponse; import com.slack.api.methods.response.admin.roles.AdminRolesRemoveAssignmentsResponse; +import com.slack.api.methods.response.admin.slackbot.skills.AdminSlackbotSkillsListResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsAdminsListResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsCreateResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsListResponse; @@ -656,6 +658,14 @@ CompletableFuture CompletableFuture adminRolesRemoveAssignments(RequestConfigurator req); + // ------------------------------ + // admin.slackbot.skills + // ------------------------------ + + CompletableFuture adminSlackbotSkillsList(AdminSlackbotSkillsListRequest req); + + CompletableFuture adminSlackbotSkillsList(RequestConfigurator req); + // ------------------------------ // admin.teams.admins // ------------------------------ diff --git a/slack-api-client/src/main/java/com/slack/api/methods/Methods.java b/slack-api-client/src/main/java/com/slack/api/methods/Methods.java index 3c420c455..3a62832d8 100644 --- a/slack-api-client/src/main/java/com/slack/api/methods/Methods.java +++ b/slack-api-client/src/main/java/com/slack/api/methods/Methods.java @@ -138,6 +138,12 @@ private Methods() { public static final String ADMIN_ROLES_ADD_ASSIGNMENTS = "admin.roles.addAssignments"; public static final String ADMIN_ROLES_REMOVE_ASSIGNMENTS = "admin.roles.removeAssignments"; + // ------------------------------ + // admin.slackbot.skills + // ------------------------------ + + public static final String ADMIN_SLACKBOT_SKILLS_LIST = "admin.slackbot.skills.list"; + // ------------------------------ // admin.teams.admins // ------------------------------ diff --git a/slack-api-client/src/main/java/com/slack/api/methods/MethodsClient.java b/slack-api-client/src/main/java/com/slack/api/methods/MethodsClient.java index dae277424..0d84d4727 100644 --- a/slack-api-client/src/main/java/com/slack/api/methods/MethodsClient.java +++ b/slack-api-client/src/main/java/com/slack/api/methods/MethodsClient.java @@ -26,6 +26,7 @@ import com.slack.api.methods.request.admin.roles.AdminRolesAddAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesListAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesRemoveAssignmentsRequest; +import com.slack.api.methods.request.admin.slackbot.skills.AdminSlackbotSkillsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsAdminsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsCreateRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsListRequest; @@ -199,6 +200,7 @@ import com.slack.api.methods.response.admin.roles.AdminRolesAddAssignmentsResponse; import com.slack.api.methods.response.admin.roles.AdminRolesListAssignmentsResponse; import com.slack.api.methods.response.admin.roles.AdminRolesRemoveAssignmentsResponse; +import com.slack.api.methods.response.admin.slackbot.skills.AdminSlackbotSkillsListResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsAdminsListResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsCreateResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsListResponse; @@ -896,6 +898,15 @@ AdminRolesRemoveAssignmentsResponse adminRolesRemoveAssignments( RequestConfigurator req) throws IOException, SlackApiException; + // ------------------------------ + // admin.slackbot.skills + // ------------------------------ + + AdminSlackbotSkillsListResponse adminSlackbotSkillsList(AdminSlackbotSkillsListRequest req) throws IOException, SlackApiException; + + AdminSlackbotSkillsListResponse adminSlackbotSkillsList(RequestConfigurator req) + throws IOException, SlackApiException; + // ------------------------------ // admin.teams.admins // ------------------------------ diff --git a/slack-api-client/src/main/java/com/slack/api/methods/MethodsRateLimits.java b/slack-api-client/src/main/java/com/slack/api/methods/MethodsRateLimits.java index 66cd8a278..82bfd1f80 100644 --- a/slack-api-client/src/main/java/com/slack/api/methods/MethodsRateLimits.java +++ b/slack-api-client/src/main/java/com/slack/api/methods/MethodsRateLimits.java @@ -129,6 +129,8 @@ public static void setRateLimitTier(String methodName, MethodsRateLimitTier tier ADMIN_ROLES_ADD_ASSIGNMENTS, ADMIN_ROLES_REMOVE_ASSIGNMENTS, + ADMIN_SLACKBOT_SKILLS_LIST, + ADMIN_TEAMS_SETTINGS_SET_DEFAULT_CHANNELS, ADMIN_TEAMS_SETTINGS_SET_DESCRIPTION, ADMIN_TEAMS_SETTINGS_SET_DISCOVERABILITY, diff --git a/slack-api-client/src/main/java/com/slack/api/methods/RequestFormBuilder.java b/slack-api-client/src/main/java/com/slack/api/methods/RequestFormBuilder.java index a8a86a61a..7762a37bd 100644 --- a/slack-api-client/src/main/java/com/slack/api/methods/RequestFormBuilder.java +++ b/slack-api-client/src/main/java/com/slack/api/methods/RequestFormBuilder.java @@ -27,6 +27,7 @@ import com.slack.api.methods.request.admin.roles.AdminRolesAddAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesListAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesRemoveAssignmentsRequest; +import com.slack.api.methods.request.admin.slackbot.skills.AdminSlackbotSkillsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsAdminsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsCreateRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsListRequest; @@ -822,6 +823,21 @@ public static FormBody.Builder toForm(AdminRolesRemoveAssignmentsRequest req) { return form; } + public static FormBody.Builder toForm(AdminSlackbotSkillsListRequest req) { + FormBody.Builder form = new FormBody.Builder(); + setIfNotNull("category", req.getCategory(), form); + setIfNotNull("cursor", req.getCursor(), form); + setIfNotNull("limit", req.getLimit(), form); + if (req.getCreatorIds() != null) { + setIfNotNull("creator_ids", req.getCreatorIds().stream().collect(joining(",")), form); + } + setIfNotNull("publish_status", req.getPublishStatus(), form); + setIfNotNull("auto_enabled_status", req.getAutoEnabledStatus(), form); + setIfNotNull("sort", req.getSort(), form); + setIfNotNull("sort_dir", req.getSortDir(), form); + return form; + } + public static FormBody.Builder toForm(AdminTeamsAdminsListRequest req) { FormBody.Builder form = new FormBody.Builder(); setIfNotNull("cursor", req.getCursor(), form); diff --git a/slack-api-client/src/main/java/com/slack/api/methods/impl/AsyncMethodsClientImpl.java b/slack-api-client/src/main/java/com/slack/api/methods/impl/AsyncMethodsClientImpl.java index 01906e50e..df0e53f48 100644 --- a/slack-api-client/src/main/java/com/slack/api/methods/impl/AsyncMethodsClientImpl.java +++ b/slack-api-client/src/main/java/com/slack/api/methods/impl/AsyncMethodsClientImpl.java @@ -31,6 +31,7 @@ import com.slack.api.methods.request.admin.roles.AdminRolesAddAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesListAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesRemoveAssignmentsRequest; +import com.slack.api.methods.request.admin.slackbot.skills.AdminSlackbotSkillsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsAdminsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsCreateRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsListRequest; @@ -191,6 +192,7 @@ import com.slack.api.methods.response.admin.roles.AdminRolesAddAssignmentsResponse; import com.slack.api.methods.response.admin.roles.AdminRolesListAssignmentsResponse; import com.slack.api.methods.response.admin.roles.AdminRolesRemoveAssignmentsResponse; +import com.slack.api.methods.response.admin.slackbot.skills.AdminSlackbotSkillsListResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsAdminsListResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsCreateResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsListResponse; @@ -999,6 +1001,16 @@ public CompletableFuture adminRolesRemoveAs return adminRolesRemoveAssignments(req.configure(AdminRolesRemoveAssignmentsRequest.builder()).build()); } + @Override + public CompletableFuture adminSlackbotSkillsList(AdminSlackbotSkillsListRequest req) { + return executor.execute(ADMIN_SLACKBOT_SKILLS_LIST, toMap(req), () -> methods.adminSlackbotSkillsList(req)); + } + + @Override + public CompletableFuture adminSlackbotSkillsList(RequestConfigurator req) { + return adminSlackbotSkillsList(req.configure(AdminSlackbotSkillsListRequest.builder()).build()); + } + @Override public CompletableFuture adminTeamsAdminsList(AdminTeamsAdminsListRequest req) { return executor.execute(ADMIN_TEAMS_ADMINS_LIST, toMap(req), () -> methods.adminTeamsAdminsList(req)); diff --git a/slack-api-client/src/main/java/com/slack/api/methods/impl/MethodsClientImpl.java b/slack-api-client/src/main/java/com/slack/api/methods/impl/MethodsClientImpl.java index 572f9877f..609b4a65c 100644 --- a/slack-api-client/src/main/java/com/slack/api/methods/impl/MethodsClientImpl.java +++ b/slack-api-client/src/main/java/com/slack/api/methods/impl/MethodsClientImpl.java @@ -27,6 +27,7 @@ import com.slack.api.methods.request.admin.roles.AdminRolesAddAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesListAssignmentsRequest; import com.slack.api.methods.request.admin.roles.AdminRolesRemoveAssignmentsRequest; +import com.slack.api.methods.request.admin.slackbot.skills.AdminSlackbotSkillsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsAdminsListRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsCreateRequest; import com.slack.api.methods.request.admin.teams.AdminTeamsListRequest; @@ -200,6 +201,7 @@ import com.slack.api.methods.response.admin.roles.AdminRolesAddAssignmentsResponse; import com.slack.api.methods.response.admin.roles.AdminRolesListAssignmentsResponse; import com.slack.api.methods.response.admin.roles.AdminRolesRemoveAssignmentsResponse; +import com.slack.api.methods.response.admin.slackbot.skills.AdminSlackbotSkillsListResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsAdminsListResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsCreateResponse; import com.slack.api.methods.response.admin.teams.AdminTeamsListResponse; @@ -1040,6 +1042,16 @@ public AdminRolesRemoveAssignmentsResponse adminRolesRemoveAssignments(RequestCo return adminRolesRemoveAssignments(req.configure(AdminRolesRemoveAssignmentsRequest.builder()).build()); } + @Override + public AdminSlackbotSkillsListResponse adminSlackbotSkillsList(AdminSlackbotSkillsListRequest req) throws IOException, SlackApiException { + return postFormWithTokenAndParseResponse(toForm(req), Methods.ADMIN_SLACKBOT_SKILLS_LIST, getToken(req), AdminSlackbotSkillsListResponse.class); + } + + @Override + public AdminSlackbotSkillsListResponse adminSlackbotSkillsList(RequestConfigurator req) throws IOException, SlackApiException { + return adminSlackbotSkillsList(req.configure(AdminSlackbotSkillsListRequest.builder()).build()); + } + @Override public AdminTeamsAdminsListResponse adminTeamsAdminsList(AdminTeamsAdminsListRequest req) throws IOException, SlackApiException { return postFormWithTokenAndParseResponse(toForm(req), Methods.ADMIN_TEAMS_ADMINS_LIST, getToken(req), AdminTeamsAdminsListResponse.class); diff --git a/slack-api-client/src/main/java/com/slack/api/methods/request/admin/slackbot/skills/AdminSlackbotSkillsListRequest.java b/slack-api-client/src/main/java/com/slack/api/methods/request/admin/slackbot/skills/AdminSlackbotSkillsListRequest.java new file mode 100644 index 000000000..b41389461 --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/request/admin/slackbot/skills/AdminSlackbotSkillsListRequest.java @@ -0,0 +1,66 @@ +package com.slack.api.methods.request.admin.slackbot.skills; + +import com.slack.api.methods.SlackApiRequest; +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +/** + * https://docs.slack.dev/reference/methods/admin.slackbot.skills.list + */ +@Data +@Builder +public class AdminSlackbotSkillsListRequest implements SlackApiRequest { + + /** + * Authentication token bearing required scopes. Tokens should be passed as an HTTP Authorization header or alternatively, as a POST parameter. + */ + private String token; + + /** + * Only return skills in this category. + * Acceptable values: `communication`, `customer_support`, `data_and_analytics`, `engineering`, `product_management`, `productivity`, `professional_development`, `project_management`, `sales`, `system`, `team_management`, `other` + */ + private String category; + + /** + * Continuation from the previous page. Keep all filters and sorting unchanged. Pages can be empty while a continuation remains; continue until next_cursor is empty. Changes during traversal may move results; pagination is not a snapshot. + */ + private String cursor; + + /** + * The maximum number of skills to return. Fewer may be returned even when more remain. + */ + private Integer limit; + + /** + * Only return skills created by these users. Accepts U or W user IDs. + */ + private List creatorIds; + + /** + * Filter by publication to the org catalog. + * Acceptable values: `all`, `published`, `unpublished` + */ + private String publishStatus; + + /** + * Filter by org deployment, independently of publication. + * Acceptable values: `all`, `enabled`, `disabled` + */ + private String autoEnabledStatus; + + /** + * Sort across the inventory. Name uses case-insensitive ordering. Unedited skills use their creation date for date_updated sorting. + * Acceptable values: `name`, `usage_count`, `date_updated` + */ + private String sort; + + /** + * Sort direction; file ID breaks ties. + * Acceptable values: `asc`, `desc` + */ + private String sortDir; + +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/response/admin/slackbot/skills/AdminSlackbotSkillsListResponse.java b/slack-api-client/src/main/java/com/slack/api/methods/response/admin/slackbot/skills/AdminSlackbotSkillsListResponse.java new file mode 100644 index 000000000..8f3e7a367 --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/response/admin/slackbot/skills/AdminSlackbotSkillsListResponse.java @@ -0,0 +1,44 @@ +package com.slack.api.methods.response.admin.slackbot.skills; + +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 AdminSlackbotSkillsListResponse implements SlackApiTextResponse { + + private boolean ok; + private String warning; + private String error; + private String needed; + private String provided; + private transient Map> httpResponseHeaders; + + private ResponseMetadata responseMetadata; + private List skills; + + @Data + public static class AutoEnabled { + private String permissionType; + private List usergroupIds; + } + + @Data + public static class Skill { + private AutoEnabled autoEnabled; + private String category; + private String creatorId; + private Integer dateCreated; + private Integer dateUpdated; + private String description; + private String displayName; + private String id; + private Boolean isOfficial; + private Integer libraryCount; + private Integer usageCount; + private String visibility; + } +} diff --git a/slack-api-client/src/test/java/test_locally/api/MethodsTest.java b/slack-api-client/src/test/java/test_locally/api/MethodsTest.java index 6d82d826e..5934744e5 100644 --- a/slack-api-client/src/test/java/test_locally/api/MethodsTest.java +++ b/slack-api-client/src/test/java/test_locally/api/MethodsTest.java @@ -19,8 +19,8 @@ public class MethodsTest { public void verifyTheCoverage() { // https://docs.slack.dev/reference/methods // var methodNames = [].slice.call(document.getElementsByClassName('apiReferenceFilterableList__listItemLink')).map(e => e.href.replace("https://docs.slack.dev/reference/methods/", ""));console.log(methodNames.toString());console.log(methodNames.length); - // 319 endpoints as of November 11, 2026 (apps.user.connection.bulkUpdate and requestAuth added ahead of their docs.slack.dev pages) - String methods = "admin.analytics.getFile,admin.apps.activities.list,admin.apps.approve,admin.apps.clearResolution,admin.apps.restrict,admin.apps.uninstall,admin.apps.approved.list,admin.apps.config.lookup,admin.apps.config.set,admin.apps.requests.cancel,admin.apps.requests.list,admin.apps.restricted.list,admin.audit.anomaly.allow.getItem,admin.audit.anomaly.allow.updateItem,admin.auth.policy.assignEntities,admin.auth.policy.getEntities,admin.auth.policy.removeEntities,admin.barriers.create,admin.barriers.delete,admin.barriers.list,admin.barriers.update,admin.conversations.archive,admin.conversations.bulkArchive,admin.conversations.bulkDelete,admin.conversations.bulkMove,admin.conversations.convertToPrivate,admin.conversations.convertToPublic,admin.conversations.create,admin.conversations.createForObjects,admin.conversations.delete,admin.conversations.disconnectShared,admin.conversations.getConversationPrefs,admin.conversations.getCustomRetention,admin.conversations.getTeams,admin.conversations.invite,admin.conversations.linkObjects,admin.conversations.lookup,admin.conversations.removeCustomRetention,admin.conversations.rename,admin.conversations.search,admin.conversations.setConversationPrefs,admin.conversations.setCustomRetention,admin.conversations.setTeams,admin.conversations.unarchive,admin.conversations.unlinkObjects,admin.conversations.ekm.listOriginalConnectedChannelInfo,admin.conversations.restrictAccess.addGroup,admin.conversations.restrictAccess.listGroups,admin.conversations.restrictAccess.removeGroup,admin.emoji.add,admin.emoji.addAlias,admin.emoji.list,admin.emoji.remove,admin.emoji.rename,admin.functions.list,admin.functions.permissions.lookup,admin.functions.permissions.set,admin.inviteRequests.approve,admin.inviteRequests.deny,admin.inviteRequests.list,admin.inviteRequests.approved.list,admin.inviteRequests.denied.list,admin.roles.addAssignments,admin.roles.listAssignments,admin.roles.removeAssignments,admin.teams.admins.list,admin.teams.create,admin.teams.list,admin.teams.owners.list,admin.teams.settings.info,admin.teams.settings.setDefaultChannels,admin.teams.settings.setDescription,admin.teams.settings.setDiscoverability,admin.teams.settings.setIcon,admin.teams.settings.setName,admin.usergroups.addChannels,admin.usergroups.addTeams,admin.usergroups.listChannels,admin.usergroups.removeChannels,admin.users.assign,admin.users.getExpiration,admin.users.invite,admin.users.list,admin.users.remove,admin.users.setAdmin,admin.users.setExpiration,admin.users.setOwner,admin.users.setRegular,admin.users.session.clearSettings,admin.users.session.getSettings,admin.users.session.invalidate,admin.users.session.list,admin.users.session.reset,admin.users.session.resetBulk,admin.users.session.setSettings,admin.users.unsupportedVersions.export,admin.workflows.collaborators.add,admin.workflows.collaborators.remove,admin.workflows.permissions.lookup,admin.workflows.search,admin.workflows.unpublish,admin.workflows.triggers.types.permissions.lookup,admin.workflows.triggers.types.permissions.set,api.test,apps.activities.list,apps.auth.external.delete,apps.auth.external.get,apps.connections.open,apps.datastore.bulkDelete,apps.datastore.bulkGet,apps.datastore.bulkPut,apps.datastore.count,apps.datastore.delete,apps.datastore.get,apps.datastore.put,apps.datastore.query,apps.datastore.update,apps.event.authorizations.list,apps.manifest.create,apps.manifest.delete,apps.manifest.export,apps.manifest.update,apps.manifest.validate,apps.uninstall,apps.user.connection.bulkUpdate,apps.user.connection.requestAuth,apps.user.connection.update,assistant.search.context,assistant.threads.setStatus,assistant.threads.setSuggestedPrompts,assistant.threads.setTitle,auth.revoke,auth.test,auth.teams.list,blocks.validate,bookmarks.add,bookmarks.edit,bookmarks.list,bookmarks.remove,bots.info,calls.add,calls.end,calls.info,calls.update,calls.participants.add,calls.participants.remove,canvases.access.delete,canvases.access.set,canvases.create,canvases.delete,canvases.edit,canvases.getContent,canvases.sections.lookup,channels.mark,chat.appendStream,chat.delete,chat.deleteScheduledMessage,chat.getPermalink,chat.meMessage,chat.postEphemeral,chat.postMessage,chat.scheduleMessage,chat.startStream,chat.stopStream,chat.unfurl,chat.update,chat.scheduledMessages.list,conversations.acceptSharedInvite,conversations.approveSharedInvite,conversations.archive,conversations.close,conversations.create,conversations.declineSharedInvite,conversations.history,conversations.info,conversations.invite,conversations.inviteShared,conversations.join,conversations.kick,conversations.leave,conversations.list,conversations.listConnectInvites,conversations.mark,conversations.members,conversations.open,conversations.rename,conversations.replies,conversations.setPurpose,conversations.setTopic,conversations.unarchive,conversations.canvases.create,conversations.externalInvitePermissions.set,conversations.requestSharedInvite.approve,conversations.requestSharedInvite.deny,conversations.requestSharedInvite.list,dialog.open,dnd.endDnd,dnd.endSnooze,dnd.info,dnd.setSnooze,dnd.teamInfo,emoji.list,files.comments.delete,files.completeUploadExternal,files.delete,files.getUploadURLExternal,files.info,files.list,files.revokePublicURL,files.sharedPublicURL,files.upload,files.remote.add,files.remote.info,files.remote.list,files.remote.remove,files.remote.share,files.remote.update,functions.completeError,functions.completeSuccess,functions.distributions.permissions.add,functions.distributions.permissions.list,functions.distributions.permissions.remove,functions.distributions.permissions.set,functions.workflows.steps.list,functions.workflows.steps.responses.export,groups.mark,migration.exchange,oauth.access,oauth.v2.access,oauth.v2.exchange,openid.connect.token,openid.connect.userInfo,pins.add,pins.list,pins.remove,reactions.add,reactions.get,reactions.list,reactions.remove,reminders.add,reminders.complete,reminders.delete,reminders.info,reminders.list,rtm.connect,rtm.start,search.all,search.files,search.messages,slackbot.skills.create,slackbot.skills.info,slackbot.skills.library.add,slackbot.skills.library.remove,slackbot.skills.list,slackbot.skills.update,slackLists.access.delete,slackLists.access.set,slackLists.create,slackLists.download.get,slackLists.download.start,slackLists.items.create,slackLists.items.delete,slackLists.items.deleteMultiple,slackLists.items.info,slackLists.items.list,slackLists.items.update,slackLists.update,stars.add,stars.list,stars.remove,team.accessLogs,team.billableInfo,team.info,team.integrationLogs,team.billing.info,team.externalTeams.disconnect,team.externalTeams.list,team.preferences.list,team.profile.get,tooling.tokens.rotate,usergroups.create,usergroups.disable,usergroups.enable,usergroups.list,usergroups.update,usergroups.users.list,usergroups.users.update,users.conversations,users.deletePhoto,users.getPresence,users.identity,users.info,users.list,users.lookupByEmail,users.setActive,users.setPhoto,users.setPresence,users.discoverableContacts.lookup,users.profile.get,users.profile.set,views.open,views.publish,views.push,views.update,workflows.featured.add,workflows.featured.list,workflows.featured.remove,workflows.featured.set,workflows.stepCompleted,workflows.stepFailed,workflows.updateStep,workflows.triggers.permissions.add,workflows.triggers.permissions.list,workflows.triggers.permissions.remove,workflows.triggers.permissions.set,im.list,im.mark,mpim.list,mpim.mark"; + // 320 endpoints as of November 11, 2026 (apps.user.connection.bulkUpdate and requestAuth added ahead of their docs.slack.dev pages) + String methods = "admin.analytics.getFile,admin.apps.activities.list,admin.apps.approve,admin.apps.clearResolution,admin.apps.restrict,admin.apps.uninstall,admin.apps.approved.list,admin.apps.config.lookup,admin.apps.config.set,admin.apps.requests.cancel,admin.apps.requests.list,admin.apps.restricted.list,admin.audit.anomaly.allow.getItem,admin.audit.anomaly.allow.updateItem,admin.auth.policy.assignEntities,admin.auth.policy.getEntities,admin.auth.policy.removeEntities,admin.barriers.create,admin.barriers.delete,admin.barriers.list,admin.barriers.update,admin.conversations.archive,admin.conversations.bulkArchive,admin.conversations.bulkDelete,admin.conversations.bulkMove,admin.conversations.convertToPrivate,admin.conversations.convertToPublic,admin.conversations.create,admin.conversations.createForObjects,admin.conversations.delete,admin.conversations.disconnectShared,admin.conversations.getConversationPrefs,admin.conversations.getCustomRetention,admin.conversations.getTeams,admin.conversations.invite,admin.conversations.linkObjects,admin.conversations.lookup,admin.conversations.removeCustomRetention,admin.conversations.rename,admin.conversations.search,admin.conversations.setConversationPrefs,admin.conversations.setCustomRetention,admin.conversations.setTeams,admin.conversations.unarchive,admin.conversations.unlinkObjects,admin.conversations.ekm.listOriginalConnectedChannelInfo,admin.conversations.restrictAccess.addGroup,admin.conversations.restrictAccess.listGroups,admin.conversations.restrictAccess.removeGroup,admin.emoji.add,admin.emoji.addAlias,admin.emoji.list,admin.emoji.remove,admin.emoji.rename,admin.functions.list,admin.functions.permissions.lookup,admin.functions.permissions.set,admin.inviteRequests.approve,admin.inviteRequests.deny,admin.inviteRequests.list,admin.inviteRequests.approved.list,admin.inviteRequests.denied.list,admin.roles.addAssignments,admin.roles.listAssignments,admin.roles.removeAssignments,admin.slackbot.skills.list,admin.teams.admins.list,admin.teams.create,admin.teams.list,admin.teams.owners.list,admin.teams.settings.info,admin.teams.settings.setDefaultChannels,admin.teams.settings.setDescription,admin.teams.settings.setDiscoverability,admin.teams.settings.setIcon,admin.teams.settings.setName,admin.usergroups.addChannels,admin.usergroups.addTeams,admin.usergroups.listChannels,admin.usergroups.removeChannels,admin.users.assign,admin.users.getExpiration,admin.users.invite,admin.users.list,admin.users.remove,admin.users.setAdmin,admin.users.setExpiration,admin.users.setOwner,admin.users.setRegular,admin.users.session.clearSettings,admin.users.session.getSettings,admin.users.session.invalidate,admin.users.session.list,admin.users.session.reset,admin.users.session.resetBulk,admin.users.session.setSettings,admin.users.unsupportedVersions.export,admin.workflows.collaborators.add,admin.workflows.collaborators.remove,admin.workflows.permissions.lookup,admin.workflows.search,admin.workflows.unpublish,admin.workflows.triggers.types.permissions.lookup,admin.workflows.triggers.types.permissions.set,api.test,apps.activities.list,apps.auth.external.delete,apps.auth.external.get,apps.connections.open,apps.datastore.bulkDelete,apps.datastore.bulkGet,apps.datastore.bulkPut,apps.datastore.count,apps.datastore.delete,apps.datastore.get,apps.datastore.put,apps.datastore.query,apps.datastore.update,apps.event.authorizations.list,apps.manifest.create,apps.manifest.delete,apps.manifest.export,apps.manifest.update,apps.manifest.validate,apps.uninstall,apps.user.connection.bulkUpdate,apps.user.connection.requestAuth,apps.user.connection.update,assistant.search.context,assistant.threads.setStatus,assistant.threads.setSuggestedPrompts,assistant.threads.setTitle,auth.revoke,auth.test,auth.teams.list,blocks.validate,bookmarks.add,bookmarks.edit,bookmarks.list,bookmarks.remove,bots.info,calls.add,calls.end,calls.info,calls.update,calls.participants.add,calls.participants.remove,canvases.access.delete,canvases.access.set,canvases.create,canvases.delete,canvases.edit,canvases.getContent,canvases.sections.lookup,channels.mark,chat.appendStream,chat.delete,chat.deleteScheduledMessage,chat.getPermalink,chat.meMessage,chat.postEphemeral,chat.postMessage,chat.scheduleMessage,chat.startStream,chat.stopStream,chat.unfurl,chat.update,chat.scheduledMessages.list,conversations.acceptSharedInvite,conversations.approveSharedInvite,conversations.archive,conversations.close,conversations.create,conversations.declineSharedInvite,conversations.history,conversations.info,conversations.invite,conversations.inviteShared,conversations.join,conversations.kick,conversations.leave,conversations.list,conversations.listConnectInvites,conversations.mark,conversations.members,conversations.open,conversations.rename,conversations.replies,conversations.setPurpose,conversations.setTopic,conversations.unarchive,conversations.canvases.create,conversations.externalInvitePermissions.set,conversations.requestSharedInvite.approve,conversations.requestSharedInvite.deny,conversations.requestSharedInvite.list,dialog.open,dnd.endDnd,dnd.endSnooze,dnd.info,dnd.setSnooze,dnd.teamInfo,emoji.list,files.comments.delete,files.completeUploadExternal,files.delete,files.getUploadURLExternal,files.info,files.list,files.revokePublicURL,files.sharedPublicURL,files.upload,files.remote.add,files.remote.info,files.remote.list,files.remote.remove,files.remote.share,files.remote.update,functions.completeError,functions.completeSuccess,functions.distributions.permissions.add,functions.distributions.permissions.list,functions.distributions.permissions.remove,functions.distributions.permissions.set,functions.workflows.steps.list,functions.workflows.steps.responses.export,groups.mark,migration.exchange,oauth.access,oauth.v2.access,oauth.v2.exchange,openid.connect.token,openid.connect.userInfo,pins.add,pins.list,pins.remove,reactions.add,reactions.get,reactions.list,reactions.remove,reminders.add,reminders.complete,reminders.delete,reminders.info,reminders.list,rtm.connect,rtm.start,search.all,search.files,search.messages,slackbot.skills.create,slackbot.skills.info,slackbot.skills.library.add,slackbot.skills.library.remove,slackbot.skills.list,slackbot.skills.update,slackLists.access.delete,slackLists.access.set,slackLists.create,slackLists.download.get,slackLists.download.start,slackLists.items.create,slackLists.items.delete,slackLists.items.deleteMultiple,slackLists.items.info,slackLists.items.list,slackLists.items.update,slackLists.update,stars.add,stars.list,stars.remove,team.accessLogs,team.billableInfo,team.info,team.integrationLogs,team.billing.info,team.externalTeams.disconnect,team.externalTeams.list,team.preferences.list,team.profile.get,tooling.tokens.rotate,usergroups.create,usergroups.disable,usergroups.enable,usergroups.list,usergroups.update,usergroups.users.list,usergroups.users.update,users.conversations,users.deletePhoto,users.getPresence,users.identity,users.info,users.list,users.lookupByEmail,users.setActive,users.setPhoto,users.setPresence,users.discoverableContacts.lookup,users.profile.get,users.profile.set,views.open,views.publish,views.push,views.update,workflows.featured.add,workflows.featured.list,workflows.featured.remove,workflows.featured.set,workflows.stepCompleted,workflows.stepFailed,workflows.updateStep,workflows.triggers.permissions.add,workflows.triggers.permissions.list,workflows.triggers.permissions.remove,workflows.triggers.permissions.set,im.list,im.mark,mpim.list,mpim.mark"; final List existingMethods = new ArrayList<>(); for (Field f : Methods.class.getDeclaredFields()) { int modifiers = f.getModifiers(); 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 d24132132..d389a6aa6 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 @@ -212,6 +212,22 @@ public void adminRoles() throws Exception { .get().isOk(), is(true)); } + @Test + public void adminSlackbotSkills() throws Exception { + AsyncMethodsClient methods = slack.methodsAsync(ValidToken); + + assertThat(methods.adminSlackbotSkillsList(r -> r + .category("productivity") + .cursor("xxx") + .limit(100) + .creatorIds(Arrays.asList("U0123ABCD")) + .publishStatus("published") + .autoEnabledStatus("enabled") + .sort("usage_count") + .sortDir("desc")) + .get().isOk(), is(true)); + } + @Test public void adminTeams() throws Exception { AsyncMethodsClient methods = slack.methodsAsync(ValidToken); diff --git a/slack-api-client/src/test/java/test_locally/api/methods_admin_api/AdminApiTest.java b/slack-api-client/src/test/java/test_locally/api/methods_admin_api/AdminApiTest.java index 5456d9b01..d4f57c0ec 100644 --- a/slack-api-client/src/test/java/test_locally/api/methods_admin_api/AdminApiTest.java +++ b/slack-api-client/src/test/java/test_locally/api/methods_admin_api/AdminApiTest.java @@ -194,6 +194,21 @@ public void adminRoles() throws Exception { assertThat(methods.adminRolesRemoveAssignments(r -> r).isOk(), is(true)); } + @Test + public void adminSlackbotSkills() throws Exception { + MethodsClient methods = slack.methods(ValidToken); + + assertThat(methods.adminSlackbotSkillsList(r -> r + .category("productivity") + .cursor("xxx") + .limit(100) + .creatorIds(Arrays.asList("U0123ABCD")) + .publishStatus("published") + .autoEnabledStatus("enabled") + .sort("usage_count") + .sortDir("desc")).isOk(), is(true)); + } + @Test public void adminTeams() throws Exception { MethodsClient methods = slack.methods(ValidToken); diff --git a/slack-api-client/src/test/java/test_with_remote_apis/methods_admin_api/AdminApi_slackbot_skills_Test.java b/slack-api-client/src/test/java/test_with_remote_apis/methods_admin_api/AdminApi_slackbot_skills_Test.java new file mode 100644 index 000000000..fe7092deb --- /dev/null +++ b/slack-api-client/src/test/java/test_with_remote_apis/methods_admin_api/AdminApi_slackbot_skills_Test.java @@ -0,0 +1,55 @@ +package test_with_remote_apis.methods_admin_api; + +import com.slack.api.Slack; +import com.slack.api.methods.MethodsClient; +import com.slack.api.methods.response.admin.slackbot.skills.AdminSlackbotSkillsListResponse; +import config.Constants; +import config.SlackTestConfig; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.util.Arrays; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.notNullValue; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +@Slf4j +public class AdminApi_slackbot_skills_Test { + + static SlackTestConfig testConfig = SlackTestConfig.getInstance(); + static Slack slack = Slack.getInstance(testConfig.getConfig()); + + @BeforeClass + public static void setUp() throws Exception { + SlackTestConfig.initializeRawJSONDataFiles("admin.slackbot.skills.*"); + } + + @AfterClass + public static void tearDown() throws InterruptedException { + SlackTestConfig.awaitCompletion(testConfig); + } + + static String orgAdminUserToken = System.getenv(Constants.SLACK_SDK_TEST_GRID_ORG_ADMIN_USER_TOKEN); + + @Test + public void list() throws Exception { + if (orgAdminUserToken != null) { + MethodsClient client = slack.methods(orgAdminUserToken); + for (String sort : Arrays.asList("name", "usage_count", "date_updated")) { + AdminSlackbotSkillsListResponse list = client.adminSlackbotSkillsList(r -> r + .limit(100) + .publishStatus("all") + .autoEnabledStatus("all") + .sort(sort) + .sortDir("desc")); + assertThat(list.getError(), is(nullValue())); + assertThat(list.getSkills(), is(notNullValue())); + assertThat(list.getResponseMetadata(), is(notNullValue())); + } + } + } +} From 40e1ab15f47bed2729b91b817b98c7b4f4d0dbbe Mon Sep 17 00:00:00 2001 From: Eden Zimbelman Date: Wed, 11 Nov 2026 23:09:53 -0800 Subject: [PATCH 2/2] test: add admin.slackbot.skills.list response deserialization test Parses a live admin.slackbot.skills.list response with unknown properties failing the test. Co-Authored-By: Claude --- .../api/methods/SlackbotSkillsTest.java | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/slack-api-client/src/test/java/test_locally/api/methods/SlackbotSkillsTest.java b/slack-api-client/src/test/java/test_locally/api/methods/SlackbotSkillsTest.java index 820022d48..453afbf66 100644 --- a/slack-api-client/src/test/java/test_locally/api/methods/SlackbotSkillsTest.java +++ b/slack-api-client/src/test/java/test_locally/api/methods/SlackbotSkillsTest.java @@ -2,6 +2,7 @@ import com.slack.api.Slack; import com.slack.api.SlackConfig; +import com.slack.api.methods.response.admin.slackbot.skills.AdminSlackbotSkillsListResponse; import com.slack.api.methods.response.slackbot.skills.SlackbotSkillsCreateResponse; import com.slack.api.methods.response.slackbot.skills.SlackbotSkillsInfoResponse; import com.slack.api.methods.response.slackbot.skills.SlackbotSkillsListResponse; @@ -126,6 +127,50 @@ public void test_async() throws Exception { ).get().isOk(), is(true)); } + @Test + public void adminSlackbotSkillsListResponse() { + SlackConfig strict = new SlackConfig(); + strict.setFailOnUnknownProperties(true); + + String json = "{" + + " \"ok\": true," + + " \"skills\": [" + + " {" + + " \"id\": \"F0123ABCD\"," + + " \"display_name\": \"Daily priorities\"," + + " \"description\": null," + + " \"category\": null," + + " \"creator_id\": \"U0123ABCD\"," + + " \"date_created\": 1794467171," + + " \"date_updated\": 1794467171," + + " \"visibility\": \"anyone_can_view\"," + + " \"is_official\": true," + + " \"usage_count\": 0," + + " \"library_count\": 1," + + " \"auto_enabled\": {" + + " \"permission_type\": \"named_entities\"," + + " \"usergroup_ids\": [" + + " \"S0123ABCD\"" + + " ]" + + " }" + + " }" + + " ]," + + " \"response_metadata\": {" + + " \"next_cursor\": \"dGVhbTpDMDYxRkE1UEI=\"" + + " }" + + "}"; + AdminSlackbotSkillsListResponse response = GsonFactory.createSnakeCase(strict).fromJson(json, AdminSlackbotSkillsListResponse.class); + assertThat(response.isOk(), is(true)); + assertThat(response.getSkills().get(0).getId(), is("F0123ABCD")); + assertThat(response.getSkills().get(0).getDescription(), is(nullValue())); + assertThat(response.getSkills().get(0).getVisibility(), is("anyone_can_view")); + assertThat(response.getSkills().get(0).getIsOfficial(), is(true)); + assertThat(response.getSkills().get(0).getLibraryCount(), is(1)); + assertThat(response.getSkills().get(0).getAutoEnabled().getPermissionType(), is("named_entities")); + assertThat(response.getSkills().get(0).getAutoEnabled().getUsergroupIds(), is(Collections.singletonList("S0123ABCD"))); + assertThat(response.getResponseMetadata().getNextCursor(), is("dGVhbTpDMDYxRkE1UEI=")); + } + @Test public void slackbotSkillsCreateResponse() { SlackConfig strict = new SlackConfig();