com.vonage.client.conversations.ConversationsClient Maven / Gradle / Ivy
/*
* Copyright 2024 Vonage
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.vonage.client.conversations;
import com.vonage.client.DynamicEndpoint;
import com.vonage.client.HttpWrapper;
import com.vonage.client.RestEndpoint;
import com.vonage.client.VonageClient;
import com.vonage.client.auth.JWTAuthMethod;
import com.vonage.client.common.HttpMethod;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Function;
/**
* A client for communicating with the Vonage Conversations API. The standard way to obtain an instance
* of this class is to use {@link VonageClient#getConversationsClient()}.
*/
public class ConversationsClient {
final RestEndpoint listConversations;
final RestEndpoint createConversation;
final RestEndpoint getConversation;
final RestEndpoint updateConversation;
final RestEndpoint deleteConversation;
final RestEndpoint listUserConversations;
final RestEndpoint listMembers;
final RestEndpoint getMember;
final RestEndpoint createMember;
final RestEndpoint updateMember;
final RestEndpoint deleteEvent;
final RestEndpoint getEvent;
final RestEndpoint listEvents;
final RestEndpoint createEvent;
/**
* Constructor.
*
* @param wrapper (REQUIRED) shared HTTP wrapper object used for making REST calls.
*/
@SuppressWarnings("unchecked")
public ConversationsClient(HttpWrapper wrapper) {
final String v1c = "/v1/conversations/", v1u = "/v1/users/", mems = "/members/", events = "/events/";
class Endpoint extends DynamicEndpoint {
Endpoint(Function pathGetter, HttpMethod method, R... type) {
super(DynamicEndpoint. builder(type)
.authMethod(JWTAuthMethod.class)
.responseExceptionType(ConversationsResponseException.class)
.requestMethod(method).wrapper(wrapper).pathGetter((de, req) -> {
String base = de.getHttpWrapper().getHttpConfig().getApiBaseUri();
return base + pathGetter.apply(req);
})
);
}
}
listConversations = new Endpoint<>(req -> v1c, HttpMethod.GET);
createConversation = new Endpoint<>(req -> v1c, HttpMethod.POST);
getConversation = new Endpoint<>(id -> v1c+id, HttpMethod.GET);
updateConversation = new Endpoint<>(req -> v1c+req.getId(), HttpMethod.PUT);
deleteConversation = new Endpoint<>(id -> v1c+id, HttpMethod.DELETE);
listUserConversations = new Endpoint<>(req -> v1u+req.userId+"/conversations", HttpMethod.GET);
listMembers = new Endpoint<>(req -> v1c+req.conversationId+mems, HttpMethod.GET);
getMember = new Endpoint<>(req -> v1c+req.conversationId+mems+req.resourceId, HttpMethod.GET);
createMember = new Endpoint<>(req -> v1c+req.getConversationId()+mems, HttpMethod.POST);
updateMember = new Endpoint<>(req -> v1c+req.conversationId+mems+req.resourceId, HttpMethod.PATCH);
deleteEvent = new Endpoint<>(req -> v1c+req.conversationId+events+req.resourceId, HttpMethod.DELETE);
getEvent = new Endpoint<>(req -> v1c+req.conversationId+events+req.resourceId, HttpMethod.GET);
listEvents = new Endpoint<>(req -> v1c+req.conversationId+events, HttpMethod.GET);
createEvent = new Endpoint<>(req -> v1c+req.conversationId+events, HttpMethod.POST);
}
// VALIDATION
private static String validateId(String prefix, String arg) {
final int prefixLength = prefix.length(), expectedLength = prefixLength + 36;
if (arg == null || arg.length() != expectedLength) {
throw new IllegalArgumentException(
"Invalid ID: '"+arg+"' is not "+expectedLength+" characters in length."
);
}
if (!arg.startsWith(prefix)) {
String actualPrefix = arg.substring(0, prefixLength);
throw new IllegalArgumentException(
"Invalid ID: expected prefix '"+prefix+"' but got '"+actualPrefix+"'."
);
}
return prefix + UUID.fromString(arg.substring(prefixLength));
}
private static String validateConversationId(String id) {
return validateId("CON-", id);
}
static String validateMemberId(String id) {
return validateId("MEM-", id);
}
private static String validateUserId(String id) {
return validateId("USR-", id);
}
private static String validateEventId(int id) {
if (id < 0) {
throw new IllegalArgumentException("Event ID cannot be negative.");
}
return String.valueOf(id);
}
private static T validateRequest(T request) {
return Objects.requireNonNull(request, "Request parameter is required.");
}
private static > F defaultFilterParams(B builder) {
return builder.pageSize(100).build();
}
// ENDPOINTS
/**
* Retrieve the first 100 Conversations in the application. Note that the returned conversations are
* incomplete, hence of type {@linkplain BaseConversation}. To get the full data, use the
* {@link #getConversation(String)} method, passing in the ID from {@linkplain BaseConversation#getId()}.
*
* @return A list of the first 100 conversations returned from the API, in default (ascending) order.
*
* @throws ConversationsResponseException If the API call fails due to a bad request (400).
* @see #listConversations(ListConversationsRequest)
*/
public List listConversations() {
return listConversations(defaultFilterParams(ListConversationsRequest.builder())).getConversations();
}
/**
* Retrieve conversations in the application which match the specified filter criteria. Note that the
* returned conversations in {@linkplain ListConversationsResponse#getConversations()} are incomplete,
* hence type of {@linkplain BaseConversation}. To get the full data, use {@link #getConversation(String)}
* method, passing in the ID from {@linkplain BaseConversation#getId()}.
*
* @param filter Filter options to narrow down the search results.
*
* @return The search results along with HAL metadata.
*
* @throws ConversationsResponseException If the API call fails due to a bad request (400).
*/
public ListConversationsResponse listConversations(ListConversationsRequest filter) {
return listConversations.execute(validateRequest(filter));
}
/**
* Creates a new Conversation within the application.
*
* @param request The Conversation parameters. Use {@code Conversation.builder().build()} for default settings.
*
* @return The created Conversation response with additional fields populated.
*
* @throws ConversationsResponseException If the Conversation name already exists (409), or any other API error.
*/
public Conversation createConversation(Conversation request) {
return createConversation.execute(validateRequest(request));
}
/**
* Retrieve a conversation by its ID.
*
* @param conversationId Unique identifier of the conversation to look up.
*
* @return Details of the conversation corresponding to the specified ID.
*
* @throws ConversationsResponseException If the conversation was not found (404), or any other API error.
*/
public Conversation getConversation(String conversationId) {
return getConversation.execute(validateConversationId(conversationId));
}
/**
* Update an existing conversation's settings / parameters.
*
* @param conversationId Unique conversation identifier.
* @param request Conversation object with the updated parameters. Any fields not set will be unchanged.
*
* @return The full updated conversation details.
*
* @throws ConversationsResponseException If the conversation was not found (404)
* or the parameters are invalid (400), e.g. the updated name already exists (409).
*/
public Conversation updateConversation(String conversationId, Conversation request) {
validateRequest(request).id = validateConversationId(conversationId);
return updateConversation.execute(request);
}
/**
* Delete an existing conversation by ID.
*
* @param conversationId Unique conversation identifier.
*
* @throws ConversationsResponseException If the conversation was not found (404), or any other API error.
*/
public void deleteConversation(String conversationId) {
deleteConversation.execute(validateConversationId(conversationId));
}
/**
* List the first 100 conversations for a given user.
*
* @param userId Unique identifier for the user.
*
* @return The list of conversations the specified user is in, with default (ascending) order.
*
* @throws ConversationsResponseException If the user was not found (404), or any other API error.
*
* @see #listUserConversations(String, ListUserConversationsRequest)
* @see com.vonage.client.users
*/
public List listUserConversations(String userId) {
return listUserConversations(userId,
defaultFilterParams(ListUserConversationsRequest.builder())
).getConversations();
}
/**
* List the first 100 conversations for a given user.
*
* @param userId Unique identifier for the user.
* @param filter Filter options to narrow down the search results.
*
* @return The wrapped list of user conversations, along with HAL metadata.
*
* @throws ConversationsResponseException If the user was not found (404),
* the filter options were invalid (400) or any other API error.
*
* @see com.vonage.client.users
*/
public ListUserConversationsResponse listUserConversations(String userId, ListUserConversationsRequest filter) {
validateRequest(filter).userId = validateUserId(userId);
return listUserConversations.execute(filter);
}
/**
* List the first 100 Members for a given Conversation. Note that the returned members are
* incomplete, hence of type {@linkplain BaseMember}. To get the full data, use the
* {@link #getMember(String, String)} method, passing in the ID from {@linkplain BaseMember#getId()}.
*
* @param conversationId Unique conversation identifier.
*
* @return The list of members in default (ascending) order.
*
* @throws ConversationsResponseException If the conversation was not found (404), or any other API error.
*
* @see #listMembers(String, ListMembersRequest)
*/
public List listMembers(String conversationId) {
return listMembers(conversationId, ListMembersRequest.builder().pageSize(100).build()).getMembers();
}
/**
* Retrieve Members associated with a particular Conversation which match the specified filter criteria. Note
* that the returned members are incomplete, hence of type {@linkplain BaseMember}. To get the full data, use
* the {@link #getMember(String, String)} method, passing in the ID from {@linkplain BaseMember#getId()}.
*
* @param conversationId Unique conversation identifier.
* @param filter Filter options to narrow down the search results.
*
* @return The wrapped list of Members, along with HAL metadata.
*
* @throws ConversationsResponseException If the conversation was not found (404),
* the filter options were invalid (400) or any other API error.
*/
public ListMembersResponse listMembers(String conversationId, ListMembersRequest filter) {
validateRequest(filter).conversationId = validateConversationId(conversationId);
return listMembers.execute(filter);
}
/**
* Retrieve a conversation Member by its ID.
*
* @param conversationId Unique conversation identifier.
* @param memberId Unique identifier for the member.
*
* @return Details of the member corresponding to the specified ID.
*
* @throws ConversationsResponseException If the conversation or member was not found (404), or any other API error.
*/
public Member getMember(String conversationId, String memberId) {
return getMember.execute(new ConversationResourceRequestWrapper(
validateConversationId(conversationId), validateMemberId(memberId)
));
}
/**
* Creates a new Member for the specified conversation.
*
* @param conversationId Unique conversation identifier.
* @param request The Members parameters. Use {@link Member#builder()}, remember to set the mandatory parameters.
*
* @return The created Member response with additional fields populated.
*
* @throws ConversationsResponseException If the conversation was not found (404),
* the request parameters were invalid (400) or any other API error.
*/
public Member createMember(String conversationId, Member request) {
validateRequest(request).setConversationId(validateConversationId(conversationId));
return createMember.execute(request);
}
/**
* Update an existing member's state.
*
* @param request Details of the member to update. Use {@link UpdateMemberRequest#builder()},
* remember to set the mandatory parameters, including the conversation and member IDs.
*
* @return The updated Member object response.
*
* @throws ConversationsResponseException If the conversation or member were not found (404),
* the request parameters were invalid (400) or any other API error.
*/
public Member updateMember(UpdateMemberRequest request) {
validateConversationId(validateRequest(request).conversationId);
validateMemberId(request.resourceId);
return updateMember.execute(request);
}
/**
* List the first 100 events for a given Conversation.
*
* @param conversationId Unique conversation identifier.
*
* @return The list of events in default (ascending) order.
*
* @throws ConversationsResponseException If the conversation was not found (404), or any other API error.
*/
public List listEvents(String conversationId) {
return listEvents(conversationId, ListEventsRequest.builder().pageSize(100).build()).getEvents();
}
/**
* Retrieve Events associated with a particular Conversation which match the specified filter criteria.
*
* @param conversationId Unique conversation identifier.
* @param request Filter options to narrow down the search results.
*
* @return The wrapped list of Events, along with HAL metadata.
*
* @throws ConversationsResponseException If the conversation was not found (404), or any other API error.
*/
public ListEventsResponse listEvents(String conversationId, ListEventsRequest request) {
validateRequest(request).conversationId = validateConversationId(conversationId);
return listEvents.execute(request);
}
/**
* Retrieve a conversation Event by its ID.
*
* @param conversationId Unique conversation identifier.
* @param eventId Sequence ID of the event to retrieve as an integer.
*
* @return Details of the event corresponding to the specified ID.
*
* @throws ConversationsResponseException If the conversation or event was not found (404), or any other API error.
*/
public Event getEvent(String conversationId, int eventId) {
return getEvent.execute(new ConversationResourceRequestWrapper(
validateConversationId(conversationId), validateEventId(eventId)
));
}
/**
* Creates a new Event for the specified conversation.
*
* @param conversationId Unique conversation identifier.
* @param request Details of the event to create.
*
* @return The created Event response with additional fields populated.
*
* @throws ConversationsResponseException If the conversation was not found (404), or any other API error.
*/
@SuppressWarnings("unchecked")
public E createEvent(String conversationId, E request) {
validateRequest(request).conversationId = validateConversationId(conversationId);
return (E) createEvent.execute(request);
}
/**
* Deletes an event. Only message and custom events can be deleted.
*
* @param conversationId Unique conversation identifier.
* @param eventId Sequence ID of the event to retrieve as an integer.
*
* @throws ConversationsResponseException If the conversation or event was not found (404),
* the event could not be deleted, or any other API error.
*/
public void deleteEvent(String conversationId, int eventId) {
deleteEvent.execute(new ConversationResourceRequestWrapper(
validateConversationId(conversationId), validateEventId(eventId)
));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy