diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/Zulip.java b/src/main/java/com/github/jamesnetherton/zulip/client/Zulip.java
index 972082dc..2972b1c2 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/Zulip.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/Zulip.java
@@ -3,6 +3,7 @@
import com.github.jamesnetherton.zulip.client.api.core.ZulipService;
import com.github.jamesnetherton.zulip.client.api.draft.DraftService;
import com.github.jamesnetherton.zulip.client.api.event.EventService;
+import com.github.jamesnetherton.zulip.client.api.invitation.InvitationService;
import com.github.jamesnetherton.zulip.client.api.message.MessageService;
import com.github.jamesnetherton.zulip.client.api.server.ServerService;
import com.github.jamesnetherton.zulip.client.api.stream.StreamService;
@@ -72,6 +73,17 @@ public Zulip(ZulipConfiguration configuration) throws ZulipClientException {
this.client = factory.createZulipHttpClient(configuration);
}
+ /**
+ * Access the collection of channel Zulip APIs.
+ *
+ * Since channels are analogous to streams. The {@link StreamService} is returned.
+ *
+ * @return The {@link StreamService} Zulip channel APIs
+ */
+ public StreamService channels() {
+ return streams();
+ }
+
/**
* Access the collection of draft Zulip APIs.
*
@@ -90,6 +102,15 @@ public EventService events() {
return (EventService) services.computeIfAbsent(EventService.class, key -> new EventService(this.client));
}
+ /**
+ * Access the collection of invitation Zulip APIs.
+ *
+ * @return The {@link InvitationService} Zulip event APIs
+ */
+ public InvitationService invitations() {
+ return (InvitationService) services.computeIfAbsent(InvitationService.class, key -> new InvitationService(this.client));
+ }
+
/**
* Access the collection of message Zulip APIs.
*
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/event/EventPoller.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/event/EventPoller.java
index f1ecb3b6..08c5de99 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/event/EventPoller.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/event/EventPoller.java
@@ -26,6 +26,8 @@ public class EventPoller {
private final MessageEventListener listener;
private final ZulipHttpClient client;
private final Narrow[] narrows;
+ private volatile ExecutorService eventListenerExecutorService;
+ private volatile boolean userManagedEventListenerExecutorService = false;
private volatile EventQueue queue;
private volatile ExecutorService executor;
private volatile Status status = Status.STOPPED;
@@ -44,6 +46,25 @@ public EventPoller(ZulipHttpClient client, MessageEventListener listener, Narrow
this.narrows = narrows;
}
+ /**
+ * Constructs a {@link EventPoller}.
+ *
+ * @param client The Zulip HTTP client
+ * @param listener The {@link MessageEventListener} to be invoked on each message event
+ * @param narrows optional {@link Narrow} expressions to filter which message events are captured. E.g
+ * messages from a
+ * specific stream
+ * @param eventListenerExecutorService Custom {@link ExecutorService} to use for message event listener execution
+ */
+ public EventPoller(ZulipHttpClient client, MessageEventListener listener, Narrow[] narrows,
+ ExecutorService eventListenerExecutorService) {
+ this.client = client;
+ this.listener = listener;
+ this.narrows = narrows;
+ this.eventListenerExecutorService = eventListenerExecutorService;
+ this.userManagedEventListenerExecutorService = true;
+ }
+
/**
* Starts event message polling.
*
@@ -60,6 +81,10 @@ public synchronized void start() throws ZulipClientException {
queue = createQueue.execute();
executor = Executors.newSingleThreadExecutor();
+ if (eventListenerExecutorService == null) {
+ eventListenerExecutorService = Executors.newCachedThreadPool();
+ }
+
executor.submit(new Runnable() {
private long lastEventId = queue.getLastEventId();
@@ -72,7 +97,7 @@ public void run() {
List messageEvents = getEvents.execute();
for (MessageEvent event : messageEvents) {
- listener.onEvent(event.getMessage());
+ eventListenerExecutorService.submit(() -> listener.onEvent(event.getMessage()));
}
lastEventId = messageEvents.stream().max(Comparator.comparing(Event::getId))
@@ -111,6 +136,11 @@ public synchronized void stop() {
LOG.info("EventPoller stopping");
status = Status.STOPPING;
executor.shutdown();
+ if (userManagedEventListenerExecutorService) {
+ eventListenerExecutorService.shutdown();
+ eventListenerExecutorService = null;
+ }
+
DeleteEventQueueApiRequest deleteQueue = new DeleteEventQueueApiRequest(this.client, queue.getQueueId());
deleteQueue.execute();
} catch (ZulipClientException e) {
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/Invitation.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/Invitation.java
new file mode 100644
index 00000000..6f6edd2e
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/Invitation.java
@@ -0,0 +1,73 @@
+package com.github.jamesnetherton.zulip.client.api.invitation;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.jamesnetherton.zulip.client.api.user.UserRole;
+import java.time.Instant;
+
+/**
+ * Defines a Zulip invitation.
+ */
+public class Invitation {
+ @JsonProperty
+ private long id;
+
+ @JsonProperty
+ private long invitedByUserId;
+
+ @JsonProperty
+ private Instant invited;
+
+ @JsonProperty
+ private Instant expiryDate;
+
+ @JsonProperty
+ private UserRole invitedAs;
+
+ @JsonProperty
+ private String email;
+
+ @JsonProperty
+ private boolean notifyReferrerOnJoin;
+
+ @JsonProperty
+ private String linkUrl;
+
+ @JsonProperty
+ private boolean isMultiuse;
+
+ public long getId() {
+ return id;
+ }
+
+ public long getInvitedByUserId() {
+ return invitedByUserId;
+ }
+
+ public Instant getInvited() {
+ return invited;
+ }
+
+ public Instant getExpiryDate() {
+ return expiryDate;
+ }
+
+ public UserRole getInvitedAs() {
+ return invitedAs;
+ }
+
+ public String getEmail() {
+ return email;
+ }
+
+ public boolean isNotifyReferrerOnJoin() {
+ return notifyReferrerOnJoin;
+ }
+
+ public String getLinkUrl() {
+ return linkUrl;
+ }
+
+ public boolean isMultiuse() {
+ return isMultiuse;
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/InvitationService.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/InvitationService.java
new file mode 100644
index 00000000..52ef771d
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/InvitationService.java
@@ -0,0 +1,99 @@
+package com.github.jamesnetherton.zulip.client.api.invitation;
+
+import com.github.jamesnetherton.zulip.client.api.core.ZulipService;
+import com.github.jamesnetherton.zulip.client.api.invitation.request.CreateReusableInvitationLinkApiRequest;
+import com.github.jamesnetherton.zulip.client.api.invitation.request.GetAllInvitationsApiRequest;
+import com.github.jamesnetherton.zulip.client.api.invitation.request.ResendEmailInvitationApiRequest;
+import com.github.jamesnetherton.zulip.client.api.invitation.request.RevokeEmailInvitationApiRequest;
+import com.github.jamesnetherton.zulip.client.api.invitation.request.RevokeReusableInvitationApiRequest;
+import com.github.jamesnetherton.zulip.client.api.invitation.request.SendInvitationsApiRequest;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+import java.util.List;
+
+/**
+ * Zulip invitation APIs.
+ */
+public class InvitationService implements ZulipService {
+
+ private final ZulipHttpClient client;
+
+ /**
+ * Constructs a {@link InvitationService}.
+ *
+ * @param client The Zulip HTTP client
+ */
+ public InvitationService(ZulipHttpClient client) {
+ this.client = client;
+ }
+
+ /**
+ * Creates a new invitation link.
+ *
+ * @see https://zulip.com/api/create-invite-link
+ *
+ * @return The {@link CreateReusableInvitationLinkApiRequest} builder object
+ */
+ public CreateReusableInvitationLinkApiRequest createReusableInvitationLink() {
+ return new CreateReusableInvitationLinkApiRequest(client);
+ }
+
+ /**
+ * Fetches all unexpired invitations.
+ *
+ * @see https://zulip.com/api/get-invites
+ *
+ * @return The {@link GetAllInvitationsApiRequest} builder object
+ */
+ public GetAllInvitationsApiRequest getAllInvitations() {
+ return new GetAllInvitationsApiRequest(client);
+ }
+
+ /**
+ * Resends an email invitation.
+ *
+ * @see https://zulip.com/api/resend-email-invite
+ *
+ * @param invitationId The id of the invitation to resend
+ * @return The {@link ResendEmailInvitationApiRequest} builder object
+ */
+ public ResendEmailInvitationApiRequest resendEmailInvitation(long invitationId) {
+ return new ResendEmailInvitationApiRequest(client, invitationId);
+ }
+
+ /**
+ * Revokes an email invitation.
+ *
+ * @see https://zulip.com/api/revoke-email-invite
+ *
+ * @param invitationId The id of the invitation to revoke
+ * @return The {@link RevokeEmailInvitationApiRequest} builder object
+ */
+ public RevokeEmailInvitationApiRequest revokeEmailInvitation(long invitationId) {
+ return new RevokeEmailInvitationApiRequest(client, invitationId);
+ }
+
+ /**
+ * Revokes a reusable invitation.
+ *
+ * @see https://zulip.com/api/revoke-invite-link
+ *
+ * @param invitationId The id of the invitation to revoke
+ * @return The {@link RevokeReusableInvitationApiRequest} builder object
+ */
+ public RevokeReusableInvitationApiRequest revokeReusableInvitation(long invitationId) {
+ return new RevokeReusableInvitationApiRequest(client, invitationId);
+ }
+
+ /**
+ * Send invitations to specified email addresses.
+ *
+ * @see https://zulip.com/api/send-invites
+ *
+ * @param inviteeEmails The list of email addresses to invite
+ * @param streamIds The list of channel ids that the newly created user will be automatically subscribed to
+ * @return The {@link SendInvitationsApiRequest} builder object
+ */
+ public SendInvitationsApiRequest sendInvitations(List inviteeEmails, List streamIds) {
+ return new SendInvitationsApiRequest(client, inviteeEmails, streamIds);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/CreateReusableInvitationLinkApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/CreateReusableInvitationLinkApiRequest.java
new file mode 100644
index 00000000..8472d2c9
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/CreateReusableInvitationLinkApiRequest.java
@@ -0,0 +1,101 @@
+package com.github.jamesnetherton.zulip.client.api.invitation.request;
+
+import static com.github.jamesnetherton.zulip.client.api.invitation.request.InvitationRequestConstants.MULTIUSE_API_PATH;
+
+import com.github.jamesnetherton.zulip.client.api.core.ExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.invitation.response.CreateReusableInvitationLinkApiResponse;
+import com.github.jamesnetherton.zulip.client.api.user.UserRole;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for creating a reusable invitation link.
+ *
+ * @see https://zulip.com/api/create-invite-link
+ */
+public class CreateReusableInvitationLinkApiRequest extends ZulipApiRequest implements ExecutableApiRequest {
+ public static final String INCLUDE_REALM_DEFAULT_SUBSCRIPTIONS = "include_realm_default_subscriptions";
+ public static final String INVITE_AS = "invite_as";
+ public static final String INVITE_EXPIRES_IN_MINUTES = "invite_expires_in_minutes";
+ public static final String STREAM_IDS = "stream_ids";
+
+ /**
+ * Constructs a {@link CreateReusableInvitationLinkApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ */
+ public CreateReusableInvitationLinkApiRequest(ZulipHttpClient client) {
+ super(client);
+ }
+
+ /**
+ * Sets whether the newly created user should be subscribed to the default channels for the organization.
+ *
+ * @see https://zulip.com/api/create-invite-link#parameter-include_realm_default_subscriptions
+ *
+ * @param includeRealmDefaultSubscriptions When {@code true}, the newly created user will be subscribed to the default
+ * channels for the organization. When {@code false} the user is not subscribed to
+ * any default channels.
+ * @return This {@link CreateReusableInvitationLinkApiRequest} instance
+ */
+ public CreateReusableInvitationLinkApiRequest withIncludeRealmDefaultSubscriptions(
+ boolean includeRealmDefaultSubscriptions) {
+ putParam(INCLUDE_REALM_DEFAULT_SUBSCRIPTIONS, includeRealmDefaultSubscriptions);
+ return this;
+ }
+
+ /**
+ * Sets the organization level role of the user that is created when the invitation is accepted.
+ *
+ * @see https://zulip.com/api/create-invite-link#parameter-invite_as
+ *
+ * @param role The {@link UserRole} that should apply to the new user
+ * @return This {@link CreateReusableInvitationLinkApiRequest} instance
+ */
+ public CreateReusableInvitationLinkApiRequest withInviteAs(UserRole role) {
+ putParam(INVITE_AS, role.getId());
+ return this;
+ }
+
+ /**
+ * Sets the number of minutes before the invitation will expire.
+ *
+ * @see https://zulip.com/api/create-invite-link#parameter-invite_expires_in_minutes
+ *
+ * @param minutes The number of minutes before the invitation will expire
+ * @return This {@link CreateReusableInvitationLinkApiRequest} instance
+ */
+ public CreateReusableInvitationLinkApiRequest inviteExpiresInMinutes(int minutes) {
+ putParam(INVITE_EXPIRES_IN_MINUTES, minutes);
+ return this;
+ }
+
+ /**
+ * Sets the list of channel ids that the newly created user will be automatically subscribed to.
+ *
+ * @see https://zulip.com/api/create-invite-link#parameter-stream_ids
+ *
+ * @param streamIds The ids of channels that the newly created user will be automatically subscribed to
+ * @return This {@link CreateReusableInvitationLinkApiRequest} instance
+ */
+ public CreateReusableInvitationLinkApiRequest streamIds(long... streamIds) {
+ putParamAsJsonString(STREAM_IDS, streamIds);
+ return this;
+ }
+
+ /**
+ * Executes the Zulip API request for creating a reusable invitation link.
+ *
+ * @return The generated invitation link URL
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public String execute() throws ZulipClientException {
+ return client().post(MULTIUSE_API_PATH, getParams(), CreateReusableInvitationLinkApiResponse.class).getInviteLink();
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/GetAllInvitationsApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/GetAllInvitationsApiRequest.java
new file mode 100644
index 00000000..5aa22479
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/GetAllInvitationsApiRequest.java
@@ -0,0 +1,38 @@
+package com.github.jamesnetherton.zulip.client.api.invitation.request;
+
+import static com.github.jamesnetherton.zulip.client.api.invitation.request.InvitationRequestConstants.INVITATIONS_API_PATH;
+
+import com.github.jamesnetherton.zulip.client.api.core.ExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.invitation.Invitation;
+import com.github.jamesnetherton.zulip.client.api.invitation.response.GetAllInvitationsApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+import java.util.List;
+
+/**
+ * Zulip API request builder for fetching invitations.
+ *
+ * @see https://zulip.com/api/get-invites
+ */
+public class GetAllInvitationsApiRequest extends ZulipApiRequest implements ExecutableApiRequest> {
+ /**
+ * Constructs a {@link GetAllInvitationsApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ */
+ public GetAllInvitationsApiRequest(ZulipHttpClient client) {
+ super(client);
+ }
+
+ /**
+ * Executes the Zulip API request for fetching invitations.
+ *
+ * @return List of {@link Invitation} containing each unexpired invitation
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public List execute() throws ZulipClientException {
+ return client().get(INVITATIONS_API_PATH, getParams(), GetAllInvitationsApiResponse.class).getInvites();
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/InvitationRequestConstants.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/InvitationRequestConstants.java
new file mode 100644
index 00000000..f71a7a85
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/InvitationRequestConstants.java
@@ -0,0 +1,12 @@
+package com.github.jamesnetherton.zulip.client.api.invitation.request;
+
+final class InvitationRequestConstants {
+ final static String INVITATIONS_API_PATH = "invites";
+ final static String INVITATIONS_WITH_ID = INVITATIONS_API_PATH + "/%d";
+ final static String MULTIUSE_API_PATH = INVITATIONS_API_PATH + "/multiuse";
+ final static String MULTIUSE_WITH_ID = MULTIUSE_API_PATH + "/%d";
+ final static String RESEND = INVITATIONS_WITH_ID + "/resend";
+
+ private InvitationRequestConstants() {
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/ResendEmailInvitationApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/ResendEmailInvitationApiRequest.java
new file mode 100644
index 00000000..02090068
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/ResendEmailInvitationApiRequest.java
@@ -0,0 +1,40 @@
+package com.github.jamesnetherton.zulip.client.api.invitation.request;
+
+import static com.github.jamesnetherton.zulip.client.api.invitation.request.InvitationRequestConstants.RESEND;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for resending an email invitation.
+ *
+ * @see https://zulip.com/api/resend-email-invite
+ */
+public class ResendEmailInvitationApiRequest extends ZulipApiRequest implements VoidExecutableApiRequest {
+ private final long invitationId;
+
+ /**
+ * Constructs a {@link ResendEmailInvitationApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param invitationId The id of the invitation to resend
+ */
+ public ResendEmailInvitationApiRequest(ZulipHttpClient client, long invitationId) {
+ super(client);
+ this.invitationId = invitationId;
+ }
+
+ /**
+ * Executes the Zulip API request for resending an email invitation.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ String path = String.format(RESEND, invitationId);
+ client().post(path, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/RevokeEmailInvitationApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/RevokeEmailInvitationApiRequest.java
new file mode 100644
index 00000000..b2416931
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/RevokeEmailInvitationApiRequest.java
@@ -0,0 +1,40 @@
+package com.github.jamesnetherton.zulip.client.api.invitation.request;
+
+import static com.github.jamesnetherton.zulip.client.api.invitation.request.InvitationRequestConstants.INVITATIONS_WITH_ID;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for revoking an email invitation.
+ *
+ * @see https://zulip.com/api/revoke-email-invite
+ */
+public class RevokeEmailInvitationApiRequest extends ZulipApiRequest implements VoidExecutableApiRequest {
+ private final long invitationId;
+
+ /**
+ * Constructs a {@link RevokeEmailInvitationApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param invitationId The id of the invitation to revoke
+ */
+ public RevokeEmailInvitationApiRequest(ZulipHttpClient client, long invitationId) {
+ super(client);
+ this.invitationId = invitationId;
+ }
+
+ /**
+ * Executes the Zulip API request for revoking an email invitation.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ String path = String.format(INVITATIONS_WITH_ID, invitationId);
+ client().delete(path, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/RevokeReusableInvitationApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/RevokeReusableInvitationApiRequest.java
new file mode 100644
index 00000000..0270a298
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/RevokeReusableInvitationApiRequest.java
@@ -0,0 +1,40 @@
+package com.github.jamesnetherton.zulip.client.api.invitation.request;
+
+import static com.github.jamesnetherton.zulip.client.api.invitation.request.InvitationRequestConstants.MULTIUSE_WITH_ID;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for revoking a reusable invitation.
+ *
+ * @see https://zulip.com/api/revoke-invite-link
+ */
+public class RevokeReusableInvitationApiRequest extends ZulipApiRequest implements VoidExecutableApiRequest {
+ private final long invitationId;
+
+ /**
+ * Constructs a {@link RevokeReusableInvitationApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param invitationId The id of the invitation to revoke
+ */
+ public RevokeReusableInvitationApiRequest(ZulipHttpClient client, long invitationId) {
+ super(client);
+ this.invitationId = invitationId;
+ }
+
+ /**
+ * Executes the Zulip API request for revoking a reusable invitation.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ String path = String.format(MULTIUSE_WITH_ID, invitationId);
+ client().delete(path, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/SendInvitationsApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/SendInvitationsApiRequest.java
new file mode 100644
index 00000000..d60fea08
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/request/SendInvitationsApiRequest.java
@@ -0,0 +1,107 @@
+package com.github.jamesnetherton.zulip.client.api.invitation.request;
+
+import static com.github.jamesnetherton.zulip.client.api.invitation.request.InvitationRequestConstants.INVITATIONS_API_PATH;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.api.user.UserRole;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+import java.util.List;
+
+/**
+ * Zulip API request builder for sending user invitations.
+ *
+ * @see https://zulip.com/api/send-invites
+ */
+public class SendInvitationsApiRequest extends ZulipApiRequest implements VoidExecutableApiRequest {
+ public static final String INCLUDE_REALM_DEFAULT_SUBSCRIPTIONS = "include_realm_default_subscriptions";
+ public static final String INVITEE_EMAILS = "invitee_emails";
+ public static final String INVITE_AS = "invite_as";
+ public static final String INVITE_EXPIRES_IN_MINUTES = "invite_expires_in_minutes";
+ public static final String NOTIFIY_REFERRER_ON_JOIN = "notify_referrer_on_join";
+ public static final String STREAM_IDS = "stream_ids";
+
+ /**
+ * Constructs a {@link SendInvitationsApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param inviteeEmails The list of email addresses to invite
+ * @param streamIds The list of channel ids that the newly created user will be automatically subscribed to
+ */
+ public SendInvitationsApiRequest(ZulipHttpClient client, List inviteeEmails, List streamIds) {
+ super(client);
+ putParam(INVITEE_EMAILS, String.join(",", inviteeEmails));
+ putParamAsJsonString(STREAM_IDS, streamIds.toArray(new Long[0]));
+ }
+
+ /**
+ * Sets whether the newly created user should be subscribed to the default channels for the organization.
+ *
+ * @see https://zulip.com/api/send-invites#parameter-include_realm_default_subscriptions
+ *
+ * @param includeRealmDefaultSubscriptions When {@code true}, the newly created user will be subscribed to the default
+ * channels for the organization. When {@code false} the user is not subscribed to
+ * any default channels.
+ * @return This {@link SendInvitationsApiRequest} instance
+ */
+ public SendInvitationsApiRequest withIncludeRealmDefaultSubscriptions(boolean includeRealmDefaultSubscriptions) {
+ putParam(INCLUDE_REALM_DEFAULT_SUBSCRIPTIONS, includeRealmDefaultSubscriptions);
+ return this;
+ }
+
+ /**
+ * Sets the organization level role of the user that is created when the invitation is accepted.
+ *
+ * @see https://zulip.com/api/send-invites#parameter-invite_as
+ *
+ * @param role The {@link UserRole} that should apply to the new user
+ * @return This {@link SendInvitationsApiRequest} instance
+ */
+ public SendInvitationsApiRequest withInviteAs(UserRole role) {
+ putParam(INVITE_AS, role.getId());
+ return this;
+ }
+
+ /**
+ * Sets the number of minutes before the invitation will expire.
+ *
+ * @see https://zulip.com/api/send-invites#parameter-invite_expires_in_minutes
+ *
+ * @param minutes The number of minutes before the invitation will expire
+ * @return This {@link SendInvitationsApiRequest} instance
+ */
+ public SendInvitationsApiRequest inviteExpiresInMinutes(int minutes) {
+ putParam(INVITE_EXPIRES_IN_MINUTES, minutes);
+ return this;
+ }
+
+ /**
+ * Sets whether the referrer would like to receive a direct message from notification bot when a user account is created.
+ *
+ * @see https://zulip.com/api/send-invites#parameter-notify_referrer_on_join
+ *
+ * @param notifyReferrerOnJoin When {@code true} the referrer will receive a direct message from notification bot when a
+ * user account is created. When {@code false} no notification is sent
+ * @return This {@link SendInvitationsApiRequest} instance
+ */
+ public SendInvitationsApiRequest withNotifyReferrerOnJoin(boolean notifyReferrerOnJoin) {
+ putParam(NOTIFIY_REFERRER_ON_JOIN, notifyReferrerOnJoin);
+ return this;
+ }
+
+ /**
+ * Executes the Zulip API request for sending user invitations.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ client().post(INVITATIONS_API_PATH, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/response/CreateReusableInvitationLinkApiResponse.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/response/CreateReusableInvitationLinkApiResponse.java
new file mode 100644
index 00000000..0f47b55e
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/response/CreateReusableInvitationLinkApiResponse.java
@@ -0,0 +1,18 @@
+package com.github.jamesnetherton.zulip.client.api.invitation.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+
+/**
+ * Zulip API response class for creating a reusable invitation link.
+ *
+ * @see https://zulip.com/api/create-invite-link#response
+ */
+public class CreateReusableInvitationLinkApiResponse extends ZulipApiResponse {
+ @JsonProperty
+ private String inviteLink;
+
+ public String getInviteLink() {
+ return inviteLink;
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/response/GetAllInvitationsApiResponse.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/response/GetAllInvitationsApiResponse.java
new file mode 100644
index 00000000..46a0b434
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/invitation/response/GetAllInvitationsApiResponse.java
@@ -0,0 +1,21 @@
+package com.github.jamesnetherton.zulip.client.api.invitation.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.api.invitation.Invitation;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Zulip API response class for fetching invitations.
+ *
+ * @see https://zulip.com/api/get-invites#response
+ */
+public class GetAllInvitationsApiResponse extends ZulipApiResponse {
+ @JsonProperty
+ List invites = new ArrayList<>();
+
+ public List getInvites() {
+ return invites;
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/MessageService.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/MessageService.java
index 6c9a4dbd..da29ebf3 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/MessageService.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/MessageService.java
@@ -287,6 +287,34 @@ public RenderMessageApiRequest renderMessage(String content) {
return new RenderMessageApiRequest(this.client, content);
}
+ /**
+ * Sends a channel message to the given channel name and topic.
+ *
+ * @see https://zulip.com/api/send-message
+ *
+ * @param content The content of the message
+ * @param channelName The name of the channel to send the message to
+ * @param topic The name of the message topic
+ * @return The {@link SendMessageApiRequest} builder object
+ */
+ public SendMessageApiRequest sendChannelMessage(String content, String channelName, String topic) {
+ return new SendMessageApiRequest(this.client, content, channelName, topic, MessageType.CHANNEL);
+ }
+
+ /**
+ * Sends a channel message to the given channel id and topic.
+ *
+ * @see https://zulip.com/api/send-message
+ *
+ * @param content The content of the message
+ * @param channelId The id of the stream to send the message to
+ * @param topic The name of the message topic
+ * @return The {@link SendMessageApiRequest} builder object
+ */
+ public SendMessageApiRequest sendChannelMessage(String content, long channelId, String topic) {
+ return new SendMessageApiRequest(this.client, content, channelId, topic, MessageType.CHANNEL);
+ }
+
/**
* Sends a direct message to the users matching the given email addresses.
*
@@ -313,36 +341,6 @@ public SendMessageApiRequest sendDirectMessage(String content, long... userIds)
return new SendMessageApiRequest(this.client, content, userIds);
}
- /**
- * Sends a private message to the users matching the given email addresses.
- *
- * @see https://zulip.com/api/send-message
- *
- * @param content The content of the message
- * @param userEmails The email addresses of the users to send the message to
- * @return The {@link SendMessageApiRequest} builder object
- * @deprecated Use sendDirectMessage instead
- */
- @Deprecated(forRemoval = true)
- public SendMessageApiRequest sendPrivateMessage(String content, String... userEmails) {
- return sendDirectMessage(content, userEmails);
- }
-
- /**
- * Sends a private message to the users matching the given email user ids.
- *
- * @see https://zulip.com/api/send-message
- *
- * @param content The content of the message
- * @param userIds The ids of the users to send the message to
- * @return The {@link SendMessageApiRequest} builder object
- * @deprecated Use sendDirectMessage instead
- */
- @Deprecated(forRemoval = true)
- public SendMessageApiRequest sendPrivateMessage(String content, long... userIds) {
- return sendDirectMessage(content, userIds);
- }
-
/**
* Schedules the sending of a message to a specified stream or users.
*
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/MessageType.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/MessageType.java
index 41e0dfd1..085e7139 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/MessageType.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/MessageType.java
@@ -6,6 +6,10 @@
* Defines the type of Zulip message.
*/
public enum MessageType {
+ /**
+ * The message is a channel message.
+ */
+ CHANNEL,
/**
* The message is a direct message.
*/
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/ReactionType.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/ReactionType.java
index febe50ad..7601d7f1 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/ReactionType.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/ReactionType.java
@@ -1,5 +1,7 @@
package com.github.jamesnetherton.zulip.client.api.message;
+import com.fasterxml.jackson.annotation.JsonCreator;
+
/**
* Defines the Zulip emoji reaction type.
*/
@@ -17,6 +19,14 @@ public enum ReactionType {
*/
ZULIP_EXTRA;
+ @JsonCreator
+ public static ReactionType fromString(String type) {
+ if (type == null || type.isEmpty()) {
+ return ReactionType.UNICODE;
+ }
+ return ReactionType.valueOf(type.toUpperCase().replace("_EMOJI", ""));
+ }
+
@Override
public String toString() {
return this.name().toLowerCase() + "_emoji";
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/request/FileUploadApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/request/FileUploadApiRequest.java
index de2e0daf..7dff5cbe 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/request/FileUploadApiRequest.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/request/FileUploadApiRequest.java
@@ -37,6 +37,9 @@ public FileUploadApiRequest(ZulipHttpClient client, File file) {
@Override
public String execute() throws ZulipClientException {
FileUploadApiResponse response = client().upload(USER_UPLOADS_API_PATH, file, FileUploadApiResponse.class);
- return response.getUri();
+ if (response.getUri() != null) {
+ return response.getUri();
+ }
+ return response.getUrl();
}
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/request/SendMessageApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/request/SendMessageApiRequest.java
index d2fae6e5..4030fce3 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/request/SendMessageApiRequest.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/request/SendMessageApiRequest.java
@@ -90,6 +90,40 @@ public SendMessageApiRequest(ZulipHttpClient client, String content, long stream
putParam(TOPIC, topic);
}
+ /**
+ * Constructs a {@link SendMessageApiRequest} for sending a message to a stream.
+ *
+ * @param client The Zulip HTTP client
+ * @param content The message content
+ * @param streamName The name of the stream to which the stream should be sent to
+ * @param topic The name od the topic to post the message under
+ * @param type The {@link MessageType} for the type of message to send
+ */
+ public SendMessageApiRequest(ZulipHttpClient client, String content, String streamName, String topic, MessageType type) {
+ super(client);
+ putParam(CONTENT, content);
+ putParam(TYPE, type.toString());
+ putParam(TO_STREAM, streamName);
+ putParam(TOPIC, topic);
+ }
+
+ /**
+ * Constructs a {@link SendMessageApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param content The message content
+ * @param streamId The id of the stream to which the stream should be sent to
+ * @param topic The name od the topic to post the message under
+ * @param type The {@link MessageType} for the type of message to send
+ */
+ public SendMessageApiRequest(ZulipHttpClient client, String content, long streamId, String topic, MessageType type) {
+ super(client);
+ putParam(CONTENT, content);
+ putParam(TYPE, type.toString());
+ putParam(TO_STREAM, streamId);
+ putParam(TOPIC, topic);
+ }
+
/**
* The optional local id associated with the message.
*
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/response/FileUploadApiResponse.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/response/FileUploadApiResponse.java
index 9129700d..6142f86a 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/message/response/FileUploadApiResponse.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/message/response/FileUploadApiResponse.java
@@ -9,11 +9,19 @@
* @see https://zulip.com/api/get-message-history#response
*/
public class FileUploadApiResponse extends ZulipApiResponse {
-
+ @Deprecated(since = "0.7", forRemoval = true)
@JsonProperty
private String uri;
+ @JsonProperty
+ private String url;
+
public String getUri() {
return uri;
}
+
+ @Deprecated(since = "0.7", forRemoval = true)
+ public String getUrl() {
+ return url;
+ }
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ProfileField.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ProfileField.java
index 2e44713b..00047997 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ProfileField.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ProfileField.java
@@ -35,6 +35,9 @@ public class ProfileField {
@JsonProperty
private boolean displayInProfileSummary;
+ @JsonProperty
+ private boolean required;
+
@JsonCreator
public ProfileField(JsonNode node) {
this.hint = node.get("hint").asText();
@@ -42,6 +45,9 @@ public ProfileField(JsonNode node) {
this.name = node.get("name").asText();
this.order = node.get("order").asInt();
this.type = ProfileFieldType.fromInt(node.get("type").asInt());
+ if (node.has("required")) {
+ this.required = node.get("required").asBoolean();
+ }
if (node.has("display_in_profile_summary")) {
this.displayInProfileSummary = node.get("display_in_profile_summary").asBoolean();
}
@@ -115,4 +121,8 @@ public ProfileFieldType getType() {
public boolean isDisplayInProfileSummary() {
return displayInProfileSummary;
}
+
+ public boolean isRequired() {
+ return required;
+ }
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ServerService.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ServerService.java
index 80486ea1..0c7c32d0 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ServerService.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ServerService.java
@@ -1,8 +1,11 @@
package com.github.jamesnetherton.zulip.client.api.server;
import com.github.jamesnetherton.zulip.client.api.core.ZulipService;
+import com.github.jamesnetherton.zulip.client.api.server.request.AddApnsDeviceTokenApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.AddCodePlaygroundApiRequest;
+import com.github.jamesnetherton.zulip.client.api.server.request.AddFcmRegistrationTokenApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.AddLinkifierApiRequest;
+import com.github.jamesnetherton.zulip.client.api.server.request.CreateBigBlueButtonVideoCallApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.CreateProfileFieldApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.DeleteLinkifierApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.DeleteProfileFieldApiRequest;
@@ -11,9 +14,12 @@
import com.github.jamesnetherton.zulip.client.api.server.request.GetLinkifiersApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.GetProfileFieldsApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.GetServerSettingsApiRequest;
+import com.github.jamesnetherton.zulip.client.api.server.request.RemoveApnsDeviceTokenApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.RemoveCodePlaygroundApiRequest;
+import com.github.jamesnetherton.zulip.client.api.server.request.RemoveFcmRegistrationTokenApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.ReorderLinkifiersApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.ReorderProfileFieldsApiRequest;
+import com.github.jamesnetherton.zulip.client.api.server.request.SendMobilePushTestNotification;
import com.github.jamesnetherton.zulip.client.api.server.request.UpdateLinkifierApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.UpdateRealmNewUserDefaultSettingsApiRequest;
import com.github.jamesnetherton.zulip.client.api.server.request.UploadEmojiApiRequest;
@@ -246,4 +252,77 @@ public RemoveCodePlaygroundApiRequest removeCodePlayground(long codePlaygroundId
public UpdateRealmNewUserDefaultSettingsApiRequest updateRealmNewUserDefaultSettings() {
return new UpdateRealmNewUserDefaultSettingsApiRequest(this.client);
}
+
+ /**
+ * Sends mobile push test notifications.
+ *
+ * @see https://zulip.com/api/test-notify
+ *
+ * @return The {@link SendMobilePushTestNotification} builder object
+ */
+ public SendMobilePushTestNotification sendMobilePushTestNotification() {
+ return new SendMobilePushTestNotification(this.client);
+ }
+
+ /**
+ * Adds an APNs device token to register for iOS push notifications
+ *
+ * @see https://zulip.com/api/add-apns-token
+ *
+ * @param token The token provided by the device
+ * @param appId The ID of the Zulip app that is making the request
+ * @return The {@link AddApnsDeviceTokenApiRequest} builder object
+ */
+ public AddApnsDeviceTokenApiRequest addApnsDeviceToken(String token, String appId) {
+ return new AddApnsDeviceTokenApiRequest(this.client, token, appId);
+ }
+
+ /**
+ * Removes an APNs device token.
+ *
+ * @see https://zulip.com/api/remove-apns-token
+ *
+ * @param token The token provided by the device
+ * @return The {@link RemoveApnsDeviceTokenApiRequest} builder object
+ */
+ public RemoveApnsDeviceTokenApiRequest removeApnsDeviceToken(String token) {
+ return new RemoveApnsDeviceTokenApiRequest(this.client, token);
+ }
+
+ /**
+ * Adds an FCM registration token.
+ *
+ * @see https://zulip.com/api/add-fcm-token
+ *
+ * @param token The token provided by the device
+ * @return The {@link AddFcmRegistrationTokenApiRequest} builder object
+ */
+ public AddFcmRegistrationTokenApiRequest addFcmRegsitrationToken(String token) {
+ return new AddFcmRegistrationTokenApiRequest(this.client, token);
+ }
+
+ /**
+ * Removes an FCM registration token.
+ *
+ * @see https://zulip.com/api/remove-fcm-token
+ *
+ * @param token The token provided by the device
+ * @return The {@link RemoveFcmRegistrationTokenApiRequest} builder object
+ */
+ public RemoveFcmRegistrationTokenApiRequest removeFcmRegistrationToken(String token) {
+ return new RemoveFcmRegistrationTokenApiRequest(this.client, token);
+ }
+
+ /**
+ * Creates a BigBlueButton video call.
+ *
+ * @see https://zulip.com/api/create-big-blue-button-video-call
+ *
+ * @param meetingName Meeting name for the BigBlueButton video call
+ * @return The {@link CreateBigBlueButtonVideoCallApiRequest} builder object
+ */
+ public CreateBigBlueButtonVideoCallApiRequest createBigBlueButtonVideoCall(String meetingName) {
+ return new CreateBigBlueButtonVideoCallApiRequest(this.client, meetingName);
+ }
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ServerSettings.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ServerSettings.java
index 9ae6618f..87bbab54 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ServerSettings.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/ServerSettings.java
@@ -46,10 +46,15 @@ public String getRealmName() {
return delegate.getRealmName();
}
+ @Deprecated(since = "0.7.0", forRemoval = true)
public String getRealmUri() {
return delegate.getRealmUri();
}
+ public String getRealmUrl() {
+ return delegate.getRealmUrl();
+ }
+
public boolean isRealmWebPublicAccessEnabled() {
return delegate.isRealmWebPublicAccessEnabled();
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/AddApnsDeviceTokenApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/AddApnsDeviceTokenApiRequest.java
new file mode 100644
index 00000000..0a44325b
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/AddApnsDeviceTokenApiRequest.java
@@ -0,0 +1,43 @@
+package com.github.jamesnetherton.zulip.client.api.server.request;
+
+import static com.github.jamesnetherton.zulip.client.api.server.request.ServerRequestConstants.USERS_APNS_DEVICE_TOKEN;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for adding APNs device token to register for iOS push notifications.
+ *
+ * @see https://zulip.com/api/add-apns-token
+ *
+ */
+public class AddApnsDeviceTokenApiRequest extends ZulipApiRequest implements VoidExecutableApiRequest {
+ public static final String APP_ID = "appid";
+ public static final String TOKEN = "token";
+
+ /**
+ * Constructs a {@link AddApnsDeviceTokenApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param token The token provided by the device
+ * @param appId The ID of the Zulip app that is making the request
+ */
+ public AddApnsDeviceTokenApiRequest(ZulipHttpClient client, String token, String appId) {
+ super(client);
+ putParam(TOKEN, token);
+ putParam(APP_ID, appId);
+ }
+
+ /**
+ * Executes the Zulip API request for for adding APNs device token to register for iOS push notifications.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ client().post(USERS_APNS_DEVICE_TOKEN, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/AddFcmRegistrationTokenApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/AddFcmRegistrationTokenApiRequest.java
new file mode 100644
index 00000000..9751d39e
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/AddFcmRegistrationTokenApiRequest.java
@@ -0,0 +1,40 @@
+package com.github.jamesnetherton.zulip.client.api.server.request;
+
+import static com.github.jamesnetherton.zulip.client.api.server.request.ServerRequestConstants.USERS_ANDROID_GCM_REG_ID;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for adding an FCM registration token.
+ *
+ * @see https://zulip.com/api/add-fcm-token
+ *
+ */
+public class AddFcmRegistrationTokenApiRequest extends ZulipApiRequest implements VoidExecutableApiRequest {
+ public static final String TOKEN = "token";
+
+ /**
+ * Constructs a {@link RemoveFcmRegistrationTokenApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param token The token provided by the device
+ */
+ public AddFcmRegistrationTokenApiRequest(ZulipHttpClient client, String token) {
+ super(client);
+ putParam(TOKEN, token);
+ }
+
+ /**
+ * Executes the Zulip API request for adding an FCM registration token.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ client().post(USERS_ANDROID_GCM_REG_ID, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/CreateBigBlueButtonVideoCallApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/CreateBigBlueButtonVideoCallApiRequest.java
new file mode 100644
index 00000000..294d2d31
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/CreateBigBlueButtonVideoCallApiRequest.java
@@ -0,0 +1,42 @@
+package com.github.jamesnetherton.zulip.client.api.server.request;
+
+import static com.github.jamesnetherton.zulip.client.api.server.request.ServerRequestConstants.CALLS_BIG_BLUE_BUTTON;
+
+import com.github.jamesnetherton.zulip.client.api.core.ExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.server.response.CreateBigBlueButtonVideoCallApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for creating a BigBlueButton video call.
+ *
+ * @see https://zulip.com/api/create-big-blue-button-video-call
+ *
+ */
+public class CreateBigBlueButtonVideoCallApiRequest extends ZulipApiRequest implements ExecutableApiRequest {
+ public static final String MEETING_NAME = "meeting_name";
+
+ /**
+ * Constructs a {@link CreateBigBlueButtonVideoCallApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param meetingName Meeting name for the BigBlueButton video call
+ */
+ public CreateBigBlueButtonVideoCallApiRequest(ZulipHttpClient client, String meetingName) {
+ super(client);
+ putParam(MEETING_NAME, meetingName);
+ }
+
+ /**
+ * Executes the Zulip API request for creating a BigBlueButton video call.
+ *
+ * @return The URL of the created BigBlueButton video call.
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public String execute() throws ZulipClientException {
+ return client().get(CALLS_BIG_BLUE_BUTTON, getParams(), CreateBigBlueButtonVideoCallApiResponse.class).getUrl();
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/CreateProfileFieldApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/CreateProfileFieldApiRequest.java
index d3e0c17a..711b4e10 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/CreateProfileFieldApiRequest.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/CreateProfileFieldApiRequest.java
@@ -27,6 +27,7 @@ public class CreateProfileFieldApiRequest extends ZulipApiRequest implements Exe
public static final String FIELD_TYPE = "field_type";
public static final String FIELD_DATA = "field_data";
public static final String DISPLAY_IN_PROFILE_SUMMARY = "display_in_profile_summary";
+ public static final String REQUIRED = "required";
/**
* Constructs a {@link CreateProfileFieldApiRequest}.
@@ -109,6 +110,17 @@ public CreateProfileFieldApiRequest withDisplayInProfileSummary(boolean isDispla
return this;
}
+ /**
+ * Sets whether the profile field is required.
+ *
+ * @param required Whether the profile field is required
+ * @return This {@link CreateProfileFieldApiRequest} instance
+ */
+ public CreateProfileFieldApiRequest withRequired(boolean required) {
+ putParam(REQUIRED, required);
+ return this;
+ }
+
/**
* Executes the Zulip API request for creating a custom profile field.
*
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/RemoveApnsDeviceTokenApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/RemoveApnsDeviceTokenApiRequest.java
new file mode 100644
index 00000000..b8ff6af8
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/RemoveApnsDeviceTokenApiRequest.java
@@ -0,0 +1,40 @@
+package com.github.jamesnetherton.zulip.client.api.server.request;
+
+import static com.github.jamesnetherton.zulip.client.api.server.request.ServerRequestConstants.USERS_APNS_DEVICE_TOKEN;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for removing an APNs device token.
+ *
+ * @see https://zulip.com/api/remove-apns-token
+ *
+ */
+public class RemoveApnsDeviceTokenApiRequest extends ZulipApiRequest implements VoidExecutableApiRequest {
+ public static final String TOKEN = "token";
+
+ /**
+ * Constructs a {@link RemoveApnsDeviceTokenApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param token The token provided by the device
+ */
+ public RemoveApnsDeviceTokenApiRequest(ZulipHttpClient client, String token) {
+ super(client);
+ putParam(TOKEN, token);
+ }
+
+ /**
+ * Executes the Zulip API request for removing an APNs device token.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ client().delete(USERS_APNS_DEVICE_TOKEN, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/RemoveFcmRegistrationTokenApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/RemoveFcmRegistrationTokenApiRequest.java
new file mode 100644
index 00000000..d4f7ff9e
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/RemoveFcmRegistrationTokenApiRequest.java
@@ -0,0 +1,40 @@
+package com.github.jamesnetherton.zulip.client.api.server.request;
+
+import static com.github.jamesnetherton.zulip.client.api.server.request.ServerRequestConstants.USERS_ANDROID_GCM_REG_ID;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for removing an FCM registration token.
+ *
+ * @see https://zulip.com/api/remove-fcm-token
+ *
+ */
+public class RemoveFcmRegistrationTokenApiRequest extends ZulipApiRequest implements VoidExecutableApiRequest {
+ public static final String TOKEN = "token";
+
+ /**
+ * Constructs a {@link RemoveFcmRegistrationTokenApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param token The token provided by the device
+ */
+ public RemoveFcmRegistrationTokenApiRequest(ZulipHttpClient client, String token) {
+ super(client);
+ putParam(TOKEN, token);
+ }
+
+ /**
+ * Executes the Zulip API request for removing an FCM registration token.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ client().delete(USERS_ANDROID_GCM_REG_ID, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/SendMobilePushTestNotification.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/SendMobilePushTestNotification.java
new file mode 100644
index 00000000..085af038
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/SendMobilePushTestNotification.java
@@ -0,0 +1,52 @@
+package com.github.jamesnetherton.zulip.client.api.server.request;
+
+import static com.github.jamesnetherton.zulip.client.api.server.request.ServerRequestConstants.MOBILE_PUSH_TEST;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for sending mobile push test notifications.
+ *
+ * @see https://zulip.com/api/test-notify
+ *
+ */
+public class SendMobilePushTestNotification extends ZulipApiRequest implements VoidExecutableApiRequest {
+ public static final String TOKEN = "token";
+
+ /**
+ * Constructs a {@link SendMobilePushTestNotification}.
+ *
+ * @param client The Zulip HTTP client
+ */
+ public SendMobilePushTestNotification(ZulipHttpClient client) {
+ super(client);
+ }
+
+ /**
+ * The push token for the device to which to send the test notification.
+ *
+ * @see https://zulip.com/api/test-notify#parameter-token
+ *
+ * @param token The mobile device token
+ * @return This {@link SendMobilePushTestNotification} instance
+ */
+ public SendMobilePushTestNotification withToken(String token) {
+ putParam(TOKEN, token);
+ return this;
+ }
+
+ /**
+ * Executes the Zulip API request for sending mobile push test notifications.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ client().post(MOBILE_PUSH_TEST, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/ServerRequestConstants.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/ServerRequestConstants.java
index e6d522a7..eb9d73d7 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/ServerRequestConstants.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/ServerRequestConstants.java
@@ -1,9 +1,10 @@
package com.github.jamesnetherton.zulip.client.api.server.request;
final class ServerRequestConstants {
-
+ public static final String CALLS_BIG_BLUE_BUTTON = "calls/bigbluebutton/create";
public static final String DEV_FETCH_API_KEY = "dev_fetch_api_key";
public static final String FETCH_API_KEY = "fetch_api_key";
+ public static final String MOBILE_PUSH_TEST = "mobile_push/test_notification";
public static final String REALM = "realm";
public static final String REALM_EMOJI = REALM + "/emoji";
public static final String REALM_EMOJI_WITH_NAME = REALM_EMOJI + "/%s";
@@ -16,6 +17,9 @@ final class ServerRequestConstants {
public static final String REALM_PROFILE_FIELDS_WITH_ID = REALM_PROFILE_FIELDS + "/%d";
public static final String REALM_USER_SETTINGS_DEFAULTS = REALM + "/user_settings_defaults";
public static final String SERVER_SETTINGS = "server_settings";
+ public static final String USERS_WITH_ME = "users/me";
+ public static final String USERS_APNS_DEVICE_TOKEN = USERS_WITH_ME + "/apns_device_token";
+ public static final String USERS_ANDROID_GCM_REG_ID = USERS_WITH_ME + "/android_gcm_reg_id";
private ServerRequestConstants() {
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/UpdateRealmNewUserDefaultSettingsApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/UpdateRealmNewUserDefaultSettingsApiRequest.java
index 1166bd19..80b1bf4d 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/UpdateRealmNewUserDefaultSettingsApiRequest.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/request/UpdateRealmNewUserDefaultSettingsApiRequest.java
@@ -16,8 +16,9 @@
import com.github.jamesnetherton.zulip.client.api.user.DesktopIconCountDisplay;
import com.github.jamesnetherton.zulip.client.api.user.EmojiSet;
import com.github.jamesnetherton.zulip.client.api.user.UserListStyle;
+import com.github.jamesnetherton.zulip.client.api.user.WebAnimateImageOption;
+import com.github.jamesnetherton.zulip.client.api.user.WebChannelView;
import com.github.jamesnetherton.zulip.client.api.user.WebHomeView;
-import com.github.jamesnetherton.zulip.client.api.user.request.UpdateOwnUserSettingsApiRequest;
import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
import java.util.List;
@@ -65,6 +66,7 @@ public class UpdateRealmNewUserDefaultSettingsApiRequest extends ZulipApiRequest
public static final String PRESENCE_ENABLED = "presence_enabled";
public static final String REALM_NAME_IN_NOTIFICATIONS = "realm_name_in_notifications";
public static final String REALM_NAME_IN_EMAIL_NOTIFICATIONS_POLICY = "realm_name_in_email_notifications_policy";
+ public static final String RECEIVES_TYPING_NOTIFICATIONS = "receives_typing_notifications";
public static final String SEND_PRIVATE_TYPING_NOTIFICATIONS = "send_private_typing_notifications";
public static final String SEND_READ_RECEIPTS = "send_read_receipts";
public static final String SEND_STREAM_TYPING_NOTIFICATIONS = "send_stream_typing_notifications";
@@ -72,8 +74,13 @@ public class UpdateRealmNewUserDefaultSettingsApiRequest extends ZulipApiRequest
public static final String TRANSLATE_EMOTICONS = "translate_emoticons";
public static final String TWENTY_FOUR_HOUR_TIME = "twenty_four_hour_time";
public static final String USER_LIST_STYLE = "user_list_style";
+ public static final String WEB_ANIMATE_IMAGE_PREVIEWS = "web_animate_image_previews";
+ public static final String WEB_CHANNEL_DEFAULT_VIEW = "web_channel_default_view";
public static final String WEB_ESCAPE_NAVIGATES_TO_HOME_VIEW = "web_escape_navigates_to_home_view";
+ public static final String WEB_FONT_SIZE_PX = "web_font_size_px";
+ public static final String WEB_LINE_HEIGHT_PERCENT = "web_line_height_percent";
public static final String WEB_MARK_READ_ON_SCROLL_POLICY = "web_mark_read_on_scroll_policy";
+ public static final String WEB_NAVIGATE_TO_SENT_MESSAGE = "web_navigate_to_sent_message";
public static final String WEB_HOME_VIEW = "web_home_view";
public static final String WEB_STREAM_UNREADS_COUNT_DISPLAY_POLICY = "web_stream_unreads_count_display_policy";
public static final String WILDCARD_MENTIONS_NOTIFY = "wildcard_mentions_notify";
@@ -527,7 +534,7 @@ public UpdateRealmNewUserDefaultSettingsApiRequest withRealmNameInNotifications(
*
* @param policy The {@link RealmNameInNotificationsPolicy} to determine whether to include the organization name in the
* subject of message notification emails
- * @return This {@link UpdateOwnUserSettingsApiRequest} instance
+ * @return This {@link UpdateRealmNewUserDefaultSettingsApiRequest} instance
*/
public UpdateRealmNewUserDefaultSettingsApiRequest withRealmNameInEmailNotifications(
RealmNameInNotificationsPolicy policy) {
@@ -535,6 +542,18 @@ public UpdateRealmNewUserDefaultSettingsApiRequest withRealmNameInEmailNotificat
return this;
}
+ /**
+ * Sets whether the user is configured to receive typing notifications from other users.
+ *
+ * @param receivesTypingNotifications {@code} true to receive typing notifications from other users. {@code false} to not
+ * receive typing notifications from other users.
+ * @return This {@link UpdateRealmNewUserDefaultSettingsApiRequest} instance
+ */
+ public UpdateRealmNewUserDefaultSettingsApiRequest withReceivesTypingNotifications(boolean receivesTypingNotifications) {
+ putParam(RECEIVES_TYPING_NOTIFICATIONS, receivesTypingNotifications);
+ return this;
+ }
+
/**
* Sets whether typing notifications be sent when composing private messages.
*
@@ -633,6 +652,51 @@ public UpdateRealmNewUserDefaultSettingsApiRequest withUserListStyle(UserListSty
return this;
}
+ /**
+ * Sets how animated images should be played in the message feed.
+ *
+ * @param webAnimateImageOption The option determining how animated images should be played
+ * @return This {@link UpdateRealmNewUserDefaultSettingsApiRequest} instance
+ */
+ public UpdateRealmNewUserDefaultSettingsApiRequest withWebAnimateImagePreviews(
+ WebAnimateImageOption webAnimateImageOption) {
+ putParam(WEB_ANIMATE_IMAGE_PREVIEWS, webAnimateImageOption.toString());
+ return this;
+ }
+
+ /**
+ * Sets the default navigation behavior when clicking on a channel link.
+ *
+ * @param webChannelView for the default channel view
+ * @return This {@link UpdateRealmNewUserDefaultSettingsApiRequest} instance
+ */
+ public UpdateRealmNewUserDefaultSettingsApiRequest withWebChannelDefaultView(WebChannelView webChannelView) {
+ putParam(WEB_CHANNEL_DEFAULT_VIEW, webChannelView.getId());
+ return this;
+ }
+
+ /**
+ * Sets the user primary font size in pixels.
+ *
+ * @param fontSize The size of the font used on the Zulip web UI
+ * @return This {@link UpdateRealmNewUserDefaultSettingsApiRequest} instance
+ */
+ public UpdateRealmNewUserDefaultSettingsApiRequest withWebFontPx(int fontSize) {
+ putParam(WEB_FONT_SIZE_PX, fontSize);
+ return this;
+ }
+
+ /**
+ * Sets the user primary line height for the Zulip web UI in percent.
+ *
+ * @param webLineHeightPercent The line height percentage value
+ * @return This {@link UpdateRealmNewUserDefaultSettingsApiRequest} instance
+ */
+ public UpdateRealmNewUserDefaultSettingsApiRequest withWebLineHeightPercent(int webLineHeightPercent) {
+ putParam(WEB_LINE_HEIGHT_PERCENT, webLineHeightPercent);
+ return this;
+ }
+
/**
* Sets whether or not to mark messages as read when the user scrolls through their feed.
*
@@ -644,6 +708,18 @@ public UpdateRealmNewUserDefaultSettingsApiRequest withWebMarkReadOnScrollPolicy
return this;
}
+ /**
+ * Sets whether the user view should automatically go to the conversation where they sent a message.
+ *
+ * @param webNavigateToSentMessage {@code trye} to automatically go to the conversation where they sent a message.
+ * {@code false} to not automatically go to the conversation where they sent a message.
+ * @return This {@link UpdateRealmNewUserDefaultSettingsApiRequest} instance
+ */
+ public UpdateRealmNewUserDefaultSettingsApiRequest withWebNavigateToSentMessage(boolean webNavigateToSentMessage) {
+ putParam(WEB_NAVIGATE_TO_SENT_MESSAGE, webNavigateToSentMessage);
+ return this;
+ }
+
/**
* Sets which streams should be displayed with a numeric unread count in the left sidebar in the Zulip UI.
*
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/response/CreateBigBlueButtonVideoCallApiResponse.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/response/CreateBigBlueButtonVideoCallApiResponse.java
new file mode 100644
index 00000000..fa083e91
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/response/CreateBigBlueButtonVideoCallApiResponse.java
@@ -0,0 +1,19 @@
+package com.github.jamesnetherton.zulip.client.api.server.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+
+/**
+ * Zulip API response class for creating a BigBlueButton video call.
+ *
+ * @see https://zulip.com/api/create-big-blue-button-video-call#response
+ */
+public class CreateBigBlueButtonVideoCallApiResponse extends ZulipApiResponse {
+ @JsonProperty
+ private String url;
+
+ public String getUrl() {
+ return url;
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/response/GetServerSettingsApiResponse.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/response/GetServerSettingsApiResponse.java
index f4532a0f..c4ba5700 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/server/response/GetServerSettingsApiResponse.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/server/response/GetServerSettingsApiResponse.java
@@ -38,9 +38,13 @@ public class GetServerSettingsApiResponse extends ZulipApiResponse {
@JsonProperty
private String realmName;
+ @Deprecated(since = "0.7.0", forRemoval = true)
@JsonProperty
private String realmUri;
+ @JsonProperty
+ private String realmUrl;
+
@JsonProperty
private boolean realmWebPublicAccessEnabled;
@@ -85,10 +89,16 @@ public String getRealmName() {
return realmName;
}
+ @Deprecated(since = "0.7.0", forRemoval = true)
+ @JsonProperty
public String getRealmUri() {
return realmUri;
}
+ public String getRealmUrl() {
+ return realmUrl;
+ }
+
public boolean isRealmWebPublicAccessEnabled() {
return realmWebPublicAccessEnabled;
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/Stream.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/Stream.java
index 54ec8407..0969792f 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/Stream.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/Stream.java
@@ -14,6 +14,9 @@ public class Stream {
@JsonProperty
private Instant dateCreated;
+ @JsonProperty
+ private long creatorId;
+
@JsonProperty
private boolean isDefault;
@@ -57,6 +60,10 @@ public boolean isAnnouncementOnly() {
return isAnnouncementOnly;
}
+ public long getCreatorId() {
+ return creatorId;
+ }
+
public Instant getDateCreated() {
return dateCreated;
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/StreamSubscription.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/StreamSubscription.java
index ef50afba..4c596227 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/StreamSubscription.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/StreamSubscription.java
@@ -15,6 +15,9 @@ public class StreamSubscription {
@JsonProperty
private String color;
+ @JsonProperty
+ private long creatorId;
+
@JsonProperty
private Instant dateCreated;
@@ -80,6 +83,10 @@ public String getColor() {
return color;
}
+ public long getCreatorId() {
+ return creatorId;
+ }
+
public Instant getDateCreated() {
return dateCreated;
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/request/DeleteTopicApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/request/DeleteTopicApiRequest.java
index 6ea11bab..9bb208e6 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/request/DeleteTopicApiRequest.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/request/DeleteTopicApiRequest.java
@@ -4,7 +4,7 @@
import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
-import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.api.stream.response.DeleteTopicApiResponse;
import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
@@ -38,9 +38,12 @@ public DeleteTopicApiRequest(ZulipHttpClient client, long streamId, String topic
*/
@Override
public void execute() throws ZulipClientException {
- ZulipApiResponse response = null;
+ DeleteTopicApiResponse response = null;
while (response == null || response.isPartiallyCompleted()) {
- response = client().post(this.path, getParams(), ZulipApiResponse.class);
+ response = client().post(this.path, getParams(), DeleteTopicApiResponse.class);
+ }
+ while (!response.isComplete()) {
+ response = client().post(this.path, getParams(), DeleteTopicApiResponse.class);
}
}
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/response/DeleteTopicApiResponse.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/response/DeleteTopicApiResponse.java
new file mode 100644
index 00000000..f656ae5b
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/stream/response/DeleteTopicApiResponse.java
@@ -0,0 +1,18 @@
+package com.github.jamesnetherton.zulip.client.api.stream.response;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+
+/**
+ * Zulip API response class for deleting a topic.
+ *
+ * @see https://zulip.com/api/delete-topic#response
+ */
+public class DeleteTopicApiResponse extends ZulipApiResponse {
+ @JsonProperty
+ boolean complete;
+
+ public boolean isComplete() {
+ return complete;
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserPresenceDetail.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserPresenceDetail.java
index 70a8bb68..f0ec974e 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserPresenceDetail.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserPresenceDetail.java
@@ -7,6 +7,8 @@
* Defines details about Zulip user presence.
*/
public class UserPresenceDetail {
+ @JsonProperty
+ private String client;
@JsonProperty
private UserPresenceStatus status;
@@ -14,6 +16,19 @@ public class UserPresenceDetail {
@JsonProperty
private Instant timestamp;
+ @JsonProperty
+ private Instant activeTimestamp;
+
+ @JsonProperty
+ private Instant idleTimestamp;
+
+ @JsonProperty
+ private boolean pushable;
+
+ public String getClient() {
+ return client;
+ }
+
public UserPresenceStatus getStatus() {
return status;
}
@@ -21,4 +36,16 @@ public UserPresenceStatus getStatus() {
public Instant getTimestamp() {
return timestamp;
}
+
+ public Instant getActiveTimestamp() {
+ return activeTimestamp;
+ }
+
+ public Instant getIdleTimestamp() {
+ return idleTimestamp;
+ }
+
+ public boolean isPushable() {
+ return pushable;
+ }
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserRole.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserRole.java
index 69065cd4..60652b9a 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserRole.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserRole.java
@@ -1,5 +1,7 @@
package com.github.jamesnetherton.zulip.client.api.user;
+import com.fasterxml.jackson.annotation.JsonCreator;
+
/**
* Defines Zulip user roles.
*/
@@ -23,7 +25,11 @@ public enum UserRole {
/**
* Guest role.
*/
- GUEST(600);
+ GUEST(600),
+ /**
+ * Unknown role.
+ */
+ UNKNOWN(999);
private final int id;
@@ -34,4 +40,14 @@ public enum UserRole {
public int getId() {
return id;
}
+
+ @JsonCreator
+ public static UserRole fromInt(int userRole) {
+ for (UserRole role : UserRole.values()) {
+ if (role.getId() == userRole) {
+ return role;
+ }
+ }
+ return UNKNOWN;
+ }
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserService.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserService.java
index ca05917c..65cf5ef8 100644
--- a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserService.java
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserService.java
@@ -7,8 +7,10 @@
import com.github.jamesnetherton.zulip.client.api.user.request.CreateUserGroupApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.DeactivateOwnUserApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.DeactivateUserApiRequest;
+import com.github.jamesnetherton.zulip.client.api.user.request.DeleteUserAttachmentApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.DeleteUserGroupApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.GetAllAlertWordsApiRequest;
+import com.github.jamesnetherton.zulip.client.api.user.request.GetAllUserPresenceApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.GetAllUsersApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.GetOwnUserApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.GetSubGroupsOfUserGroupApiRequest;
@@ -18,6 +20,7 @@
import com.github.jamesnetherton.zulip.client.api.user.request.GetUserGroupMembershipStatusApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.GetUserGroupsApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.GetUserPresenceApiRequest;
+import com.github.jamesnetherton.zulip.client.api.user.request.GetUserStatusApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.MuteUserApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.ReactivateUserApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.RemoveAlertWordsApiRequest;
@@ -25,6 +28,7 @@
import com.github.jamesnetherton.zulip.client.api.user.request.SetTypingStatusApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.UnmuteUserApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.UpdateNotificationSettingsApiRequest;
+import com.github.jamesnetherton.zulip.client.api.user.request.UpdateOwnUserPresenceApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.UpdateOwnUserSettingsApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.UpdateOwnUserStatusApiRequest;
import com.github.jamesnetherton.zulip.client.api.user.request.UpdateUserApiRequest;
@@ -325,6 +329,29 @@ public GetUserPresenceApiRequest getUserPresence(String email) {
return new GetUserPresenceApiRequest(this.client, email);
}
+ /**
+ * Gets all user presence details.
+ *
+ * @see https://zulip.com/api/get-presence
+ *
+ * @return The {@link GetAllUserPresenceApiRequest} builder object
+ */
+ public GetAllUserPresenceApiRequest getAllUserPresence() {
+ return new GetAllUserPresenceApiRequest(this.client);
+ }
+
+ /**
+ * Fetches presence details for the current client user.
+ *
+ * @see https://zulip.com/api/update-presence
+ *
+ * @param status The status of the user
+ * @return The {@link UpdateOwnUserPresenceApiRequest} builder object
+ */
+ public UpdateOwnUserPresenceApiRequest updateOwnUserPresence(UserPresenceStatus status) {
+ return new UpdateOwnUserPresenceApiRequest(this.client, status);
+ }
+
/**
* Get user attachments.
*
@@ -336,6 +363,18 @@ public GetUserAttachmentsApiRequest getUserAttachments() {
return new GetUserAttachmentsApiRequest(this.client);
}
+ /**
+ * Deletes an attachment.
+ *
+ * @see https://zulip.com/api/remove-attachment
+ *
+ * @param attachmentId The id of the attachment to delete
+ * @return The {@link DeleteUserAttachmentApiRequest} builder object
+ */
+ public DeleteUserAttachmentApiRequest deleteAttachment(long attachmentId) {
+ return new DeleteUserAttachmentApiRequest(this.client, attachmentId);
+ }
+
/**
* Mute a user.
*
@@ -445,4 +484,16 @@ public GetAllAlertWordsApiRequest getAllAlertWords() {
public RemoveAlertWordsApiRequest removeAlertWords(String... alertWords) {
return new RemoveAlertWordsApiRequest(this.client, alertWords);
}
+
+ /**
+ * Gets a user status.
+ *
+ * @see https://zulip.com/api/get-user-status
+ *
+ * @param userId The ID of the user to fetch the status for
+ * @return The {@link GetUserStatusApiRequest} builder object
+ */
+ public GetUserStatusApiRequest getUserStatus(long userId) {
+ return new GetUserStatusApiRequest(this.client, userId);
+ }
}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserStatus.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserStatus.java
new file mode 100644
index 00000000..8db34d57
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/UserStatus.java
@@ -0,0 +1,41 @@
+package com.github.jamesnetherton.zulip.client.api.user;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+import com.github.jamesnetherton.zulip.client.api.message.ReactionType;
+
+public class UserStatus {
+ @JsonProperty
+ private boolean away;
+
+ @JsonProperty
+ private String statusText;
+
+ @JsonProperty
+ private String emojiName;
+
+ @JsonProperty
+ private String emojiCode;
+
+ @JsonProperty
+ ReactionType reactionType;
+
+ public boolean isAway() {
+ return away;
+ }
+
+ public String getStatusText() {
+ return statusText;
+ }
+
+ public String getEmojiName() {
+ return emojiName;
+ }
+
+ public String getEmojiCode() {
+ return emojiCode;
+ }
+
+ public ReactionType getReactionType() {
+ return reactionType;
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/WebAnimateImageOption.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/WebAnimateImageOption.java
new file mode 100644
index 00000000..a79dd9f3
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/WebAnimateImageOption.java
@@ -0,0 +1,19 @@
+package com.github.jamesnetherton.zulip.client.api.user;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+public enum WebAnimateImageOption {
+ ALWAYS,
+ NEVER,
+ ON_HOVER;
+
+ @Override
+ public String toString() {
+ return this.name().toLowerCase();
+ }
+
+ @JsonCreator
+ public static WebAnimateImageOption fromString(String option) {
+ return WebAnimateImageOption.valueOf(option.toUpperCase());
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/WebChannelView.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/WebChannelView.java
new file mode 100644
index 00000000..50a3888b
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/WebChannelView.java
@@ -0,0 +1,37 @@
+package com.github.jamesnetherton.zulip.client.api.user;
+
+import com.fasterxml.jackson.annotation.JsonCreator;
+
+/**
+ * Setting for controlling the default navigation behavior when clicking on a channel link
+ */
+public enum WebChannelView {
+ /**
+ * Top topic in the channel
+ */
+ CHANNEL_TOP_TOPIC(1),
+ /**
+ * Channel feed
+ */
+ CHANNEL_FEED(2);
+
+ private final int id;
+
+ WebChannelView(int id) {
+ this.id = id;
+ }
+
+ public int getId() {
+ return id;
+ }
+
+ @JsonCreator
+ public static WebChannelView fromInt(int id) {
+ for (WebChannelView webChannelView : WebChannelView.values()) {
+ if (webChannelView.getId() == id) {
+ return webChannelView;
+ }
+ }
+ return null;
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/request/DeleteUserAttachmentApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/request/DeleteUserAttachmentApiRequest.java
new file mode 100644
index 00000000..d02d185d
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/request/DeleteUserAttachmentApiRequest.java
@@ -0,0 +1,38 @@
+package com.github.jamesnetherton.zulip.client.api.user.request;
+
+import com.github.jamesnetherton.zulip.client.api.core.VoidExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+
+/**
+ * Zulip API request builder for deleting an attachment.
+ *
+ * @see https://zulip.com/api/remove-attachment
+ */
+public class DeleteUserAttachmentApiRequest extends ZulipApiRequest implements VoidExecutableApiRequest {
+ private final long attachmentId;
+
+ /**
+ * Constructs a {@link DeleteUserAttachmentApiRequest}.
+ *
+ * @param client The Zulip HTTP client
+ * @param attachmentId The id of the attachment to delete
+ */
+ public DeleteUserAttachmentApiRequest(ZulipHttpClient client, long attachmentId) {
+ super(client);
+ this.attachmentId = attachmentId;
+ }
+
+ /**
+ * Executes the Zulip API request for deleting an attachment.
+ *
+ * @throws ZulipClientException if the request was not successful
+ */
+ @Override
+ public void execute() throws ZulipClientException {
+ String attachmentsWithId = String.format(UserRequestConstants.ATTACHMENTS_WITH_ID, attachmentId);
+ client().delete(attachmentsWithId, getParams(), ZulipApiResponse.class);
+ }
+}
diff --git a/src/main/java/com/github/jamesnetherton/zulip/client/api/user/request/GetAllUserPresenceApiRequest.java b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/request/GetAllUserPresenceApiRequest.java
new file mode 100644
index 00000000..1313623d
--- /dev/null
+++ b/src/main/java/com/github/jamesnetherton/zulip/client/api/user/request/GetAllUserPresenceApiRequest.java
@@ -0,0 +1,39 @@
+package com.github.jamesnetherton.zulip.client.api.user.request;
+
+import static com.github.jamesnetherton.zulip.client.api.user.request.UserRequestConstants.USERS_REALM_PRESENCE;
+
+import com.github.jamesnetherton.zulip.client.api.core.ExecutableApiRequest;
+import com.github.jamesnetherton.zulip.client.api.core.ZulipApiRequest;
+import com.github.jamesnetherton.zulip.client.api.user.UserPresenceDetail;
+import com.github.jamesnetherton.zulip.client.api.user.response.GetAllUserPresenceApiResponse;
+import com.github.jamesnetherton.zulip.client.exception.ZulipClientException;
+import com.github.jamesnetherton.zulip.client.http.ZulipHttpClient;
+import java.util.Map;
+
+/**
+ * Zulip API request builder for getting all user presence.
+ *
+ * @see https://zulip.com/api/get-presence
+ */
+public class GetAllUserPresenceApiRequest extends ZulipApiRequest
+ implements ExecutableApiRequest