diff --git a/bolt-servlet/src/test/java/samples/EventsSample_SlackConnectInvites.java b/bolt-servlet/src/test/java/samples/EventsSample_SlackConnectInvites.java new file mode 100644 index 000000000..34a1c758e --- /dev/null +++ b/bolt-servlet/src/test/java/samples/EventsSample_SlackConnectInvites.java @@ -0,0 +1,41 @@ +package samples; + +import com.slack.api.bolt.App; +import com.slack.api.bolt.AppConfig; +import com.slack.api.model.event.SharedChannelInviteAcceptedEvent; +import com.slack.api.model.event.SharedChannelInviteApprovedEvent; +import com.slack.api.model.event.SharedChannelInviteDeclinedEvent; +import com.slack.api.model.event.SharedChannelInviteReceivedEvent; +import lombok.extern.slf4j.Slf4j; +import util.ResourceLoader; +import util.TestSlackAppServer; + +@Slf4j +public class EventsSample_SlackConnectInvites { + + public static void main(String[] args) throws Exception { + AppConfig config = ResourceLoader.loadAppConfig("appConfig_SlackConnectReceiver.json"); + App app = new App(config); + + app.event(SharedChannelInviteReceivedEvent.class, (event, ctx) -> { + ctx.logger.info("received - {}", event); + return ctx.ack(); + }); + app.event(SharedChannelInviteAcceptedEvent.class, (event, ctx) -> { + ctx.logger.info("accepted - {}", event); + return ctx.ack(); + }); + app.event(SharedChannelInviteApprovedEvent.class, (event, ctx) -> { + ctx.logger.info("approved - {}", event); + return ctx.ack(); + }); + app.event(SharedChannelInviteDeclinedEvent.class, (event, ctx) -> { + ctx.logger.info("declined - {}", event); + return ctx.ack(); + }); + + TestSlackAppServer server = new TestSlackAppServer(app); + server.start(); + } + +} diff --git a/json-logs/samples/api/conversations.acceptSharedInvite.json b/json-logs/samples/api/conversations.acceptSharedInvite.json new file mode 100644 index 000000000..fd276a527 --- /dev/null +++ b/json-logs/samples/api/conversations.acceptSharedInvite.json @@ -0,0 +1,9 @@ +{ + "ok": false, + "error": "", + "implicit_approval": false, + "channel_id": "C00000000", + "invite_id": "I00000000", + "needed": "", + "provided": "" +} \ No newline at end of file diff --git a/json-logs/samples/api/conversations.approveSharedInvite.json b/json-logs/samples/api/conversations.approveSharedInvite.json new file mode 100644 index 000000000..1b3fc766f --- /dev/null +++ b/json-logs/samples/api/conversations.approveSharedInvite.json @@ -0,0 +1,6 @@ +{ + "ok": false, + "error": "", + "needed": "", + "provided": "" +} \ No newline at end of file diff --git a/json-logs/samples/api/conversations.declineSharedInvite.json b/json-logs/samples/api/conversations.declineSharedInvite.json new file mode 100644 index 000000000..1b3fc766f --- /dev/null +++ b/json-logs/samples/api/conversations.declineSharedInvite.json @@ -0,0 +1,6 @@ +{ + "ok": false, + "error": "", + "needed": "", + "provided": "" +} \ No newline at end of file diff --git a/json-logs/samples/api/conversations.inviteShared.json b/json-logs/samples/api/conversations.inviteShared.json new file mode 100644 index 000000000..785274b10 --- /dev/null +++ b/json-logs/samples/api/conversations.inviteShared.json @@ -0,0 +1,10 @@ +{ + "ok": false, + "error": "", + "url": "https://www.example.com/", + "invite_id": "I00000000", + "conf_code": "", + "is_legacy_shared_channel": false, + "needed": "", + "provided": "" +} \ No newline at end of file diff --git a/json-logs/samples/api/conversations.listConnectInvites.json b/json-logs/samples/api/conversations.listConnectInvites.json new file mode 100644 index 000000000..24da2794c --- /dev/null +++ b/json-logs/samples/api/conversations.listConnectInvites.json @@ -0,0 +1,146 @@ +{ + "ok": false, + "error": "", + "arg": "", + "invites": [ + { + "direction": "", + "status": "", + "date_last_updated": 12345, + "invite_type": "", + "invite": { + "id": "I00000000", + "date_created": 12345, + "date_invalid": 12345, + "inviting_team": { + "id": "E00000000", + "name": "", + "icon": { + "image_102": "https://www.example.com/", + "image_132": "https://www.example.com/", + "image_230": "https://www.example.com/", + "image_34": "https://www.example.com/", + "image_44": "https://www.example.com/", + "image_68": "https://www.example.com/", + "image_88": "https://www.example.com/", + "image_default": false, + "image_original": "https://www.example.com/" + }, + "is_verified": false, + "domain": "", + "date_created": 12345 + }, + "inviting_user": { + "id": "U00000000", + "team_id": "E00000000", + "name": "", + "updated": 12345, + "profile": { + "real_name": "", + "display_name": "", + "real_name_normalized": "", + "display_name_normalized": "", + "team": "E00000000", + "avatar_hash": "", + "email": "", + "image_24": "https://www.example.com/", + "image_32": "https://www.example.com/", + "image_48": "https://www.example.com/", + "image_72": "https://www.example.com/", + "image_192": "https://www.example.com/", + "image_512": "https://www.example.com/", + "image_1024": "https://www.example.com/", + "image_original": "https://www.example.com/", + "is_custom_image": false + } + }, + "link": "https://www.example.com/", + "recipient_user_id": "U00000000", + "recipient_email": "" + }, + "channel": { + "id": "C00000000", + "is_im": false, + "is_private": false, + "name": "" + }, + "acceptances": [ + { + "approval_status": "", + "date_accepted": 12345, + "date_invalid": 12345, + "date_last_updated": 12345, + "accepting_team": { + "id": "T00000000", + "name": "", + "icon": { + "image_102": "https://www.example.com/", + "image_132": "https://www.example.com/", + "image_230": "https://www.example.com/", + "image_34": "https://www.example.com/", + "image_44": "https://www.example.com/", + "image_68": "https://www.example.com/", + "image_88": "https://www.example.com/", + "image_original": "https://www.example.com/" + }, + "is_verified": false, + "domain": "", + "date_created": 12345 + }, + "accepting_user": { + "id": "U00000000", + "team_id": "T00000000", + "name": "", + "updated": 12345, + "profile": { + "real_name": "", + "display_name": "", + "real_name_normalized": "", + "display_name_normalized": "", + "team": "T00000000", + "avatar_hash": "", + "email": "", + "image_24": "https://www.example.com/", + "image_32": "https://www.example.com/", + "image_48": "https://www.example.com/", + "image_72": "https://www.example.com/", + "image_192": "https://www.example.com/", + "image_512": "https://www.example.com/" + } + }, + "reviews": [ + { + "type": "", + "date_review": 12345, + "reviewing_team": { + "id": "T00000000", + "name": "", + "icon": { + "image_102": "https://www.example.com/", + "image_132": "https://www.example.com/", + "image_230": "https://www.example.com/", + "image_34": "https://www.example.com/", + "image_44": "https://www.example.com/", + "image_68": "https://www.example.com/", + "image_88": "https://www.example.com/", + "image_original": "https://www.example.com/" + }, + "is_verified": false, + "domain": "", + "date_created": 12345 + } + } + ] + } + ] + } + ], + "response_metadata": { + "next_cursor": "", + "messages": [ + "" + ] + }, + "needed": "", + "provided": "" +} \ No newline at end of file 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 abe7e1cc0..c55452ae2 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 @@ -795,6 +795,29 @@ CompletableFuture CompletableFuture conversationsUnarchive(RequestConfigurator req); + // ------------- + // Slack Connect + + CompletableFuture conversationsInviteShared(ConversationsInviteSharedRequest req); + + CompletableFuture conversationsInviteShared(RequestConfigurator req); + + CompletableFuture conversationsAcceptSharedInvite(ConversationsAcceptSharedInviteRequest req); + + CompletableFuture conversationsAcceptSharedInvite(RequestConfigurator req); + + CompletableFuture conversationsApproveSharedInvite(ConversationsApproveSharedInviteRequest req); + + CompletableFuture conversationsApproveSharedInvite(RequestConfigurator req); + + CompletableFuture conversationsDeclineSharedInvite(ConversationsDeclineSharedInviteRequest req); + + CompletableFuture conversationsDeclineSharedInvite(RequestConfigurator req); + + CompletableFuture conversationsListConnectInvites(ConversationsListConnectInvitesRequest req); + + CompletableFuture conversationsListConnectInvites(RequestConfigurator req); + // ------------------------------ // dialog // ------------------------------ 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 2375ae551..bf2a30b8c 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 @@ -326,6 +326,13 @@ private Methods() { public static final String CONVERSATIONS_SET_TOPIC = "conversations.setTopic"; public static final String CONVERSATIONS_UNARCHIVE = "conversations.unarchive"; + // Slack Connect APIs + public static final String CONVERSATIONS_INVITE_SHARED = "conversations.inviteShared"; + public static final String CONVERSATIONS_ACCEPT_SHARED_INVITE = "conversations.acceptSharedInvite"; + public static final String CONVERSATIONS_APPROVE_SHARED_INVITE = "conversations.approveSharedInvite"; + public static final String CONVERSATIONS_DECLINE_SHARED_INVITE = "conversations.declineSharedInvite"; + public static final String CONVERSATIONS_LIST_CONNECT_INVITES = "conversations.listConnectInvites"; + // ------------------------------ // dialog // ------------------------------ 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 2973fb1fc..f809307de 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 @@ -1078,6 +1078,29 @@ AdminUsergroupsRemoveChannelsResponse adminUsergroupsRemoveChannels( ConversationsUnarchiveResponse conversationsUnarchive(RequestConfigurator req) throws IOException, SlackApiException; + // ------------- + // Slack Connect + + ConversationsInviteSharedResponse conversationsInviteShared(ConversationsInviteSharedRequest req) throws IOException, SlackApiException; + + ConversationsInviteSharedResponse conversationsInviteShared(RequestConfigurator req) throws IOException, SlackApiException; + + ConversationsAcceptSharedInviteResponse conversationsAcceptSharedInvite(ConversationsAcceptSharedInviteRequest req) throws IOException, SlackApiException; + + ConversationsAcceptSharedInviteResponse conversationsAcceptSharedInvite(RequestConfigurator req) throws IOException, SlackApiException; + + ConversationsApproveSharedInviteResponse conversationsApproveSharedInvite(ConversationsApproveSharedInviteRequest req) throws IOException, SlackApiException; + + ConversationsApproveSharedInviteResponse conversationsApproveSharedInvite(RequestConfigurator req) throws IOException, SlackApiException; + + ConversationsDeclineSharedInviteResponse conversationsDeclineSharedInvite(ConversationsDeclineSharedInviteRequest req) throws IOException, SlackApiException; + + ConversationsDeclineSharedInviteResponse conversationsDeclineSharedInvite(RequestConfigurator req) throws IOException, SlackApiException; + + ConversationsListConnectInvitesResponse conversationsListConnectInvites(ConversationsListConnectInvitesRequest req) throws IOException, SlackApiException; + + ConversationsListConnectInvitesResponse conversationsListConnectInvites(RequestConfigurator req) throws IOException, SlackApiException; + // ------------------------------ // dialog // ------------------------------ 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 2f7482751..85bdabaaa 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 @@ -276,6 +276,12 @@ public static void setRateLimitTier(String methodName, MethodsRateLimitTier tier setRateLimitTier(MPIM_MARK, Tier3); setRateLimitTier(GROUPS_CREATE_CHILD, Tier2); + setRateLimitTier(CONVERSATIONS_INVITE_SHARED, Tier2); + setRateLimitTier(CONVERSATIONS_ACCEPT_SHARED_INVITE, Tier1); + setRateLimitTier(CONVERSATIONS_APPROVE_SHARED_INVITE, Tier1); + setRateLimitTier(CONVERSATIONS_DECLINE_SHARED_INVITE, Tier1); + setRateLimitTier(CONVERSATIONS_LIST_CONNECT_INVITES, Tier1); + setRateLimitTier(DIALOG_OPEN, Tier4); setRateLimitTier(DND_END_DND, Tier2); 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 aabd2864c..4f8b72b37 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 @@ -1349,6 +1349,51 @@ public static FormBody.Builder toForm(ConversationsUnarchiveRequest req) { return form; } + public static FormBody.Builder toForm(ConversationsInviteSharedRequest req) { + FormBody.Builder form = new FormBody.Builder(); + setIfNotNull("channel", req.getChannel(), form); + if (req.getEmails() != null) { + setIfNotNull("emails", req.getEmails().stream().collect(joining(",")), form); + } + if (req.getUserIds() != null) { + setIfNotNull("user_ids", req.getUserIds().stream().collect(joining(",")), form); + } + return form; + } + + public static FormBody.Builder toForm(ConversationsAcceptSharedInviteRequest req) { + FormBody.Builder form = new FormBody.Builder(); + setIfNotNull("channel_name", req.getChannelName(), form); + setIfNotNull("channel_id", req.getChannelId(), form); + setIfNotNull("free_trial_accept", req.getFreeTrialAccept(), form); + setIfNotNull("invite_id", req.getInviteId(), form); + setIfNotNull("is_private", req.getIsPrivate(), form); + setIfNotNull("team_id", req.getTeamId(), form); + return form; + } + + public static FormBody.Builder toForm(ConversationsApproveSharedInviteRequest req) { + FormBody.Builder form = new FormBody.Builder(); + setIfNotNull("invite_id", req.getInviteId(), form); + setIfNotNull("target_team", req.getTargetTeam(), form); + return form; + } + + public static FormBody.Builder toForm(ConversationsDeclineSharedInviteRequest req) { + FormBody.Builder form = new FormBody.Builder(); + setIfNotNull("invite_id", req.getInviteId(), form); + setIfNotNull("target_team", req.getTargetTeam(), form); + return form; + } + + public static FormBody.Builder toForm(ConversationsListConnectInvitesRequest req) { + FormBody.Builder form = new FormBody.Builder(); + setIfNotNull("count", req.getCount(), form); + setIfNotNull("cursor", req.getCursor(), form); + setIfNotNull("team_id", req.getTeamId(), form); + return form; + } + public static FormBody.Builder toForm(DialogOpenRequest req) { FormBody.Builder form = new FormBody.Builder(); setIfNotNull("trigger_id", req.getTriggerId(), 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 2901ec637..6d09dd965 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 @@ -1386,6 +1386,56 @@ public CompletableFuture conversationsUnarchive( return conversationsUnarchive(req.configure(ConversationsUnarchiveRequest.builder()).build()); } + @Override + public CompletableFuture conversationsInviteShared(ConversationsInviteSharedRequest req) { + return executor.execute(CONVERSATIONS_INVITE_SHARED, toMap(req), () -> methods.conversationsInviteShared(req)); + } + + @Override + public CompletableFuture conversationsInviteShared(RequestConfigurator req) { + return conversationsInviteShared(req.configure(ConversationsInviteSharedRequest.builder()).build()); + } + + @Override + public CompletableFuture conversationsAcceptSharedInvite(ConversationsAcceptSharedInviteRequest req) { + return executor.execute(CONVERSATIONS_ACCEPT_SHARED_INVITE, toMap(req), () -> methods.conversationsAcceptSharedInvite(req)); + } + + @Override + public CompletableFuture conversationsAcceptSharedInvite(RequestConfigurator req) { + return conversationsAcceptSharedInvite(req.configure(ConversationsAcceptSharedInviteRequest.builder()).build()); + } + + @Override + public CompletableFuture conversationsApproveSharedInvite(ConversationsApproveSharedInviteRequest req) { + return executor.execute(CONVERSATIONS_APPROVE_SHARED_INVITE, toMap(req), () -> methods.conversationsApproveSharedInvite(req)); + } + + @Override + public CompletableFuture conversationsApproveSharedInvite(RequestConfigurator req) { + return conversationsApproveSharedInvite(req.configure(ConversationsApproveSharedInviteRequest.builder()).build()); + } + + @Override + public CompletableFuture conversationsDeclineSharedInvite(ConversationsDeclineSharedInviteRequest req) { + return executor.execute(CONVERSATIONS_DECLINE_SHARED_INVITE, toMap(req), () -> methods.conversationsDeclineSharedInvite(req)); + } + + @Override + public CompletableFuture conversationsDeclineSharedInvite(RequestConfigurator req) { + return conversationsDeclineSharedInvite(req.configure(ConversationsDeclineSharedInviteRequest.builder()).build()); + } + + @Override + public CompletableFuture conversationsListConnectInvites(ConversationsListConnectInvitesRequest req) { + return executor.execute(CONVERSATIONS_LIST_CONNECT_INVITES, toMap(req), () -> methods.conversationsListConnectInvites(req)); + } + + @Override + public CompletableFuture conversationsListConnectInvites(RequestConfigurator req) { + return conversationsListConnectInvites(req.configure(ConversationsListConnectInvitesRequest.builder()).build()); + } + @Override public CompletableFuture dialogOpen(DialogOpenRequest req) { return executor.execute(DIALOG_OPEN, toMap(req), () -> methods.dialogOpen(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 4a377eb74..a9912787a 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 @@ -1643,6 +1643,56 @@ public ConversationsUnarchiveResponse conversationsUnarchive(RequestConfigurator return conversationsUnarchive(req.configure(ConversationsUnarchiveRequest.builder()).build()); } + @Override + public ConversationsInviteSharedResponse conversationsInviteShared(ConversationsInviteSharedRequest req) throws IOException, SlackApiException { + return postFormWithTokenAndParseResponse(toForm(req), Methods.CONVERSATIONS_INVITE_SHARED, getToken(req), ConversationsInviteSharedResponse.class); + } + + @Override + public ConversationsInviteSharedResponse conversationsInviteShared(RequestConfigurator req) throws IOException, SlackApiException { + return conversationsInviteShared(req.configure(ConversationsInviteSharedRequest.builder()).build()); + } + + @Override + public ConversationsAcceptSharedInviteResponse conversationsAcceptSharedInvite(ConversationsAcceptSharedInviteRequest req) throws IOException, SlackApiException { + return postFormWithTokenAndParseResponse(toForm(req), Methods.CONVERSATIONS_ACCEPT_SHARED_INVITE, getToken(req), ConversationsAcceptSharedInviteResponse.class); + } + + @Override + public ConversationsAcceptSharedInviteResponse conversationsAcceptSharedInvite(RequestConfigurator req) throws IOException, SlackApiException { + return conversationsAcceptSharedInvite(req.configure(ConversationsAcceptSharedInviteRequest.builder()).build()); + } + + @Override + public ConversationsApproveSharedInviteResponse conversationsApproveSharedInvite(ConversationsApproveSharedInviteRequest req) throws IOException, SlackApiException { + return postFormWithTokenAndParseResponse(toForm(req), Methods.CONVERSATIONS_APPROVE_SHARED_INVITE, getToken(req), ConversationsApproveSharedInviteResponse.class); + } + + @Override + public ConversationsApproveSharedInviteResponse conversationsApproveSharedInvite(RequestConfigurator req) throws IOException, SlackApiException { + return conversationsApproveSharedInvite(req.configure(ConversationsApproveSharedInviteRequest.builder()).build()); + } + + @Override + public ConversationsDeclineSharedInviteResponse conversationsDeclineSharedInvite(ConversationsDeclineSharedInviteRequest req) throws IOException, SlackApiException { + return postFormWithTokenAndParseResponse(toForm(req), Methods.CONVERSATIONS_DECLINE_SHARED_INVITE, getToken(req), ConversationsDeclineSharedInviteResponse.class); + } + + @Override + public ConversationsDeclineSharedInviteResponse conversationsDeclineSharedInvite(RequestConfigurator req) throws IOException, SlackApiException { + return conversationsDeclineSharedInvite(req.configure(ConversationsDeclineSharedInviteRequest.builder()).build()); + } + + @Override + public ConversationsListConnectInvitesResponse conversationsListConnectInvites(ConversationsListConnectInvitesRequest req) throws IOException, SlackApiException { + return postFormWithTokenAndParseResponse(toForm(req), Methods.CONVERSATIONS_LIST_CONNECT_INVITES, getToken(req), ConversationsListConnectInvitesResponse.class); + } + + @Override + public ConversationsListConnectInvitesResponse conversationsListConnectInvites(RequestConfigurator req) throws IOException, SlackApiException { + return conversationsListConnectInvites(req.configure(ConversationsListConnectInvitesRequest.builder()).build()); + } + @Override public DialogOpenResponse dialogOpen(DialogOpenRequest req) throws IOException, SlackApiException { diff --git a/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsAcceptSharedInviteRequest.java b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsAcceptSharedInviteRequest.java new file mode 100644 index 000000000..25bd5d7f4 --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsAcceptSharedInviteRequest.java @@ -0,0 +1,45 @@ +package com.slack.api.methods.request.conversations; + +import com.slack.api.methods.SlackApiRequest; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ConversationsAcceptSharedInviteRequest implements SlackApiRequest { + + private String token; + + /** + * Name of the channel. If the channel does not exist already in your workspace, + * this name is the one that the channel will take. + */ + private String channelName; + + /** + * ID of the channel that you'd like to accept. Must provide either invite_id or channel_id. + */ + private String channelId; + + /** + * Whether you'd like to use your workspace's free trial to begin using Slack Connect. + */ + private Boolean freeTrialAccept; + + /** + * See the shared_channel_invite_received event payload for more details + * on how to retrieve the ID of the invitation. + */ + private String inviteId; + + /** + * Whether the channel should be private. + */ + private Boolean isPrivate; + + /** + * The ID of the workspace to accept the channel in. + * If an org-level token is used to call this method, the team_id argument is required. + */ + private String teamId; +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsApproveSharedInviteRequest.java b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsApproveSharedInviteRequest.java new file mode 100644 index 000000000..bef457e1f --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsApproveSharedInviteRequest.java @@ -0,0 +1,27 @@ +package com.slack.api.methods.request.conversations; + +import com.slack.api.methods.SlackApiRequest; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ConversationsApproveSharedInviteRequest 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; + + /** + * ID of the shared channel invite to approve + */ + private String inviteId; + + /** + * The team or enterprise id of the other party involved in the invitation you are approving + */ + private String targetTeam; + +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsDeclineSharedInviteRequest.java b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsDeclineSharedInviteRequest.java new file mode 100644 index 000000000..f1f996276 --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsDeclineSharedInviteRequest.java @@ -0,0 +1,28 @@ +package com.slack.api.methods.request.conversations; + +import com.slack.api.methods.SlackApiRequest; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ConversationsDeclineSharedInviteRequest 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; + + /** + * ID of the Slack Connect invite to decline. Subscribe to the shared_channel_invite_accepted event + * to receive IDs of Slack Connect channel invites that have been accepted and are awaiting approval. + */ + private String inviteId; + + /** + * The team or enterprise id of the other party involved in the invitation you are declining + */ + private String targetTeam; + +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsInviteSharedRequest.java b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsInviteSharedRequest.java new file mode 100644 index 000000000..16d5053cb --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsInviteSharedRequest.java @@ -0,0 +1,34 @@ +package com.slack.api.methods.request.conversations; + +import com.slack.api.methods.SlackApiRequest; +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +@Data +@Builder +public class ConversationsInviteSharedRequest 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; + + /** + * ID of the channel on your team that you'd like to share + */ + private String channel; + + /** + * Optional email to receive this invite. Either emails or user_ids must be provided. + */ + private List emails; + + /** + * Optional user_id to receive this invite. Either emails or user_ids must be provided. + */ + private List userIds; + +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsListConnectInvitesRequest.java b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsListConnectInvitesRequest.java new file mode 100644 index 000000000..0f6c4dacf --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/request/conversations/ConversationsListConnectInvitesRequest.java @@ -0,0 +1,33 @@ +package com.slack.api.methods.request.conversations; + +import com.slack.api.methods.SlackApiRequest; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +public class ConversationsListConnectInvitesRequest 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; + + /** + * Maximum number of invites to return + * Default: 100 + */ + private Integer count; + + /** + * Set to next_cursor returned by previous call to list items in subsequent page + */ + private String cursor; + + /** + * Encoded team id for the workspace to retrieve invites for, required if org token is used + */ + private String teamId; + +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsAcceptSharedInviteResponse.java b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsAcceptSharedInviteResponse.java new file mode 100644 index 000000000..91f196239 --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsAcceptSharedInviteResponse.java @@ -0,0 +1,18 @@ +package com.slack.api.methods.response.conversations; + +import com.slack.api.methods.SlackApiTextResponse; +import lombok.Data; + +@Data +public class ConversationsAcceptSharedInviteResponse implements SlackApiTextResponse { + + private boolean ok; + private String warning; + private String error; + private String needed; + private String provided; + + private boolean implicitApproval; + private String channelId; + private String inviteId; +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsApproveSharedInviteResponse.java b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsApproveSharedInviteResponse.java new file mode 100644 index 000000000..6d89ad6d7 --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsApproveSharedInviteResponse.java @@ -0,0 +1,14 @@ +package com.slack.api.methods.response.conversations; + +import com.slack.api.methods.SlackApiTextResponse; +import lombok.Data; + +@Data +public class ConversationsApproveSharedInviteResponse implements SlackApiTextResponse { + + private boolean ok; + private String warning; + private String error; + private String needed; + private String provided; +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsDeclineSharedInviteResponse.java b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsDeclineSharedInviteResponse.java new file mode 100644 index 000000000..28f1cf5e0 --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsDeclineSharedInviteResponse.java @@ -0,0 +1,14 @@ +package com.slack.api.methods.response.conversations; + +import com.slack.api.methods.SlackApiTextResponse; +import lombok.Data; + +@Data +public class ConversationsDeclineSharedInviteResponse implements SlackApiTextResponse { + + private boolean ok; + private String warning; + private String error; + private String needed; + private String provided; +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsInviteSharedResponse.java b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsInviteSharedResponse.java new file mode 100644 index 000000000..4b4ac6a71 --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsInviteSharedResponse.java @@ -0,0 +1,19 @@ +package com.slack.api.methods.response.conversations; + +import com.slack.api.methods.SlackApiTextResponse; +import lombok.Data; + +@Data +public class ConversationsInviteSharedResponse implements SlackApiTextResponse { + + private boolean ok; + private String warning; + private String error; + private String needed; + private String provided; + + private String url; // https://join.slack.com/share/... + private String inviteId; // I12345 + private String confCode; + private boolean isLegacySharedChannel; +} diff --git a/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsListConnectInvitesResponse.java b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsListConnectInvitesResponse.java new file mode 100644 index 000000000..1d3cc8d4c --- /dev/null +++ b/slack-api-client/src/main/java/com/slack/api/methods/response/conversations/ConversationsListConnectInvitesResponse.java @@ -0,0 +1,23 @@ +package com.slack.api.methods.response.conversations; + +import com.slack.api.methods.SlackApiTextResponse; +import com.slack.api.model.ResponseMetadata; +import com.slack.api.model.connect.ConnectInvite; +import lombok.Data; + +import java.util.List; + +@Data +public class ConversationsListConnectInvitesResponse implements SlackApiTextResponse { + + private boolean ok; + private String warning; + private String error; + private String needed; + private String provided; + private String arg; // for missing argument error (e.g., "team_id") + + private ResponseMetadata responseMetadata; + + private List invites; +} diff --git a/slack-api-client/src/test/java/config/Constants.java b/slack-api-client/src/test/java/config/Constants.java index e0bce3b34..57ccbdae3 100644 --- a/slack-api-client/src/test/java/config/Constants.java +++ b/slack-api-client/src/test/java/config/Constants.java @@ -41,6 +41,11 @@ private Constants() { public static final String SLACK_SDK_TEST_INCOMING_WEBHOOK_URL = "SLACK_SDK_TEST_INCOMING_WEBHOOK_URL"; public static final String SLACK_SDK_TEST_INCOMING_WEBHOOK_CHANNEL_NAME = "SLACK_SDK_TEST_INCOMING_WEBHOOK_CHANNEL_NAME"; + // Slack Connect API tests + public static final String SLACK_SDK_TEST_CONNECT_INVITE_SENDER_BOT_TOKEN = "SLACK_SDK_TEST_CONNECT_INVITE_SENDER_BOT_TOKEN"; + public static final String SLACK_SDK_TEST_CONNECT_INVITE_RECEIVER_BOT_TOKEN = "SLACK_SDK_TEST_CONNECT_INVITE_RECEIVER_BOT_TOKEN"; + public static final String SLACK_SDK_TEST_CONNECT_INVITE_RECEIVER_BOT_USER_ID = "SLACK_SDK_TEST_CONNECT_INVITE_RECEIVER_BOT_USER_ID"; + public static final String SLACK_SDK_TEST_EMAIL_ADDRESS = "SLACK_SDK_TEST_EMAIL_ADDRESS"; public static final String SLACK_SDK_TEST_REDIS_ENABLED = "SLACK_SDK_TEST_REDIS_ENABLED"; 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 4f436abe6..a7d38bd4c 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 @@ -39,13 +39,7 @@ public void verifyTheCoverage() { // TODO: https://github.com/slackapi/java-slack-sdk/issues/634 "admin.conversations.getCustomRetention", "admin.conversations.removeCustomRetention", - "admin.conversations.setCustomRetention", - // TODO: https://github.com/slackapi/java-slack-sdk/issues/773 - "conversations.acceptSharedInvite", - "conversations.approveSharedInvite", - "conversations.declineSharedInvite", - "conversations.inviteShared", - "conversations.listConnectInvites" + "admin.conversations.setCustomRetention" ); List methodNames = new ArrayList<>(); for (String methodName : allMethodNames) { diff --git a/slack-api-client/src/test/java/test_locally/api/methods/ConversationsTest.java b/slack-api-client/src/test/java/test_locally/api/methods/ConversationsTest.java index e516087c2..22ed246e9 100644 --- a/slack-api-client/src/test/java/test_locally/api/methods/ConversationsTest.java +++ b/slack-api-client/src/test/java/test_locally/api/methods/ConversationsTest.java @@ -2,7 +2,9 @@ import com.slack.api.Slack; import com.slack.api.SlackConfig; +import com.slack.api.methods.MethodsConfig; import com.slack.api.model.ConversationType; +import com.slack.api.scim.metrics.MemoryMetricsDatastore; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -17,13 +19,17 @@ public class ConversationsTest { MockSlackApiServer server = new MockSlackApiServer(); - SlackConfig config = new SlackConfig(); - Slack slack = Slack.getInstance(config); + Slack slack = null; @Before public void setup() throws Exception { server.start(); + SlackConfig config = new SlackConfig(); config.setMethodsEndpointUrlPrefix(server.getMethodsEndpointPrefix()); + config.setMethodsConfig(new MethodsConfig()); + // skip the burst traffic detection for these tests + config.getMethodsConfig().setStatsEnabled(false); + slack = Slack.getInstance(config); } @After @@ -70,6 +76,16 @@ public void test() throws Exception { .isOk(), is(true)); assertThat(slack.methods(ValidToken).conversationsUnarchive(r -> r.channel("C123")) .isOk(), is(true)); + assertThat(slack.methods(ValidToken).conversationsInviteShared(r -> r) + .isOk(), is(true)); + assertThat(slack.methods(ValidToken).conversationsAcceptSharedInvite(r -> r) + .isOk(), is(true)); + assertThat(slack.methods(ValidToken).conversationsApproveSharedInvite(r -> r) + .isOk(), is(true)); + assertThat(slack.methods(ValidToken).conversationsDeclineSharedInvite(r -> r) + .isOk(), is(true)); + assertThat(slack.methods(ValidToken).conversationsListConnectInvites(r -> r) + .isOk(), is(true)); } @Test @@ -111,6 +127,16 @@ public void test_async() throws Exception { .get().isOk(), is(true)); assertThat(slack.methodsAsync(ValidToken).conversationsUnarchive(r -> r.channel("C123")) .get().isOk(), is(true)); + assertThat(slack.methodsAsync(ValidToken).conversationsInviteShared(r -> r) + .get().isOk(), is(true)); + assertThat(slack.methodsAsync(ValidToken).conversationsAcceptSharedInvite(r -> r) + .get().isOk(), is(true)); + assertThat(slack.methodsAsync(ValidToken).conversationsApproveSharedInvite(r -> r) + .get().isOk(), is(true)); + assertThat(slack.methodsAsync(ValidToken).conversationsDeclineSharedInvite(r -> r) + .get().isOk(), is(true)); + assertThat(slack.methodsAsync(ValidToken).conversationsListConnectInvites(r -> r) + .get().isOk(), is(true)); } } diff --git a/slack-api-client/src/test/java/test_with_remote_apis/methods/conversations_connect_Test.java b/slack-api-client/src/test/java/test_with_remote_apis/methods/conversations_connect_Test.java new file mode 100644 index 000000000..2ba6a7313 --- /dev/null +++ b/slack-api-client/src/test/java/test_with_remote_apis/methods/conversations_connect_Test.java @@ -0,0 +1,105 @@ +package test_with_remote_apis.methods; + +import com.slack.api.Slack; +import com.slack.api.methods.MethodsClient; +import com.slack.api.methods.response.conversations.*; +import config.Constants; +import config.SlackTestConfig; +import lombok.extern.slf4j.Slf4j; +import org.junit.AfterClass; +import org.junit.Test; + +import java.util.Arrays; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.CoreMatchers.nullValue; +import static org.hamcrest.MatcherAssert.assertThat; + +@Slf4j +public class conversations_connect_Test { + + static SlackTestConfig testConfig = SlackTestConfig.getInstance(); + static Slack slack = Slack.getInstance(testConfig.getConfig()); + + @AfterClass + public static void tearDown() throws InterruptedException { + SlackTestConfig.awaitCompletion(testConfig); + } + + @Test + public void approval() throws Exception { + MethodsClient sender = slack.methods(System.getenv(Constants.SLACK_SDK_TEST_CONNECT_INVITE_SENDER_BOT_TOKEN)); + MethodsClient receiver = slack.methods(System.getenv(Constants.SLACK_SDK_TEST_CONNECT_INVITE_RECEIVER_BOT_TOKEN)); + + String channelName = "slack-connect-test-" + System.currentTimeMillis(); + + ConversationsCreateResponse channelCreation = sender.conversationsCreate(r -> r.name(channelName)); + assertThat(channelCreation.getError(), is(nullValue())); + String channelId = channelCreation.getChannel().getId(); + + try { + ConversationsInviteSharedResponse invitation = sender.conversationsInviteShared(r -> r + .channel(channelId) + .userIds(Arrays.asList(System.getenv(Constants.SLACK_SDK_TEST_CONNECT_INVITE_RECEIVER_BOT_USER_ID))) + ); + assertThat(invitation.getError(), is(nullValue())); + + String connectTeamId = receiver.authTest(r -> r).getTeamId(); + ConversationsListConnectInvitesResponse invites = receiver.conversationsListConnectInvites(r -> r + .count(10).teamId(connectTeamId)); + assertThat(invites.getError(), is(nullValue())); + + ConversationsAcceptSharedInviteResponse acceptance = receiver.conversationsAcceptSharedInvite(r -> r + .channelName(channelName) + .inviteId(invitation.getInviteId()) + ); + assertThat(acceptance.getError(), is(nullValue())); + + ConversationsApproveSharedInviteResponse approval = receiver.conversationsApproveSharedInvite(r -> r.inviteId(invitation.getInviteId())); + if (approval.getError() != null && approval.getError().equals("invalid_action")) { + // auto-approval is enabled in this workspace / org + } else { + assertThat(approval.getError(), is(nullValue())); + } + + } finally { + ConversationsArchiveResponse archive = sender.conversationsArchive(r -> r.channel(channelId)); + assertThat(archive.getError(), is(nullValue())); + } + } + + @Test + public void decline() throws Exception { + MethodsClient sender = slack.methods(System.getenv(Constants.SLACK_SDK_TEST_CONNECT_INVITE_SENDER_BOT_TOKEN)); + MethodsClient receiver = slack.methods(System.getenv(Constants.SLACK_SDK_TEST_CONNECT_INVITE_RECEIVER_BOT_TOKEN)); + + String channelName = "slack-connect-test-" + System.currentTimeMillis(); + + ConversationsCreateResponse channelCreation = sender.conversationsCreate(r -> r.name(channelName)); + assertThat(channelCreation.getError(), is(nullValue())); + String channelId = channelCreation.getChannel().getId(); + + try { + ConversationsInviteSharedResponse invitation = sender.conversationsInviteShared(r -> r + .channel(channelId) + .userIds(Arrays.asList(System.getenv(Constants.SLACK_SDK_TEST_CONNECT_INVITE_RECEIVER_BOT_USER_ID))) + ); + assertThat(invitation.getError(), is(nullValue())); + + ConversationsAcceptSharedInviteResponse acceptance = receiver.conversationsAcceptSharedInvite(r -> r + .channelName(channelName) + .inviteId(invitation.getInviteId()) + ); + assertThat(acceptance.getError(), is(nullValue())); + + ConversationsDeclineSharedInviteResponse decline = receiver.conversationsDeclineSharedInvite(r -> r + .inviteId(invitation.getInviteId()) + ); + assertThat(decline.getError(), is(nullValue())); + + } finally { + ConversationsArchiveResponse archive = sender.conversationsArchive(r -> r.channel(channelId)); + assertThat(archive.getError(), is(nullValue())); + } + } +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectChannel.java b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectChannel.java new file mode 100644 index 000000000..3075ecdbe --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectChannel.java @@ -0,0 +1,11 @@ +package com.slack.api.model.connect; + +import lombok.Data; + +@Data +public class ConnectChannel { + private String id; + private Boolean isIm; + private Boolean isPrivate; + private String name; +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInvite.java b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInvite.java new file mode 100644 index 000000000..6e7848be7 --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInvite.java @@ -0,0 +1,16 @@ +package com.slack.api.model.connect; + +import lombok.Data; + +import java.util.List; + +@Data +public class ConnectInvite { + private String direction; // outgoing, etc. + private String status; // revoked, etc. + private Integer dateLastUpdated; + private String inviteType; // channel, etc. + private ConnectInviteDetail invite; + private ConnectChannel channel; + private List acceptances; +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInviteAcceptance.java b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInviteAcceptance.java new file mode 100644 index 000000000..5b5c6e9b6 --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInviteAcceptance.java @@ -0,0 +1,16 @@ +package com.slack.api.model.connect; + +import lombok.Data; + +import java.util.List; + +@Data +public class ConnectInviteAcceptance { + private String approvalStatus; + private Integer dateAccepted; + private Integer dateInvalid; + private Integer dateLastUpdated; + private ConnectTeam acceptingTeam; + private ConnectUser acceptingUser; + private List reviews; +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInviteDetail.java b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInviteDetail.java new file mode 100644 index 000000000..301111cca --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInviteDetail.java @@ -0,0 +1,15 @@ +package com.slack.api.model.connect; + +import lombok.Data; + +@Data +public class ConnectInviteDetail { + private String id; // I12345 + private Integer dateCreated; + private Integer dateInvalid; + private ConnectTeam invitingTeam; + private ConnectUser invitingUser; + private String link; // https://join.slack.com/share/... + private String recipientUserId; // W12345, U12345, etc. + private String recipientEmail; +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInviteReview.java b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInviteReview.java new file mode 100644 index 000000000..69d43cc5c --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectInviteReview.java @@ -0,0 +1,10 @@ +package com.slack.api.model.connect; + +import lombok.Data; + +@Data +public class ConnectInviteReview { + private String type; + private Integer dateReview; + private ConnectTeam reviewingTeam; +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectTeam.java b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectTeam.java new file mode 100644 index 000000000..8e44a261f --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectTeam.java @@ -0,0 +1,14 @@ +package com.slack.api.model.connect; + +import com.slack.api.model.TeamIcon; +import lombok.Data; + +@Data +public class ConnectTeam { + private String id; // E12345, T12345 + private String name; + private TeamIcon icon; + private boolean isVerified; + private String domain; + private Integer dateCreated; +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectUser.java b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectUser.java new file mode 100644 index 000000000..1a45075ce --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectUser.java @@ -0,0 +1,12 @@ +package com.slack.api.model.connect; + +import lombok.Data; + +@Data +public class ConnectUser { + private String id; + private String teamId; + private String name; + private Integer updated; + private ConnectUserProfile profile; +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectUserProfile.java b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectUserProfile.java new file mode 100644 index 000000000..4dbe327dc --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/connect/ConnectUserProfile.java @@ -0,0 +1,31 @@ +package com.slack.api.model.connect; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; + +@Data +public class ConnectUserProfile { + private String realName; + private String realNameNormalized; + private String displayName; + private String displayNameNormalized; + private String team; + private String avatarHash; + private String email; + @SerializedName("image_24") + private String image24; + @SerializedName("image_32") + private String image32; + @SerializedName("image_48") + private String image48; + @SerializedName("image_72") + private String image72; + @SerializedName("image_192") + private String image192; + @SerializedName("image_512") + private String image512; + @SerializedName("image_1024") + private String image1024; + private String imageOriginal; + private Boolean isCustomImage; +} diff --git a/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteAcceptedEvent.java b/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteAcceptedEvent.java new file mode 100644 index 000000000..22d9ab648 --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteAcceptedEvent.java @@ -0,0 +1,27 @@ +package com.slack.api.model.event; + +import com.slack.api.model.connect.ConnectChannel; +import com.slack.api.model.connect.ConnectInviteDetail; +import com.slack.api.model.connect.ConnectTeam; +import com.slack.api.model.connect.ConnectUser; +import lombok.Data; + +import java.util.List; + +/** + * https://api.slack.com/events/shared_channel_invite_accepted + */ +@Data +public class SharedChannelInviteAcceptedEvent implements Event { + + public static final String TYPE_NAME = "shared_channel_invite_accepted"; + + private final String type = TYPE_NAME; + private boolean approvalRequired; + private ConnectInviteDetail invite; + private ConnectChannel channel; + private List teamsInChannel; + private ConnectUser acceptingUser; + private String eventTs; + +} \ No newline at end of file diff --git a/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteApprovedEvent.java b/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteApprovedEvent.java new file mode 100644 index 000000000..0facb0f48 --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteApprovedEvent.java @@ -0,0 +1,27 @@ +package com.slack.api.model.event; + +import com.slack.api.model.connect.ConnectChannel; +import com.slack.api.model.connect.ConnectInviteDetail; +import com.slack.api.model.connect.ConnectTeam; +import com.slack.api.model.connect.ConnectUser; +import lombok.Data; + +import java.util.List; + +/** + * https://api.slack.com/events/shared_channel_invite_approved + */ +@Data +public class SharedChannelInviteApprovedEvent implements Event { + + public static final String TYPE_NAME = "shared_channel_invite_approved"; + + private final String type = TYPE_NAME; + private ConnectInviteDetail invite; + private ConnectChannel channel; + private String approvingTeamId; + private List teamsInChannel; + private ConnectUser approvingUser; + private String eventTs; + +} \ No newline at end of file diff --git a/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteDeclinedEvent.java b/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteDeclinedEvent.java new file mode 100644 index 000000000..26f4952fd --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteDeclinedEvent.java @@ -0,0 +1,27 @@ +package com.slack.api.model.event; + +import com.slack.api.model.connect.ConnectChannel; +import com.slack.api.model.connect.ConnectInviteDetail; +import com.slack.api.model.connect.ConnectTeam; +import com.slack.api.model.connect.ConnectUser; +import lombok.Data; + +import java.util.List; + +/** + * https://api.slack.com/events/shared_channel_invite_declined + */ +@Data +public class SharedChannelInviteDeclinedEvent implements Event { + + public static final String TYPE_NAME = "shared_channel_invite_declined"; + + private final String type = TYPE_NAME; + private ConnectInviteDetail invite; + private ConnectChannel channel; + private String decliningTeamId; + private List teamsInChannel; + private ConnectUser decliningUser; + private String eventTs; + +} \ No newline at end of file diff --git a/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteReceivedEvent.java b/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteReceivedEvent.java new file mode 100644 index 000000000..c360711d9 --- /dev/null +++ b/slack-api-model/src/main/java/com/slack/api/model/event/SharedChannelInviteReceivedEvent.java @@ -0,0 +1,22 @@ +package com.slack.api.model.event; + +import com.slack.api.model.User; +import com.slack.api.model.connect.ConnectChannel; +import com.slack.api.model.connect.ConnectInvite; +import com.slack.api.model.connect.ConnectInviteDetail; +import lombok.Data; + +/** + * https://api.slack.com/events/shared_channel_invite_received + */ +@Data +public class SharedChannelInviteReceivedEvent implements Event { + + public static final String TYPE_NAME = "shared_channel_invite_received"; + + private final String type = TYPE_NAME; + private ConnectInviteDetail invite; + private ConnectChannel channel; + private String eventTs; + +} \ No newline at end of file diff --git a/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteAcceptedEventTest.java b/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteAcceptedEventTest.java new file mode 100644 index 000000000..35c4c07ea --- /dev/null +++ b/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteAcceptedEventTest.java @@ -0,0 +1,112 @@ +package test_locally.api.model.event; + +import com.google.gson.Gson; +import com.slack.api.model.event.SharedChannelInviteAcceptedEvent; +import org.junit.Test; +import test_locally.unit.GsonFactory; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class SharedChannelInviteAcceptedEventTest { + + @Test + public void typeName() { + assertThat(SharedChannelInviteAcceptedEvent.TYPE_NAME, is("shared_channel_invite_accepted")); + } + + @Test + public void deserialize() { + String json = "{\n" + + " \"type\": \"shared_channel_invite_accepted\",\n" + + " \"approval_required\": false,\n" + + " \"invite\": {\n" + + " \"id\": \"I028YDERZSQ\",\n" + + " \"date_created\": 1626876000,\n" + + " \"date_invalid\": 1628085600,\n" + + " \"inviting_team\": {\n" + + " \"id\": \"T12345678\",\n" + + " \"name\": \"Corgis\",\n" + + " \"icon\": {},\n" + + " \"is_verified\": false,\n" + + " \"domain\": \"corgis\",\n" + + " \"date_created\": 1480946400\n" + + " },\n" + + " \"inviting_user\": {\n" + + " \"id\": \"U12345678\",\n" + + " \"team_id\": \"T12345678\",\n" + + " \"name\": \"crus\",\n" + + " \"updated\": 1608081902,\n" + + " \"profile\": {\n" + + " \"real_name\": \"Corgis Rus\",\n" + + " \"display_name\": \"Corgis Rus\",\n" + + " \"real_name_normalized\": \"Corgis Rus\",\n" + + " \"display_name_normalized\": \"Corgis Rus\",\n" + + " \"team\": \"T12345678\",\n" + + " \"avatar_hash\": \"gcfh83a4c72k\",\n" + + " \"email\": \"corgisrus@slack-corp.com\",\n" + + " \"image_24\": \"https://placekitten.com/24/24\",\n" + + " \"image_32\": \"https://placekitten.com/32/32\",\n" + + " \"image_48\": \"https://placekitten.com/48/48\",\n" + + " \"image_72\": \"https://placekitten.com/72/72\",\n" + + " \"image_192\": \"https://placekitten.com/192/192\",\n" + + " \"image_512\": \"https://placekitten.com/512/512\"\n" + + " }\n" + + " },\n" + + " \"recipient_email\": \"golden@doodle.com\",\n" + + " \"recipient_user_id\": \"U87654321\"\n" + + " },\n" + + " \"channel\": {\n" + + " \"id\": \"C12345678\",\n" + + " \"is_private\": false,\n" + + " \"is_im\": false,\n" + + " \"name\": \"test-slack-connect\"\n" + + " },\n" + + " \"teams_in_channel\": [\n" + + " {\n" + + " \"id\": \"T12345678\",\n" + + " \"name\": \"Corgis\",\n" + + " \"icon\": {},\n" + + " \"is_verified\": false,\n" + + " \"domain\": \"corgis\",\n" + + " \"date_created\": 1626789600\n" + + " }\n" + + " ],\n" + + " \"accepting_user\": {\n" + + " \"id\": \"U87654321\",\n" + + " \"team_id\": \"T87654321\",\n" + + " \"name\": \"golden\",\n" + + " \"updated\": 1624406113,\n" + + " \"profile\": {\n" + + " \"real_name\": \"Golden Doodle\",\n" + + " \"display_name\": \"Golden\",\n" + + " \"real_name_normalized\": \"Golden Doodle\",\n" + + " \"display_name_normalized\": \"Golden\",\n" + + " \"team\": \"T87654321\",\n" + + " \"avatar_hash\": \"g717728b118x\",\n" + + " \"email\": \"golden@doodle.com\",\n" + + " \"image_24\": \"https://placekitten.com/24/24\",\n" + + " \"image_32\": \"https://placekitten.com/32/32\",\n" + + " \"image_48\": \"https://placekitten.com/48/48\",\n" + + " \"image_72\": \"https://placekitten.com/72/72\",\n" + + " \"image_192\": \"https://placekitten.com/192/192\",\n" + + " \"image_512\": \"https://placekitten.com/512/512\"\n" + + " }\n" + + " },\n" + + " \"event_ts\": \"1626877800.000000\"\n" + + "}"; + SharedChannelInviteAcceptedEvent event = GsonFactory.createSnakeCase().fromJson(json, SharedChannelInviteAcceptedEvent.class); + assertThat(event.getType(), is("shared_channel_invite_accepted")); + assertThat(event.getEventTs(), is("1626877800.000000")); + } + + @Test + public void serialize() { + Gson gson = GsonFactory.createSnakeCase(); + SharedChannelInviteAcceptedEvent event = new SharedChannelInviteAcceptedEvent(); + String generatedJson = gson.toJson(event); + String expectedJson = "{\"type\":\"shared_channel_invite_accepted\",\"approval_required\":false}"; + assertThat(generatedJson, is(expectedJson)); + } + +} diff --git a/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteApprovedEventTest.java b/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteApprovedEventTest.java new file mode 100644 index 000000000..a8dcd54ab --- /dev/null +++ b/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteApprovedEventTest.java @@ -0,0 +1,111 @@ +package test_locally.api.model.event; + +import com.google.gson.Gson; +import com.slack.api.model.event.SharedChannelInviteApprovedEvent; +import org.junit.Test; +import test_locally.unit.GsonFactory; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class SharedChannelInviteApprovedEventTest { + + @Test + public void typeName() { + assertThat(SharedChannelInviteApprovedEvent.TYPE_NAME, is("shared_channel_invite_approved")); + } + + @Test + public void deserialize() { + String json = "{\n" + + " \"type\": \"shared_channel_invite_approved\",\n" + + " \"invite\": {\n" + + " \"id\": \"I01354X80CA\",\n" + + " \"date_created\": 1626876000,\n" + + " \"date_invalid\": 1628085600,\n" + + " \"inviting_team\": {\n" + + " \"id\": \"T12345678\",\n" + + " \"name\": \"Corgis\",\n" + + " \"icon\": {},\n" + + " \"is_verified\": false,\n" + + " \"domain\": \"corgis\",\n" + + " \"date_created\": 1480946400\n" + + " },\n" + + " \"inviting_user\": {\n" + + " \"id\": \"U12345678\",\n" + + " \"team_id\": \"T12345678\",\n" + + " \"name\": \"crus\",\n" + + " \"updated\": 1608081902,\n" + + " \"profile\": {\n" + + " \"real_name\": \"Corgis Rus\",\n" + + " \"display_name\": \"Corgis Rus\",\n" + + " \"real_name_normalized\": \"Corgis Rus\",\n" + + " \"display_name_normalized\": \"Corgis Rus\",\n" + + " \"team\": \"T12345678\",\n" + + " \"avatar_hash\": \"gcfh83a4c72k\",\n" + + " \"email\": \"corgisrus@slack-corp.com\",\n" + + " \"image_24\": \"https://placekitten.com/24/24\",\n" + + " \"image_32\": \"https://placekitten.com/32/32\",\n" + + " \"image_48\": \"https://placekitten.com/48/48\",\n" + + " \"image_72\": \"https://placekitten.com/72/72\",\n" + + " \"image_192\": \"https://placekitten.com/192/192\",\n" + + " \"image_512\": \"https://placekitten.com/512/512\"\n" + + " }\n" + + " },\n" + + " \"recipient_email\": \"golden@doodle.com\",\n" + + " \"recipient_user_id\": \"U87654321\"\n" + + " },\n" + + " \"channel\": {\n" + + " \"id\": \"C12345678\",\n" + + " \"is_private\": false,\n" + + " \"is_im\": false,\n" + + " \"name\": \"test-slack-connect\"\n" + + " },\n" + + " \"approving_team_id\": \"T87654321\",\n" + + " \"teams_in_channel\": [\n" + + " {\n" + + " \"id\": \"T12345678\",\n" + + " \"name\": \"Corgis\",\n" + + " \"icon\": {},\n" + + " \"is_verified\": false,\n" + + " \"domain\": \"corgis\",\n" + + " \"date_created\": 1626789600\n" + + " }\n" + + " ],\n" + + " \"approving_user\": {\n" + + " \"id\": \"U012A3CDE\",\n" + + " \"team_id\": \"T87654321\",\n" + + " \"name\": \"spengler\",\n" + + " \"updated\": 1624406532,\n" + + " \"profile\": {\n" + + " \"real_name\": \"Egon Spengler\",\n" + + " \"display_name\": \"Egon\",\n" + + " \"real_name_normalized\": \"Egon Spengler\",\n" + + " \"display_name_normalized\": \"Egon\",\n" + + " \"team\": \"T87654321\",\n" + + " \"avatar_hash\": \"g216425b1681\",\n" + + " \"email\": \"spengler@ghostbusters.example.com\",\n" + + " \"image_24\": \"https://placekitten.com/24/24\",\n" + + " \"image_32\": \"https://placekitten.com/32/32\",\n" + + " \"image_48\": \"https://placekitten.com/48/48\",\n" + + " \"image_72\": \"https://placekitten.com/72/72\",\n" + + " \"image_192\": \"https://placekitten.com/192/192\",\n" + + " \"image_512\": \"https://placekitten.com/512/512\"\n" + + " }\n" + + " },\n" + + " \"event_ts\": \"1626881400.000000\"\n" + + "}"; + SharedChannelInviteApprovedEvent event = GsonFactory.createSnakeCase().fromJson(json, SharedChannelInviteApprovedEvent.class); + assertThat(event.getType(), is("shared_channel_invite_approved")); + } + + @Test + public void serialize() { + Gson gson = GsonFactory.createSnakeCase(); + SharedChannelInviteApprovedEvent event = new SharedChannelInviteApprovedEvent(); + String generatedJson = gson.toJson(event); + String expectedJson = "{\"type\":\"shared_channel_invite_approved\"}"; + assertThat(generatedJson, is(expectedJson)); + } + +} diff --git a/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteDeclinedEventTest.java b/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteDeclinedEventTest.java new file mode 100644 index 000000000..4c8c047ef --- /dev/null +++ b/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteDeclinedEventTest.java @@ -0,0 +1,110 @@ +package test_locally.api.model.event; + +import com.google.gson.Gson; +import com.slack.api.model.event.SharedChannelInviteDeclinedEvent; +import org.junit.Test; +import test_locally.unit.GsonFactory; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class SharedChannelInviteDeclinedEventTest { + + @Test + public void typeName() { + assertThat(SharedChannelInviteDeclinedEvent.TYPE_NAME, is("shared_channel_invite_declined")); + } + + @Test + public void deserialize() { + String json = "{\n" + + " \"type\": \"shared_channel_invite_declined\",\n" + + " \"invite\": {\n" + + " \"id\": \"I01354X80CA\",\n" + + " \"date_created\": 1626876000,\n" + + " \"date_invalid\": 1628085600,\n" + + " \"inviting_team\": {\n" + + " \"id\": \"T12345678\",\n" + + " \"name\": \"Corgis\",\n" + + " \"icon\": {},\n" + + " \"is_verified\": false,\n" + + " \"domain\": \"corgis\",\n" + + " \"date_created\": 1480946400\n" + + " },\n" + + " \"inviting_user\": {\n" + + " \"id\": \"U12345678\",\n" + + " \"team_id\": \"T12345678\",\n" + + " \"name\": \"crus\",\n" + + " \"updated\": 1608081902,\n" + + " \"profile\": {\n" + + " \"real_name\": \"Corgis Rus\",\n" + + " \"display_name\": \"Corgis Rus\",\n" + + " \"real_name_normalized\": \"Corgis Rus\",\n" + + " \"display_name_normalized\": \"Corgis Rus\",\n" + + " \"team\": \"T12345678\",\n" + + " \"avatar_hash\": \"gcfh83a4c72k\",\n" + + " \"email\": \"corgisrus@slack-corp.com\",\n" + + " \"image_24\": \"https://placekitten.com/24/24\",\n" + + " \"image_32\": \"https://placekitten.com/32/32\",\n" + + " \"image_48\": \"https://placekitten.com/48/48\",\n" + + " \"image_72\": \"https://placekitten.com/72/72\",\n" + + " \"image_192\": \"https://placekitten.com/192/192\",\n" + + " \"image_512\": \"https://placekitten.com/512/512\"\n" + + " }\n" + + " },\n" + + " \"recipient_email\": \"golden@doodle.com\"\n" + + " },\n" + + " \"channel\": {\n" + + " \"id\": \"C12345678\",\n" + + " \"is_private\": false,\n" + + " \"is_im\": false,\n" + + " \"name\": \"test-slack-connect\"\n" + + " },\n" + + " \"declining_team_id\": \"T87654321\",\n" + + " \"teams_in_channel\": [\n" + + " {\n" + + " \"id\": \"T12345678\",\n" + + " \"name\": \"Corgis\",\n" + + " \"icon\": {},\n" + + " \"is_verified\": false,\n" + + " \"domain\": \"corgis\",\n" + + " \"date_created\": 1626789600\n" + + " }\n" + + " ],\n" + + " \"declining_user\": {\n" + + " \"id\": \"U012A3CDE\",\n" + + " \"team_id\": \"T87654321\",\n" + + " \"name\": \"spengler\",\n" + + " \"updated\": 1624406532,\n" + + " \"profile\": {\n" + + " \"real_name\": \"Egon Spengler\",\n" + + " \"display_name\": \"Egon\",\n" + + " \"real_name_normalized\": \"Egon Spengler\",\n" + + " \"display_name_normalized\": \"Egon\",\n" + + " \"team\": \"T87654321\",\n" + + " \"avatar_hash\": \"g216425b1681\",\n" + + " \"email\": \"spengler@ghostbusters.example.com\",\n" + + " \"image_24\": \"https://placekitten.com/24/24\",\n" + + " \"image_32\": \"https://placekitten.com/32/32\",\n" + + " \"image_48\": \"https://placekitten.com/48/48\",\n" + + " \"image_72\": \"https://placekitten.com/72/72\",\n" + + " \"image_192\": \"https://placekitten.com/192/192\",\n" + + " \"image_512\": \"https://placekitten.com/512/512\"\n" + + " }\n" + + " },\n" + + " \"event_ts\": \"1626881400.000000\"\n" + + "}"; + SharedChannelInviteDeclinedEvent event = GsonFactory.createSnakeCase().fromJson(json, SharedChannelInviteDeclinedEvent.class); + assertThat(event.getType(), is("shared_channel_invite_declined")); + } + + @Test + public void serialize() { + Gson gson = GsonFactory.createSnakeCase(); + SharedChannelInviteDeclinedEvent event = new SharedChannelInviteDeclinedEvent(); + String generatedJson = gson.toJson(event); + String expectedJson = "{\"type\":\"shared_channel_invite_declined\"}"; + assertThat(generatedJson, is(expectedJson)); + } + +} diff --git a/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteReceivedEventTest.java b/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteReceivedEventTest.java new file mode 100644 index 000000000..b6a619dae --- /dev/null +++ b/slack-api-model/src/test/java/test_locally/api/model/event/SharedChannelInviteReceivedEventTest.java @@ -0,0 +1,79 @@ +package test_locally.api.model.event; + +import com.google.gson.Gson; +import com.slack.api.model.event.SharedChannelInviteReceivedEvent; +import org.junit.Test; +import test_locally.unit.GsonFactory; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class SharedChannelInviteReceivedEventTest { + + @Test + public void typeName() { + assertThat(SharedChannelInviteReceivedEvent.TYPE_NAME, is("shared_channel_invite_received")); + } + + @Test + public void deserialize() { + String json = "{\n" + + " \"type\": \"shared_channel_invite_received\",\n" + + " \"invite\": {\n" + + " \"id\": \"I028YDERZSQ\",\n" + + " \"date_created\": 1626876000,\n" + + " \"date_invalid\": 1628085600,\n" + + " \"inviting_team\": {\n" + + " \"id\": \"T12345678\",\n" + + " \"name\": \"Corgis\",\n" + + " \"icon\": {},\n" + + " \"is_verified\": false,\n" + + " \"domain\": \"corgis\",\n" + + " \"date_created\": 1480946400\n" + + " },\n" + + " \"inviting_user\": {\n" + + " \"id\": \"U12345678\",\n" + + " \"team_id\": \"T12345678\",\n" + + " \"name\": \"crus\",\n" + + " \"updated\": 1608081902,\n" + + " \"profile\": {\n" + + " \"real_name\": \"Corgis Rus\",\n" + + " \"display_name\": \"Corgis Rus\",\n" + + " \"real_name_normalized\": \"Corgis Rus\",\n" + + " \"display_name_normalized\": \"Corgis Rus\",\n" + + " \"team\": \"T12345678\",\n" + + " \"avatar_hash\": \"gcfh83a4c72k\",\n" + + " \"email\": \"corgisrus@slack-corp.com\",\n" + + " \"image_24\": \"https://placekitten.com/24/24\",\n" + + " \"image_32\": \"https://placekitten.com/32/32\",\n" + + " \"image_48\": \"https://placekitten.com/48/48\",\n" + + " \"image_72\": \"https://placekitten.com/72/72\",\n" + + " \"image_192\": \"https://placekitten.com/192/192\",\n" + + " \"image_512\": \"https://placekitten.com/512/512\"\n" + + " }\n" + + " },\n" + + " \"recipient_user_id\": \"U87654321\"\n" + + " },\n" + + " \"channel\": {\n" + + " \"id\": \"C12345678\",\n" + + " \"is_private\": false,\n" + + " \"is_im\": false,\n" + + " \"name\": \"test-slack-connect\"\n" + + " },\n" + + " \"event_ts\": \"1626876010.000100\"\n" + + "}"; + SharedChannelInviteReceivedEvent event = GsonFactory.createSnakeCase().fromJson(json, SharedChannelInviteReceivedEvent.class); + assertThat(event.getType(), is("shared_channel_invite_received")); + assertThat(event.getEventTs(), is("1626876010.000100")); + } + + @Test + public void serialize() { + Gson gson = GsonFactory.createSnakeCase(); + SharedChannelInviteReceivedEvent event = new SharedChannelInviteReceivedEvent(); + String generatedJson = gson.toJson(event); + String expectedJson = "{\"type\":\"shared_channel_invite_received\"}"; + assertThat(generatedJson, is(expectedJson)); + } + +} diff --git a/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteAcceptedHandler.java b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteAcceptedHandler.java new file mode 100644 index 000000000..abbe99bd5 --- /dev/null +++ b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteAcceptedHandler.java @@ -0,0 +1,13 @@ +package com.slack.api.app_backend.events.handler; + +import com.slack.api.app_backend.events.EventHandler; +import com.slack.api.app_backend.events.payload.SharedChannelInviteAcceptedPayload; +import com.slack.api.model.event.SharedChannelInviteAcceptedEvent; + +public abstract class SharedChannelInviteAcceptedHandler extends EventHandler { + + @Override + public String getEventType() { + return SharedChannelInviteAcceptedEvent.TYPE_NAME; + } +} diff --git a/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteApprovedHandler.java b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteApprovedHandler.java new file mode 100644 index 000000000..d9cc7bffc --- /dev/null +++ b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteApprovedHandler.java @@ -0,0 +1,13 @@ +package com.slack.api.app_backend.events.handler; + +import com.slack.api.app_backend.events.EventHandler; +import com.slack.api.app_backend.events.payload.SharedChannelInviteApprovedPayload; +import com.slack.api.model.event.SharedChannelInviteApprovedEvent; + +public abstract class SharedChannelInviteApprovedHandler extends EventHandler { + + @Override + public String getEventType() { + return SharedChannelInviteApprovedEvent.TYPE_NAME; + } +} diff --git a/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteDeclinedHandler.java b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteDeclinedHandler.java new file mode 100644 index 000000000..c8db1b81e --- /dev/null +++ b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteDeclinedHandler.java @@ -0,0 +1,13 @@ +package com.slack.api.app_backend.events.handler; + +import com.slack.api.app_backend.events.EventHandler; +import com.slack.api.app_backend.events.payload.SharedChannelInviteDeclinedPayload; +import com.slack.api.model.event.SharedChannelInviteDeclinedEvent; + +public abstract class SharedChannelInviteDeclinedHandler extends EventHandler { + + @Override + public String getEventType() { + return SharedChannelInviteDeclinedEvent.TYPE_NAME; + } +} diff --git a/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteReceivedHandler.java b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteReceivedHandler.java new file mode 100644 index 000000000..9e4db0590 --- /dev/null +++ b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/handler/SharedChannelInviteReceivedHandler.java @@ -0,0 +1,13 @@ +package com.slack.api.app_backend.events.handler; + +import com.slack.api.app_backend.events.EventHandler; +import com.slack.api.app_backend.events.payload.SharedChannelInviteReceivedPayload; +import com.slack.api.model.event.SharedChannelInviteReceivedEvent; + +public abstract class SharedChannelInviteReceivedHandler extends EventHandler { + + @Override + public String getEventType() { + return SharedChannelInviteReceivedEvent.TYPE_NAME; + } +} diff --git a/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteAcceptedPayload.java b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteAcceptedPayload.java new file mode 100644 index 000000000..92ec16e26 --- /dev/null +++ b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteAcceptedPayload.java @@ -0,0 +1,25 @@ +package com.slack.api.app_backend.events.payload; + +import com.slack.api.model.event.SharedChannelInviteAcceptedEvent; +import lombok.Data; + +import java.util.List; + +@Data +public class SharedChannelInviteAcceptedPayload implements EventsApiPayload { + + private String token; + private String enterpriseId; + private String teamId; + private String apiAppId; + private String type; + private List authedUsers; + private List authedTeams; + private List authorizations; + private boolean isExtSharedChannel; + private String eventId; + private Integer eventTime; + private String eventContext; + + private SharedChannelInviteAcceptedEvent event; +} diff --git a/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteApprovedPayload.java b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteApprovedPayload.java new file mode 100644 index 000000000..67db93bea --- /dev/null +++ b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteApprovedPayload.java @@ -0,0 +1,25 @@ +package com.slack.api.app_backend.events.payload; + +import com.slack.api.model.event.SharedChannelInviteApprovedEvent; +import lombok.Data; + +import java.util.List; + +@Data +public class SharedChannelInviteApprovedPayload implements EventsApiPayload { + + private String token; + private String enterpriseId; + private String teamId; + private String apiAppId; + private String type; + private List authedUsers; + private List authedTeams; + private List authorizations; + private boolean isExtSharedChannel; + private String eventId; + private Integer eventTime; + private String eventContext; + + private SharedChannelInviteApprovedEvent event; +} diff --git a/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteDeclinedPayload.java b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteDeclinedPayload.java new file mode 100644 index 000000000..59b10c53e --- /dev/null +++ b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteDeclinedPayload.java @@ -0,0 +1,25 @@ +package com.slack.api.app_backend.events.payload; + +import com.slack.api.model.event.SharedChannelInviteDeclinedEvent; +import lombok.Data; + +import java.util.List; + +@Data +public class SharedChannelInviteDeclinedPayload implements EventsApiPayload { + + private String token; + private String enterpriseId; + private String teamId; + private String apiAppId; + private String type; + private List authedUsers; + private List authedTeams; + private List authorizations; + private boolean isExtSharedChannel; + private String eventId; + private Integer eventTime; + private String eventContext; + + private SharedChannelInviteDeclinedEvent event; +} diff --git a/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteReceivedPayload.java b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteReceivedPayload.java new file mode 100644 index 000000000..dcadc9c3d --- /dev/null +++ b/slack-app-backend/src/main/java/com/slack/api/app_backend/events/payload/SharedChannelInviteReceivedPayload.java @@ -0,0 +1,26 @@ +package com.slack.api.app_backend.events.payload; + +import com.slack.api.model.event.SharedChannelInviteReceivedEvent; +import com.slack.api.model.event.TeamJoinEvent; +import lombok.Data; + +import java.util.List; + +@Data +public class SharedChannelInviteReceivedPayload implements EventsApiPayload { + + private String token; + private String enterpriseId; + private String teamId; + private String apiAppId; + private String type; + private List authedUsers; + private List authedTeams; + private List authorizations; + private boolean isExtSharedChannel; + private String eventId; + private Integer eventTime; + private String eventContext; + + private SharedChannelInviteReceivedEvent event; +} diff --git a/slack-app-backend/src/test/java/test_locally/app_backend/events/EventHandlersTest.java b/slack-app-backend/src/test/java/test_locally/app_backend/events/EventHandlersTest.java index 23420bbbc..1acdc2af8 100644 --- a/slack-app-backend/src/test/java/test_locally/app_backend/events/EventHandlersTest.java +++ b/slack-app-backend/src/test/java/test_locally/app_backend/events/EventHandlersTest.java @@ -375,6 +375,27 @@ public void handle(WorkflowStepDeletedPayload payload) { @Override public void handle(ChannelIdChangedPayload payload) { } + }, + // Slack Connect + new SharedChannelInviteAcceptedHandler() { + @Override + public void handle(SharedChannelInviteAcceptedPayload payload) { + } + }, + new SharedChannelInviteApprovedHandler() { + @Override + public void handle(SharedChannelInviteApprovedPayload payload) { + } + }, + new SharedChannelInviteReceivedHandler() { + @Override + public void handle(SharedChannelInviteReceivedPayload payload) { + } + }, + new SharedChannelInviteDeclinedHandler() { + @Override + public void handle(SharedChannelInviteDeclinedPayload payload) { + } } );