diff --git a/src/main/java/io/getstream/chat/java/models/App.java b/src/main/java/io/getstream/chat/java/models/App.java index 15df87425..512ba9f4c 100644 --- a/src/main/java/io/getstream/chat/java/models/App.java +++ b/src/main/java/io/getstream/chat/java/models/App.java @@ -358,6 +358,137 @@ public enum EnforceUniqueUsernames { UNKNOWN } + public enum HookType { + @JsonProperty("webhook") + WEBHOOK, + @JsonProperty("sqs") + SQS, + @JsonProperty("sns") + SNS, + @JsonProperty("pending_message") + PENDING_MESSAGE, + @JsonEnumDefaultValue + UNKNOWN + } + + public enum AuthType { + @JsonProperty("keys") + KEYS, // Using AWS access key and secret key + @JsonProperty("role") + ROLE, // Using IAM role + @JsonProperty("resource") + RESOURCE, // Using resource-based policy + @JsonEnumDefaultValue + UNKNOWN + } + + @Data + @NoArgsConstructor + public static class PendingMessageCallback { + @Nullable + @JsonProperty("mode") + private CallbackMode mode; + } + + public enum CallbackMode { + @JsonProperty("CALLBACK_MODE_NONE") + NONE, + @JsonProperty("CALLBACK_MODE_REST") + REST, + @JsonProperty("CALLBACK_MODE_TWIRP") + TWIRP, + @JsonEnumDefaultValue + UNKNOWN + } + + @Data + @NoArgsConstructor + public static class EventHook { + @Nullable + @JsonProperty("id") + private String id; + + @Nullable + @JsonProperty("hook_type") + private HookType hookType; + + @Nullable + @JsonProperty("enabled") + private Boolean enabled; + + @Nullable + @JsonProperty("event_types") + private List eventTypes; + + @Nullable + @JsonProperty("webhook_url") + private String webhookURL; + + @Nullable + @JsonProperty("sqs_queue_url") + private String sqsQueueURL; + + @Nullable + @JsonProperty("sqs_region") + private String sqsRegion; + + @Nullable + @JsonProperty("sqs_auth_type") + private AuthType sqsAuthType; + + @Nullable + @JsonProperty("sqs_key") + private String sqsKey; + + @Nullable + @JsonProperty("sqs_secret") + private String sqsSecret; + + @Nullable + @JsonProperty("sqs_role_arn") + private String sqsRoleARN; + + @Nullable + @JsonProperty("sns_topic_arn") + private String snsTopicARN; + + @Nullable + @JsonProperty("sns_region") + private String snsRegion; + + @Nullable + @JsonProperty("sns_auth_type") + private AuthType snsAuthType; + + @Nullable + @JsonProperty("sns_key") + private String snsKey; + + @Nullable + @JsonProperty("sns_secret") + private String snsSecret; + + @Nullable + @JsonProperty("sns_role_arn") + private String snsRoleARN; + + @Nullable + @JsonProperty("timeout_ms") + private Integer timeoutMs; + + @Nullable + @JsonProperty("callback") + private PendingMessageCallback callback; + + @Nullable + @JsonProperty("created_at") + private Date createdAt; + + @Nullable + @JsonProperty("updated_at") + private Date updatedAt; + } + public static class EnforceUniqueUsernamesDeserializer extends JsonDeserializer { @Override @@ -778,6 +909,11 @@ public static class AppUpdateRequestData { @JsonProperty("grants") private Map> grants; + @Nullable + @JsonProperty("event_hooks") + @JsonInclude(Include.NON_NULL) + private List eventHooks; + public static class AppUpdateRequest extends StreamRequest { @Override protected Call generateCall(Client client) { diff --git a/src/test/java/io/getstream/chat/java/AppTest.java b/src/test/java/io/getstream/chat/java/AppTest.java index a3df12ce1..5264678bb 100644 --- a/src/test/java/io/getstream/chat/java/AppTest.java +++ b/src/test/java/io/getstream/chat/java/AppTest.java @@ -5,12 +5,16 @@ import io.getstream.chat.java.models.App.AppCheckSnsResponse; import io.getstream.chat.java.models.App.AppCheckSqsResponse; import io.getstream.chat.java.models.App.AppConfig; +import io.getstream.chat.java.models.App.EventHook; import io.getstream.chat.java.models.App.PushConfigRequestObject; import io.getstream.chat.java.models.App.PushVersion; import io.getstream.chat.java.models.Message; import io.getstream.chat.java.models.Message.MessageRequestObject; import io.getstream.chat.java.services.framework.DefaultClient; +import java.util.Arrays; import java.util.Calendar; +import java.util.Collections; +import java.util.Date; import java.util.GregorianCalendar; import java.util.Properties; import java.util.Random; @@ -176,4 +180,74 @@ void whenUpdatingAppSettingsSizeLimit_thenNoException() { appConfig = Assertions.assertDoesNotThrow(() -> App.get().request()).getApp(); Assertions.assertEquals(newSizeLimit, appConfig.getFileUploadConfig().getSizeLimit()); } + + @DisplayName("Can update app settings with webhook event hook") + @Test + void whenUpdatingAppSettingsWithWebhookEventHook_thenNoException() throws StreamException { + EventHook webhookHook = new EventHook(); + webhookHook.setId("webhook-1"); + webhookHook.setHookType(App.HookType.WEBHOOK); + webhookHook.setEnabled(true); + webhookHook.setEventTypes(Arrays.asList("message.new", "message.updated")); + webhookHook.setWebhookURL("https://example.com/webhook"); + webhookHook.setCreatedAt(new Date()); + webhookHook.setUpdatedAt(new Date()); + + try { + App.update().eventHooks(Collections.singletonList(webhookHook)).request(); + } catch (StreamException e) { + if (e.getMessage().contains("cannot set event hooks in hook v1 system")) { + return; + } + throw e; + } + } + + @DisplayName("Can update app settings with SQS event hook") + @Test + void whenUpdatingAppSettingsWithSQSEventHook_thenNoException() throws StreamException { + EventHook sqsHook = new EventHook(); + sqsHook.setId("sqs-1"); + sqsHook.setHookType(App.HookType.SQS); + sqsHook.setEnabled(true); + sqsHook.setEventTypes(Arrays.asList("user.presence.changed", "user.updated")); + sqsHook.setSqsQueueURL("https://sqs.us-east-1.amazonaws.com/123456789012/MyQueue"); + sqsHook.setSqsRegion("us-east-1"); + sqsHook.setSqsAuthType(App.AuthType.RESOURCE); + sqsHook.setCreatedAt(new Date()); + sqsHook.setUpdatedAt(new Date()); + + try { + App.update().eventHooks(Collections.singletonList(sqsHook)).request(); + } catch (StreamException e) { + if (e.getMessage().contains("cannot set event hooks in hook v1 system")) { + return; + } + throw e; + } + } + + @DisplayName("Can update app settings with SNS event hook") + @Test + void whenUpdatingAppSettingsWithSNSEventHook_thenNoException() throws StreamException { + EventHook snsHook = new EventHook(); + snsHook.setId("sns-1"); + snsHook.setHookType(App.HookType.SNS); + snsHook.setEnabled(true); + snsHook.setEventTypes(Arrays.asList("channel.created", "channel.updated")); + snsHook.setSnsTopicARN("arn:aws:sns:us-east-1:123456789012:MyTopic"); + snsHook.setSnsRegion("us-east-1"); + snsHook.setSnsAuthType(App.AuthType.RESOURCE); + snsHook.setCreatedAt(new Date()); + snsHook.setUpdatedAt(new Date()); + + try { + App.update().eventHooks(Collections.singletonList(snsHook)).request(); + } catch (StreamException e) { + if (e.getMessage().contains("cannot set event hooks in hook v1 system")) { + return; + } + throw e; + } + } }