Skip to content

Commit

Permalink
[#1247] Optional variables for templates creation (#1248)
Browse files Browse the repository at this point in the history
Fixes #1247

Co-authored-by: Christoph Pröschel <[email protected]>
  • Loading branch information
lucapette and Christoph Pröschel authored Mar 15, 2021
1 parent ea167e9 commit 014a3b1
Show file tree
Hide file tree
Showing 15 changed files with 70 additions and 122 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,8 @@ ResponseEntity<?> createTemplate(@RequestBody @Valid CreateTemplateRequestPayloa
final Template template = Template.newBuilder()
.setId(UUID.randomUUID().toString())
.setName(payload.getName())
.setSourceType(payload.getSourceType())
.setSource(payload.getSource())
.setContent(objectMapper.writeValueAsString(payload.getContent()))
.setVariables(objectMapper.writeValueAsString(payload.getVariables()))
.build();

try {
Expand Down Expand Up @@ -75,7 +74,7 @@ ResponseEntity<?> deleteTemplate(@RequestBody @Valid DeleteTemplateRequestPayloa
@PostMapping("/templates.list")
ResponseEntity<?> listTemplates(@RequestBody @Valid ListTemplatesRequestPayload payload) {
final List<TemplatePayload> response = stores.getTemplates().stream()
.filter(t-> t.getSourceType().equals(payload.getSourceType()))
.filter(t -> t.getSource().equals(payload.getSource()))
.filter(t -> (payload.getName() == null || payload.getName().isEmpty()) || t.getName().contains(payload.getName()))
.map(TemplatePayload::fromTemplate)
.collect(toList());
Expand All @@ -99,12 +98,8 @@ ResponseEntity<?> updateTemplate(@RequestBody @Valid UpdateTemplateRequestPayloa
template.setContent(objectMapper.writeValueAsString(payload.getContent()));
}

if (payload.getVariables() != null) {
template.setVariables(objectMapper.writeValueAsString(payload.getVariables()));
}

if (payload.getSourceType() != null) {
template.setSourceType(payload.getSourceType());
if (payload.getSource() != null) {
template.setSource(payload.getSource());
}

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@ public class CreateTemplateRequestPayload {
@NotNull
private String name;
@NotNull
private String sourceType;
private String source;
@NotNull
private JsonNode content;
@Valid
@NotNull
private JsonNode variables;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@
public class ListTemplatesRequestPayload {
private String name;
@NotNull
private String sourceType;
private String source;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,7 @@
public class UpdateTemplateRequestPayload {
@NotNull
private UUID id;
private String sourceType;
private String source;
private String name;
private JsonNode content;
private JsonNode variables;
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,35 +77,33 @@ void beforeEach() throws Exception {
@Test
void canManageTemplates() throws Exception {
final String name = "awesome-template";
final String sourceType = "facebook";
final String source = "facebook";
final String content = "{\"blueprint\":\"text\",\"payload\":\"[[salutation]]!\"}";
final String payload = "{\"name\":\"" + name + "\",\"source_type\": \"" + sourceType + "\",\"content\":" + content + ",\"variables\": { \"en\": {\"salutation\": \"Hello\"}}}";
final String payload = "{\"name\":\"" + name + "\",\"source\": \"" + source + "\",\"content\":" + content + "}";

final String createTagResponse = webTestHelper.post("/templates.create", payload, "user-id")
final String createTemplateResponse = webTestHelper.post("/templates.create", payload, "user-id")
.andExpect(status().isCreated())
.andReturn()
.getResponse()
.getContentAsString();

final JsonNode jsonNode = objectMapper.readTree(createTagResponse);
final JsonNode jsonNode = objectMapper.readTree(createTemplateResponse);
final String templateId = jsonNode.get("id").textValue();

assertThat(templateId, is(not(nullValue())));

retryOnException(() -> webTestHelper.post("/templates.info", "{\"id\":\"" + templateId + "\"}", "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(is(templateId)))
.andExpect(jsonPath("$.content").value(is(content)))
.andExpect(jsonPath("$.variables.en.salutation").value(is("Hello")))
.andExpect(jsonPath("$.source_type").value(is(sourceType)))
.andExpect(jsonPath("$.content.blueprint").value(is("text")))
.andExpect(jsonPath("$.source").value(is(source)))
.andExpect(jsonPath("$.name").value(is(name))), "could not find template");

webTestHelper.post("/templates.update", "{\"id\":\"" + templateId + "\", \"name\": \"new-template-name\", \"source_type\": \"google\", \"content\": " + content + "}", "user-id")
webTestHelper.post("/templates.update", "{\"id\":\"" + templateId + "\", \"name\": \"new-template-name\", \"source\": \"google\", \"content\": " + content + "}", "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.id").value(is(templateId)))
.andExpect(jsonPath("$.content").value(is(content)))
.andExpect(jsonPath("$.source_type").value(is("google")))
.andExpect(jsonPath("$.variables.en.salutation").value(is("Hello")))
.andExpect(jsonPath("$.content.blueprint").value(is("text")))
.andExpect(jsonPath("$.source").value(is("google")))
.andExpect(jsonPath("$.name").value(is("new-template-name")));

retryOnException(() -> webTestHelper.post("/templates.info", "{\"id\":\"" + templateId + "\"}", "user-id")
Expand All @@ -117,51 +115,52 @@ void canManageTemplates() throws Exception {

@Test
void canListTemplates() throws Exception {
final String googleSource = "google";
final String googleContent = "{\"blueprint\":\"text\",\"payload\":\"[[salutation]]!\"}";

for (int i = 0; i < 10; i++) {
final String name = "awesome-template-" + i;
final String sourceType = "google";
final String content = "{\"blueprint\":\"text\",\"payload\":\"[[salutation]]!\"}";
final String payload = "{\"name\":\"" + name + "\",\"source_type\": \"" + sourceType + "\",\"content\":" + content + ",\"variables\": { \"en\": {\"salutation\": \"Hello\"}}}";
final String payload = "{\"name\":\"" + name + "\",\"source\": \"" + googleSource + "\",\"content\":" + googleContent + "}";

webTestHelper.post("/templates.create", payload, "user-id").andExpect(status().isCreated());
}

final String twilioSource = "twilio.sms";
final String twilioContent = "{\"blueprint\":\"text\",\"payload\":\"[[salutation]]!\"}";
for (int i = 0; i < 5; i++) {
final String name = "awesome-template-" + i;
final String sourceType = "twilio.sms";
final String content = "{\"blueprint\":\"text\",\"payload\":\"[[salutation]]!\"}";
final String payload = "{\"name\":\"" + name + "\",\"source_type\": \"" + sourceType + "\",\"content\":" + content + ",\"variables\": { \"en\": {\"salutation\": \"Hello\"}}}";
final String payload = "{\"name\":\"" + name + "\",\"source\": \"" + twilioSource + "\",\"content\":" + twilioContent + "}";

webTestHelper.post("/templates.create", payload, "user-id").andExpect(status().isCreated());
}

retryOnException(() -> webTestHelper.post("/templates.list",
"{\"source_type\": \"google\"}", "user-id")
"{\"source\": \"google\"}", "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.length()", is(10))), "could not list google templates");

retryOnException(() -> webTestHelper.post("/templates.list",
"{\"source_type\": \"google\", \"name\": \"awesome-template-\"}", "user-id")
"{\"source\": \"google\", \"name\": \"awesome-template-\"}", "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.length()", is(10))), "could not list google templates by name");

retryOnException(() -> webTestHelper.post("/templates.list",
"{\"source_type\": \"google\", \"name\": \"awesome-template-1\"}", "user-id")
"{\"source\": \"google\", \"name\": \"awesome-template-1\"}", "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.length()", is(1))), "could not list google templates by name");

retryOnException(() -> webTestHelper.post("/templates.list",
"{\"source_type\": \"twilio.sms\"}", "user-id")
"{\"source\": \"twilio.sms\"}", "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.length()", is(5))), "could not list twilio templates");

retryOnException(() -> webTestHelper.post("/templates.list",
"{\"source_type\": \"twilio.sms\", \"name\": \"awesome-template-\"}", "user-id")
"{\"source\": \"twilio.sms\", \"name\": \"awesome-template-\"}", "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.length()", is(5))), "could not list twilio templates by name");

retryOnException(() -> webTestHelper.post("/templates.list",
"{\"source_type\": \"twilio.sms\", \"name\": \"awesome-template-1\"}", "user-id")
"{\"source\": \"twilio.sms\", \"name\": \"awesome-template-1\"}", "user-id")
.andExpect(status().isOk())
.andExpect(jsonPath("$.data.length()", is(1))), "could not list twilio templates by name");
}
Expand Down
5 changes: 2 additions & 3 deletions backend/avro/communication/template.avsc
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
"fields": [
{"name": "id", "type": "string"},
{"name": "name", "type": "string"},
{"name": "sourceType", "type": "string"},
{"name": "content", "type": "string"},
{"name": "variables", "type": "string"}
{"name": "source", "type": "string"},
{"name": "content", "type": "string"}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,23 @@
public class TemplatePayload {
private String id;
private String name;
private String sourceType;
private String content;
private JsonNode variables;
private String source;
private JsonNode content;

private static final ObjectMapper mapper = new ObjectMapper();

public static TemplatePayload fromTemplate(final Template template) {
final ObjectMapper mapper = new ObjectMapper();
JsonNode variables;
JsonNode content;
try {
variables = mapper.readTree(template.getVariables());
content = mapper.readTree(template.getContent());
} catch (JsonProcessingException e) {
variables = JsonNodeFactory.instance.objectNode();
content = JsonNodeFactory.instance.objectNode();
}
return TemplatePayload.builder()
.id(template.getId())
.name(template.getName())
.content(template.getContent())
.variables(variables)
.sourceType(template.getSourceType())
.content(content)
.source(template.getSource())
.build();
}
}
40 changes: 8 additions & 32 deletions docs/docs/api/endpoints/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,11 @@ for more information.
```json5
{
"name": "my template name",
"source_type": "facebook",
"source": "chatplugin",
"content": {
"message": {
"text": "[[salutation]]!"
}
},
// source specific message content
"variables": {
"en": {
"salutation": "%s"
}
}
}
```
Expand All @@ -48,12 +42,12 @@ This endpoint allows you to query templates, filtering by name.

**Sample request**

Find templates whose name contains "NASA":
Find templates whose name contains "Ada":

```json5
{
"source_type": "chatplugin",
"name": "NASA" // optional
"source": "chatplugin",
"name": "Ada" // optional
}
```

Expand All @@ -64,18 +58,12 @@ Find templates whose name contains "NASA":
"data": [
{
"id": "TEMPLATE-UUID",
"name": "Template for NASA",
"source_type": "facebook",
"name": "Template for Ada Lovelance day",
"source": "chatplugin",
"content": {
"message": {
"text": "[[salutation]]!"
}
},
// source specific message content
"variables": {
"en": {
"salutation": "%s"
}
}
}
]
Expand All @@ -98,17 +86,11 @@ Find templates whose name contains "NASA":
{
"id": "TEMPLATE-UUID",
"name": "{String}",
"source_type": "facebook",
"source": "chatplugin",
"content": {
"message": {
"text": "[[salutation]]!"
}
},
// source specific message content
"variables": {
"en": {
"salutation": "%s"
}
}
}
```
Expand All @@ -121,17 +103,11 @@ Find templates whose name contains "NASA":
{
"id": "template id",
"name": "my template name",
"source_type": "facebook",
"source_type": "chatplugin",
"content": {
"message": {
"text": "[[salutation]]!"
}
},
// source specific message content
"variables": {
"en": {
"salutation": "%s"
}
}
}
```
Expand Down
6 changes: 3 additions & 3 deletions frontend/ui/src/pages/Inbox/MessageInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ type MessageInputProps = {channelSource: string};

interface SelectedTemplate {
message: RenderedContent;
sourceType: string;
source: string;
}

const MessageInput = (props: MessageInputProps & ConnectedProps<typeof connector>) => {
Expand Down Expand Up @@ -144,7 +144,7 @@ const MessageInput = (props: MessageInputProps & ConnectedProps<typeof connector
setInput('');
setIsShowingTemplateModal(false);
const templateContent = JSON.parse(template.content) as any;
setSelectedTemplate({message: {id: template.id, content: templateContent}, sourceType: template.sourceType});
setSelectedTemplate({message: {id: template.id, content: templateContent}, source: template.source});
}
sendButtonRef.current.focus();
};
Expand Down Expand Up @@ -220,7 +220,7 @@ const MessageInput = (props: MessageInputProps & ConnectedProps<typeof connector
<button className={styles.removeTemplateButton} onClick={() => setSelectedTemplate(null)}>
<Close />
</button>
<SourceMessage message={selectedTemplate.message} source={selectedTemplate.sourceType} />
<SourceMessage message={selectedTemplate.message} source={selectedTemplate.source} />
</div>
)}
</div>
Expand Down
9 changes: 3 additions & 6 deletions frontend/ui/src/pages/Inbox/TemplateSelector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,11 @@ const TemplateSelector = ({listTemplates, onClose, templates, selectTemplate, ch
}, [searchQuery, templates]);

useEffect(() => {
const listAllTemplatesFromSourceTypePayload = {sourceType: channelSource};
const listAllTemplatesFromSourcePayload = {source: channelSource};
let abort = false;

if (templates.length === 0 && loading) {
listTemplates(listAllTemplatesFromSourceTypePayload)
listTemplates(listAllTemplatesFromSourcePayload)
.then(() => {
if (templates.length === 0 && !abort) setLoading(false);
})
Expand Down Expand Up @@ -154,10 +154,7 @@ const TemplateSelector = ({listTemplates, onClose, templates, selectTemplate, ch
selectTemplate(template);
}}>
<div className={styles.tempatePreviewName}>{template.name}</div>
<SourceMessage
message={{id: template.id, content: templateContent}}
source={template.sourceType}
/>
<SourceMessage message={{id: template.id, content: templateContent}} source={template.source} />
</div>
);
})}
Expand Down
2 changes: 1 addition & 1 deletion lib/typescript/httpclient/endpoints/listTemplates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default HttpClient.prototype.listTemplates = async function listTemplates
) {
const response = await this.doFetchFromBackend('templates.list', {
name: requestPayload.name,
source_type: requestPayload.sourceType,
source_type: requestPayload.source,
});

return camelcaseKeys(response.data);
Expand Down
16 changes: 1 addition & 15 deletions lib/typescript/httpclient/model/Message.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,7 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const camelcaseKeys = require('camelcase-keys');

export interface Attachement {
type: string;
payload: {
url?: string;
title?: string;
name?: string;
templateType?: string;
text?: string;
};
sender?: {
id: string;
};
}

export enum SourceType {
export enum Source {
facebook = 'facebook',
google = 'google',
chatplugin = 'chatplugin',
Expand Down
Loading

0 comments on commit 014a3b1

Please sign in to comment.