Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package ai.gradientlabs.client.model;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

/**
* Links a customer to their record in a third-party customer support platform.
* <p>
* {@code type} is only meaningful (and only validated) for platforms that have more than one
* kind of identifier: intercom, zendesk, and salesforce. Omit it entirely for freshchat and
* freshdesk, which don't have subtypes.
*/
@JsonInclude(JsonInclude.Include.NON_NULL)
public class CustomerSupportPlatformIdentifier {

@JsonProperty("support_platform")
private SupportPlatform supportPlatform;

@JsonProperty("type")
private CustomerSupportPlatformIdentifierType type;

@JsonProperty("value")
private String value;

/**
* Default constructor for Jackson.
*/
public CustomerSupportPlatformIdentifier() {
}

/**
* Creates a new identifier for a platform that doesn't have subtypes (e.g. freshchat, freshdesk).
*
* @param supportPlatform the support platform
* @param value the external ID in that platform
*/
public CustomerSupportPlatformIdentifier(SupportPlatform supportPlatform, String value) {
this.supportPlatform = supportPlatform;
this.value = value;
}

/**
* Creates a new identifier with a subtype (required for intercom, zendesk, and salesforce).
*
* @param supportPlatform the support platform
* @param type the kind of identifier
* @param value the external ID in that platform
*/
public CustomerSupportPlatformIdentifier(SupportPlatform supportPlatform, CustomerSupportPlatformIdentifierType type, String value) {
this.supportPlatform = supportPlatform;
this.type = type;
this.value = value;
}

public SupportPlatform getSupportPlatform() {
return supportPlatform;
}

public void setSupportPlatform(SupportPlatform supportPlatform) {
this.supportPlatform = supportPlatform;
}

public CustomerSupportPlatformIdentifierType getType() {
return type;
}

public void setType(CustomerSupportPlatformIdentifierType type) {
this.type = type;
}

public String getValue() {
return value;
}

public void setValue(String value) {
this.value = value;
}

@Override
public String toString() {
return "CustomerSupportPlatformIdentifier{" +
"supportPlatform=" + supportPlatform +
", type=" + type +
", value='" + value + '\'' +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package ai.gradientlabs.client.model;

import com.fasterxml.jackson.annotation.JsonValue;

/**
* The kind of identifier a {@link CustomerSupportPlatformIdentifier} represents, for
* platforms that have more than one kind of customer identifier.
*/
public enum CustomerSupportPlatformIdentifierType {
/**
* An Intercom lead ID.
*/
INTERCOM_LEAD("intercom_lead"),

/**
* An Intercom user ID.
*/
INTERCOM_USER("intercom_user"),

/**
* A Zendesk end-user ID from a messaging conversation.
*/
ZENDESK_CONVERSATION_USER("zendesk_conversation_user"),

/**
* A Zendesk support (ticketing) user ID.
*/
ZENDESK_SUPPORT_USER("zendesk_support_user"),

/**
* A Salesforce Contact ID.
*/
SALESFORCE_CONTACT_ID("salesforce_contact_id"),

/**
* A Salesforce Account ID.
*/
SALESFORCE_ACCOUNT_ID("salesforce_account_id");

private final String value;

CustomerSupportPlatformIdentifierType(String value) {
this.value = value;
}

@JsonValue
public String getValue() {
return value;
}

@Override
public String toString() {
return value;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package ai.gradientlabs.client.model;

import com.fasterxml.jackson.annotation.JsonValue;

/**
* A third-party customer support platform.
*/
public enum SupportPlatform {
/**
* Intercom.
*/
INTERCOM("intercom"),

/**
* Zendesk.
*/
ZENDESK("zendesk"),

/**
* Salesforce.
*/
SALESFORCE("salesforce"),

/**
* Freshchat.
*/
FRESHCHAT("freshchat"),

/**
* Freshdesk.
*/
FRESHDESK("freshdesk");

private final String value;

SupportPlatform(String value) {
this.value = value;
}

@JsonValue
public String getValue() {
return value;
}

@Override
public String toString() {
return value;
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package ai.gradientlabs.client.request;

import ai.gradientlabs.client.model.Channel;
import ai.gradientlabs.client.model.CustomerSupportPlatformIdentifier;
import ai.gradientlabs.client.model.ParticipantType;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;

import java.time.Instant;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
Expand Down Expand Up @@ -45,6 +48,9 @@ public class StartConversationRequest {
@JsonProperty("traffic_group_id")
private final String trafficGroupId;

@JsonProperty("customer_support_platform_identifiers")
private final List<CustomerSupportPlatformIdentifier> customerSupportPlatformIdentifiers;

private StartConversationRequest(Builder builder) {
this.id = builder.id;
this.customerId = builder.customerId;
Expand All @@ -56,6 +62,7 @@ private StartConversationRequest(Builder builder) {
this.resources = builder.resources;
this.conversationToken = builder.conversationToken;
this.trafficGroupId = builder.trafficGroupId;
this.customerSupportPlatformIdentifiers = builder.customerSupportPlatformIdentifiers;
}

public static Builder builder() {
Expand Down Expand Up @@ -107,6 +114,15 @@ public String getTrafficGroupId() {
return trafficGroupId;
}

/**
* Gets the customer's identifiers in third-party customer support platforms.
*
* @return the customer support platform identifiers, or null if none were set
*/
public List<CustomerSupportPlatformIdentifier> getCustomerSupportPlatformIdentifiers() {
return customerSupportPlatformIdentifiers;
}

public static class Builder {
private String id;
private String customerId;
Expand All @@ -118,6 +134,7 @@ public static class Builder {
private Map<String, Object> resources;
private String conversationToken;
private String trafficGroupId;
private List<CustomerSupportPlatformIdentifier> customerSupportPlatformIdentifiers;

private Builder() {
}
Expand Down Expand Up @@ -285,6 +302,35 @@ public Builder trafficGroupId(String trafficGroupId) {
return this;
}

/**
* Sets the customer's identifiers in third-party customer support platforms (optional).
* <p>
* Links the customer being created to their record(s) in platforms such as Intercom
* or Zendesk, alongside {@code customerId}. Each identifier's {@code type} is only
* required (and only validated) for intercom, zendesk, and salesforce.
*
* @param customerSupportPlatformIdentifiers the customer support platform identifiers
* @return this builder
*/
public Builder customerSupportPlatformIdentifiers(List<CustomerSupportPlatformIdentifier> customerSupportPlatformIdentifiers) {
this.customerSupportPlatformIdentifiers = customerSupportPlatformIdentifiers;
return this;
}

/**
* Adds a single customer support platform identifier.
*
* @param customerSupportPlatformIdentifier the identifier to add
* @return this builder
*/
public Builder addCustomerSupportPlatformIdentifier(CustomerSupportPlatformIdentifier customerSupportPlatformIdentifier) {
if (this.customerSupportPlatformIdentifiers == null) {
this.customerSupportPlatformIdentifiers = new ArrayList<>();
}
this.customerSupportPlatformIdentifiers.add(customerSupportPlatformIdentifier);
return this;
}

/**
* Builds the request.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package ai.gradientlabs.client.request;

import ai.gradientlabs.client.model.Channel;
import ai.gradientlabs.client.model.CustomerSupportPlatformIdentifier;
import ai.gradientlabs.client.model.CustomerSupportPlatformIdentifierType;
import ai.gradientlabs.client.model.SupportPlatform;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;

class StartConversationRequestTest {

private final ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());

@Test
void omitsCustomerSupportPlatformIdentifiersWhenNotSet() throws Exception {
StartConversationRequest request = StartConversationRequest.builder()
.id("conv-1")
.customerId("user-1")
.channel(Channel.CHAT)
.build();

JsonNode json = objectMapper.valueToTree(request);

assertFalse(json.has("customer_support_platform_identifiers"));
}

@Test
void serializesCustomerSupportPlatformIdentifiersWithAndWithoutType() throws Exception {
StartConversationRequest request = StartConversationRequest.builder()
.id("conv-1")
.customerId("user-1")
.channel(Channel.CHAT)
.addCustomerSupportPlatformIdentifier(new CustomerSupportPlatformIdentifier(
SupportPlatform.INTERCOM,
CustomerSupportPlatformIdentifierType.INTERCOM_USER,
"6953e162a988d9ef0f73ef9b"))
.addCustomerSupportPlatformIdentifier(new CustomerSupportPlatformIdentifier(
SupportPlatform.FRESHDESK,
"12345"))
.build();

JsonNode json = objectMapper.valueToTree(request);
JsonNode identifiers = json.get("customer_support_platform_identifiers");

assertEquals(2, identifiers.size());

JsonNode intercomIdentifier = identifiers.get(0);
assertEquals("intercom", intercomIdentifier.get("support_platform").asText());
assertEquals("intercom_user", intercomIdentifier.get("type").asText());
assertEquals("6953e162a988d9ef0f73ef9b", intercomIdentifier.get("value").asText());

JsonNode freshdeskIdentifier = identifiers.get(1);
assertEquals("freshdesk", freshdeskIdentifier.get("support_platform").asText());
assertEquals("12345", freshdeskIdentifier.get("value").asText());
assertFalse(freshdeskIdentifier.has("type"));
}

@Test
void roundTripsThroughDeserialization() throws Exception {
StartConversationRequest request = StartConversationRequest.builder()
.id("conv-1")
.customerId("user-1")
.channel(Channel.CHAT)
.addCustomerSupportPlatformIdentifier(new CustomerSupportPlatformIdentifier(
SupportPlatform.ZENDESK,
CustomerSupportPlatformIdentifierType.ZENDESK_SUPPORT_USER,
"42"))
.build();

String json = objectMapper.writeValueAsString(request);
JsonNode tree = objectMapper.readTree(json);
List<CustomerSupportPlatformIdentifier> identifiers = objectMapper.convertValue(
tree.get("customer_support_platform_identifiers"),
objectMapper.getTypeFactory().constructCollectionType(List.class, CustomerSupportPlatformIdentifier.class));

assertEquals(1, identifiers.size());
assertEquals(SupportPlatform.ZENDESK, identifiers.get(0).getSupportPlatform());
assertEquals(CustomerSupportPlatformIdentifierType.ZENDESK_SUPPORT_USER, identifiers.get(0).getType());
assertEquals("42", identifiers.get(0).getValue());
assertEquals(1, request.getCustomerSupportPlatformIdentifiers().size());
}
}
Loading
Loading