Skip to content

Commit

Permalink
Merge pull request #132 from sinch/DEVEXP-240-conversation-templates
Browse files Browse the repository at this point in the history
DEVEXP-240: Conversation Templates V1 & V2
  • Loading branch information
JPPortier authored Sep 2, 2024
2 parents 34d94aa + 5c63fdd commit 69572fa
Show file tree
Hide file tree
Showing 71 changed files with 6,324 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.sinch.sdk.domains.conversation;

import com.sinch.sdk.domains.conversation.api.templates.TemplatesService;

/**
* Conversation Service
*
Expand All @@ -15,7 +17,21 @@ public interface ConversationService {
* @return V1 service instance for project
* @see <a
* href="https://developers.sinch.com/docs/conversation/sdk/java/syntax-reference">Documentation</a>
* @since 1.2
* @since _NEXT_VERSION_
*/
com.sinch.sdk.domains.conversation.api.v1.ConversationService v1();

/**
* Templates service
*
* <p>The Template Management API offers a way to manage templates that can be used together with
* the Conversation API. Note that you may also use the Message Composer tool on the Sinch
* Customer Dashboard to manage templates.
*
* @return Service instance for project
* @see <a
* href="https://developers.sinch.com/docs/conversation/api-reference/template/overview/#section/Managing-templates">Documentation</a>
* @since _NEXT_VERSION_
*/
TemplatesService templates();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,44 @@

import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.core.models.ServerConfiguration;
import com.sinch.sdk.domains.conversation.api.templates.adapters.TemplatesService;
import com.sinch.sdk.models.ConversationContext;
import com.sinch.sdk.models.UnifiedCredentials;

public class ConversationService implements com.sinch.sdk.domains.conversation.ConversationService {

private final com.sinch.sdk.domains.conversation.api.v1.ConversationService v1;
private final UnifiedCredentials credentials;
private final ConversationContext context;
private final ServerConfiguration oAuthServer;
private final HttpClient httpClient;

private com.sinch.sdk.domains.conversation.api.v1.ConversationService conversationV1;
private TemplatesService templates;

public ConversationService(
UnifiedCredentials credentials,
ConversationContext context,
ServerConfiguration oAuthServer,
HttpClient httpClient) {

this.v1 =
new com.sinch.sdk.domains.conversation.api.v1.adapters.ConversationService(
credentials, context, oAuthServer, httpClient);
this.credentials = credentials;
this.context = context;
this.oAuthServer = oAuthServer;
this.httpClient = httpClient;
}

public com.sinch.sdk.domains.conversation.api.v1.ConversationService v1() {
return v1;
if (null == this.conversationV1) {
this.conversationV1 =
new com.sinch.sdk.domains.conversation.api.v1.adapters.ConversationService(
credentials, context, oAuthServer, httpClient);
}
return this.conversationV1;
}

public TemplatesService templates() {
if (null == this.templates) {
this.templates = new TemplatesService(credentials, context, oAuthServer, httpClient);
}
return this.templates;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.sinch.sdk.domains.conversation.api.templates;

import com.sinch.sdk.domains.conversation.api.templates.v1.TemplatesServiceV1;
import com.sinch.sdk.domains.conversation.api.templates.v2.TemplatesServiceV2;

/**
* Service for working with templates
*
* @see <a
* href="https://developers.sinch.com/docs/conversation/api-reference/template/overview/#section/Managing-templates">online
* documentation</a>
* @since _NEXT_VERSION_
*/
public interface TemplatesService {

/**
* Service for working with templates V1
*
* @return Templates V1 service
* @since _NEXT_VERSION_
*/
TemplatesServiceV1 v1();

/**
* Service for working with templates V2
*
* @return Templates V2 service
* @since _NEXT_VERSION_
*/
TemplatesServiceV2 v2();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package com.sinch.sdk.domains.conversation.api.templates.adapters;

import com.sinch.sdk.auth.adapters.OAuthManager;
import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.core.http.HttpMapper;
import com.sinch.sdk.core.models.ServerConfiguration;
import com.sinch.sdk.core.utils.StringUtil;
import com.sinch.sdk.domains.conversation.api.templates.adapters.v1.TemplatesServiceV1;
import com.sinch.sdk.domains.conversation.api.templates.adapters.v2.TemplatesServiceV2;
import com.sinch.sdk.domains.conversation.api.v1.adapters.ConversationService;
import com.sinch.sdk.domains.conversation.templates.models.v2.ChannelTemplateOverrideMapper;
import com.sinch.sdk.models.ConversationContext;
import com.sinch.sdk.models.UnifiedCredentials;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Objects;
import java.util.logging.Logger;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class TemplatesService
implements com.sinch.sdk.domains.conversation.api.templates.TemplatesService {

private static final Logger LOGGER = Logger.getLogger(TemplatesService.class.getName());
private static final String SECURITY_SCHEME_KEYWORD_ = "oAuth2";

private final String uriUUID;
private final ConversationContext context;
private final HttpClient httpClient;
private final Map<String, AuthManager> authManagers;
private TemplatesServiceV1 v1;
private TemplatesServiceV2 v2;

static {
LocalLazyInit.init();
}

public TemplatesService(
UnifiedCredentials credentials,
ConversationContext context,
ServerConfiguration oAuthServer,
HttpClient httpClient) {

Objects.requireNonNull(credentials, "Templates service requires credentials to be defined");
Objects.requireNonNull(context, "Templates service requires context to be defined");
StringUtil.requireNonEmpty(
credentials.getKeyId(), "Templates service requires 'keyId' to be defined");
StringUtil.requireNonEmpty(
credentials.getKeySecret(), "Templates service requires 'keySecret' to be defined");
StringUtil.requireNonEmpty(
credentials.getProjectId(), "Templates service requires 'projectId' to be defined");

StringUtil.requireNonEmpty(
context.getTemplateManagementUrl(),
"Templates service requires 'templateManagementUrl' to be defined");

LOGGER.fine(
String.format(
"Activate templates API with template server: '%s",
context.getTemplateManagementServer().getUrl()));

this.uriUUID = credentials.getProjectId();
this.context = context;
this.httpClient = httpClient;

OAuthManager authManager =
new OAuthManager(credentials, oAuthServer, new HttpMapper(), httpClient);
authManagers =
Stream.of(new AbstractMap.SimpleEntry<>(SECURITY_SCHEME_KEYWORD_, authManager))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}

public TemplatesServiceV1 v1() {
if (null == this.v1) {
this.v1 = new TemplatesServiceV1(uriUUID, context, httpClient, authManagers);
}
return this.v1;
}

public TemplatesServiceV2 v2() {
if (null == this.v2) {
this.v2 = new TemplatesServiceV2(uriUUID, context, httpClient, authManagers);
}
return this.v2;
}

static final class LocalLazyInit {

private LocalLazyInit() {
// Because of templates classes are depending of Conversation classes we need to init for a
// proper serialize/deserialize process
ConversationService.LocalLazyInit.init();
ChannelTemplateOverrideMapper.initMapper();
}

public static LocalLazyInit init() {
return LocalLazyInit.LazyHolder.INSTANCE;
}

private static class LazyHolder {

public static final LocalLazyInit INSTANCE = new LocalLazyInit();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package com.sinch.sdk.domains.conversation.api.templates.adapters.v1;

import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.core.http.HttpMapper;
import com.sinch.sdk.domains.conversation.templates.api.internal.TemplatesV1Api;
import com.sinch.sdk.domains.conversation.templates.models.v1.TemplateV1;
import com.sinch.sdk.models.ConversationContext;
import java.util.Collection;
import java.util.Map;

public class TemplatesServiceV1
implements com.sinch.sdk.domains.conversation.api.templates.v1.TemplatesServiceV1 {

private final String uriUUID;
private final TemplatesV1Api api;

public TemplatesServiceV1(
String uriUUID,
ConversationContext context,
HttpClient httpClient,
Map<String, AuthManager> authManagers) {
this.uriUUID = uriUUID;
this.api =
new TemplatesV1Api(
httpClient, context.getTemplateManagementServer(), authManagers, new HttpMapper());
}

protected TemplatesV1Api getApi() {
return this.api;
}

public Collection<TemplateV1> list() {
return getApi().templatesListTemplates(uriUUID).getTemplates();
}

public TemplateV1 create(TemplateV1 template) {
return getApi().templatesCreateTemplate(uriUUID, template);
}

public TemplateV1 get(String templateId) {
return getApi().templatesGetTemplate(uriUUID, templateId);
}

public void delete(String templateId) {
getApi().templatesDeleteTemplate(uriUUID, templateId);
}

public TemplateV1 update(String templateId, TemplateV1 template) {
return getApi().templatesUpdateTemplate(uriUUID, templateId, template, null);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
package com.sinch.sdk.domains.conversation.api.templates.adapters.v2;

import com.sinch.sdk.core.http.AuthManager;
import com.sinch.sdk.core.http.HttpClient;
import com.sinch.sdk.core.http.HttpMapper;
import com.sinch.sdk.domains.conversation.templates.api.internal.TemplatesV2Api;
import com.sinch.sdk.domains.conversation.templates.models.v2.TemplateTranslation;
import com.sinch.sdk.domains.conversation.templates.models.v2.TemplateV2;
import com.sinch.sdk.domains.conversation.templates.models.v2.internal.V2ListTranslationsResponseInternal;
import com.sinch.sdk.domains.conversation.templates.models.v2.request.TranslationListRequest;
import com.sinch.sdk.models.ConversationContext;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.stream.Collectors;

public class TemplatesServiceV2
implements com.sinch.sdk.domains.conversation.api.templates.v2.TemplatesServiceV2 {

private final String uriUUID;
private final TemplatesV2Api api;

public TemplatesServiceV2(
String uriUUID,
ConversationContext context,
HttpClient httpClient,
Map<String, AuthManager> authManagers) {
this.uriUUID = uriUUID;
this.api =
new TemplatesV2Api(
httpClient, context.getTemplateManagementServer(), authManagers, new HttpMapper());
}

protected TemplatesV2Api getApi() {
return this.api;
}

public Collection<TemplateV2> list() {
return getApi().templatesV2ListTemplates(uriUUID).getTemplates();
}

public Collection<TemplateTranslation> listTranslations(
String templateId, TranslationListRequest request) {

if (null == request) {
request = TranslationListRequest.builder().build();
}
String languageCode = request.getLanguageCode().orElse(null);
String translationVersion = request.getTranslationVersion().orElse(null);

V2ListTranslationsResponseInternal response =
getApi().templatesV2ListTranslations(uriUUID, templateId, languageCode, translationVersion);
if (null == response || null == response.getTranslations()) {
return Collections.emptyList();
}
return response.getTranslations().stream()
.map(TemplateTranslation::from)
.collect(Collectors.toList());
}

public TemplateV2 create(TemplateV2 template) {
return getApi().templatesV2CreateTemplate(uriUUID, template);
}

public TemplateV2 get(String templateId) {
return getApi().templatesV2GetTemplate(uriUUID, templateId);
}

public void delete(String templateId) {
getApi().templatesV2DeleteTemplate(uriUUID, templateId);
}

public TemplateV2 update(String templateId, TemplateV2 template) {
return getApi().templatesV2UpdateTemplate(uriUUID, templateId, template);
}
}
Loading

0 comments on commit 69572fa

Please sign in to comment.