Skip to content

Commit

Permalink
Added support for MessagingTemplate (WhatsApp) Canned Responses
Browse files Browse the repository at this point in the history
  • Loading branch information
Gildas Cherruel committed Jul 25, 2023
1 parent c1849d0 commit d82125a
Show file tree
Hide file tree
Showing 4 changed files with 223 additions and 18 deletions.
96 changes: 87 additions & 9 deletions responsemanagement_response.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package gcloudcx

import (
"context"
"encoding/json"
"strings"
"text/template"
"time"
Expand All @@ -16,15 +17,20 @@ import (
//
// See https://developer.genesys.cloud/api/rest/v2/responsemanagement
type ResponseManagementResponse struct {
ID uuid.UUID `json:"id"`
Name string `json:"name"`
DateCreated time.Time `json:"dateCreated,omitempty"`
CreatedBy *DomainEntityRef `json:"createdBy,omitempty"`
Libraries []DomainEntityRef `json:"libraries,omitempty"`
Texts []ResponseManagementContent `json:"texts,omitempty"`
Substitutions []ResponseManagementSubstitution `json:"substitutions,omitempty"`
Version int `json:"version"`
SelfURI URI `json:"selfUri,omitempty"`
ID uuid.UUID `json:"id"`
Name string `json:"name"`
Type string `json:"ResponseType"`
DateCreated time.Time `json:"dateCreated,omitempty"`
CreatedBy *DomainEntityRef `json:"createdBy,omitempty"`
Libraries []DomainEntityRef `json:"libraries,omitempty"`
Texts []ResponseManagementContent `json:"texts,omitempty"`
Substitutions []ResponseManagementSubstitution `json:"substitutions,omitempty"`
TemplateType string `json:"-"`
TemplateName string `json:"-"`
TemplateNamespace string `json:"-"`
TemplateLanguage string `json:"-"`
Version int `json:"version"`
SelfURI URI `json:"selfUri,omitempty"`
}

// ResponseManagementContent represent a Response Management Content
Expand Down Expand Up @@ -88,6 +94,13 @@ func (response ResponseManagementResponse) GetURI(ids ...uuid.UUID) URI {
return URI("/api/v2/responsemanagement/responses/")
}

// GetType gets the type of this
//
// implements core.TypeCarrier
func (response ResponseManagementResponse) GetType() string {
return response.Type
}

// String gets a string version
//
// implements the fmt.Stringer interface
Expand Down Expand Up @@ -184,3 +197,68 @@ func (response ResponseManagementResponse) ApplySubstitutions(context context.Co
}
return expanded.String(), nil
}

// MarshalJSON marshals into JSON
//
// implements json.Marshaler
func (response ResponseManagementResponse) MarshalJSON() ([]byte, error) {
type surrogate ResponseManagementResponse
type MessagingTemplate struct {
WhatsApp struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Language string `json:"language"`
} `json:"whatsApp"`
}

data, err := json.Marshal(struct {
surrogate
MessagingTemplate *MessagingTemplate `json:"messagingTemplate,omitempty"`
}{
surrogate: surrogate(response),
MessagingTemplate: func() *MessagingTemplate {
switch response.TemplateType {
case "whatsApp":
template := MessagingTemplate{}
template.WhatsApp.Name = response.TemplateName
template.WhatsApp.Namespace = response.TemplateNamespace
template.WhatsApp.Language = response.TemplateLanguage
return &template
default:
return nil
}
}(),
})
return data, errors.JSONMarshalError.Wrap(err)
}

// UnmarshalJSON unmarshals JSON
//
// implements json.Unmarshaler
func (response *ResponseManagementResponse) UnmarshalJSON(payload []byte) (err error) {
type surrogate ResponseManagementResponse
var inner struct {
surrogate
MessagingTemplate *struct {
WhatsApp *struct {
Name string `json:"name"`
Namespace string `json:"namespace"`
Language string `json:"language"`
} `json:"whatsApp"`
}
}

if err := json.Unmarshal(payload, &inner); err != nil {
return errors.JSONUnmarshalError.Wrap(err)
}
*response = ResponseManagementResponse(inner.surrogate)
if inner.MessagingTemplate != nil {
if inner.MessagingTemplate.WhatsApp != nil {
response.TemplateType = "whatsApp"
response.TemplateName = inner.MessagingTemplate.WhatsApp.Name
response.TemplateNamespace = inner.MessagingTemplate.WhatsApp.Namespace
response.TemplateLanguage = inner.MessagingTemplate.WhatsApp.Language
}
}
return
}
76 changes: 67 additions & 9 deletions responsemanagement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ package gcloudcx_test

import (
"context"
"encoding/json"
"fmt"
"os"
"path/filepath"
"reflect"
"strings"
"testing"
Expand Down Expand Up @@ -64,12 +67,6 @@ func (suite *ResponseManagementSuite) SetupSuite() {
secret := core.GetEnvAsString("PURECLOUD_CLIENTSECRET", "")
suite.Require().NotEmpty(secret, "PURECLOUD_CLIENTSECRET is not set")

value = core.GetEnvAsString("PURECLOUD_DEPLOYMENTID", "")
suite.Require().NotEmpty(value, "PURECLOUD_DEPLOYMENTID is not set")

deploymentID, err := uuid.Parse(value)
suite.Require().NoError(err, "PURECLOUD_DEPLOYMENTID is not a valid UUID")

value = core.GetEnvAsString("RESPONSE_MANAGEMENT_LIBRARY_ID", "")
suite.Require().NotEmpty(value, "RESPONSE_MANAGEMENT_LIBRARY_ID is not set in your environment")

Expand All @@ -89,9 +86,8 @@ func (suite *ResponseManagementSuite) SetupSuite() {
suite.Require().NotEmpty(suite.ResponseName, "RESPONSE_MANAGEMENT_RESPONSE_NAME is not set in your environment")

suite.Client = gcloudcx.NewClient(&gcloudcx.ClientOptions{
Region: region,
DeploymentID: deploymentID,
Logger: suite.Logger,
Region: region,
Logger: suite.Logger,
}).SetAuthorizationGrant(&gcloudcx.ClientCredentialsGrant{
ClientID: clientID,
Secret: secret,
Expand Down Expand Up @@ -130,9 +126,71 @@ func (suite *ResponseManagementSuite) AfterTest(suiteName, testName string) {
suite.Logger.Record("duration", duration.String()).Infof("Test End: %s %s", testName, strings.Repeat("-", 80-11-len(testName)))
}

func (suite *ResponseManagementSuite) LoadTestData(filename string) []byte {
data, err := os.ReadFile(filepath.Join(".", "testdata", filename))
suite.Require().NoErrorf(err, "Failed to Load Data. %s", err)
return data
}

func (suite *ResponseManagementSuite) UnmarshalData(filename string, v interface{}) error {
data := suite.LoadTestData(filename)
suite.Logger.Infof("Loaded %s: %s", filename, string(data))
return json.Unmarshal(data, v)
}

// #endregion: Suite Tools }}}
// *****************************************************************************

func (suite *ResponseManagementSuite) TestCanUnmarshalCampaignSMSTemplate() {
var response gcloudcx.ResponseManagementResponse

err := suite.UnmarshalData("response-campaignsms-template.json", &response)
suite.Require().NoError(err, "Failed to unmarshal response")
suite.Assert().Equal("response-01", response.Name)
suite.Assert().Equal(uuid.MustParse("86CABAAE-BD5E-4615-A4F2-712467E808F0"), response.ID)
suite.Assert().Equal(12, response.Version)
suite.Assert().Equal("CampaignSmsTemplate", response.GetType())
suite.Assert().Equal(time.Date(2023, 7, 25, 7, 30, 10, 449000000, time.UTC), response.DateCreated)
suite.Require().NotNil(response.CreatedBy, "Respnose CreatedBy should not be nil")
suite.Assert().Equal(uuid.MustParse("DDA998ED-2258-4317-8070-2745465B8B28"), response.CreatedBy.ID)
suite.Require().Len(response.Libraries, 1)
suite.Assert().Equal(uuid.MustParse("2035D559-793E-4F4B-9A09-118D9C265EFD"), response.Libraries[0].ID)
suite.Assert().Equal("Test Library", response.Libraries[0].Name)
suite.Require().Len(response.Texts, 1)
suite.Assert().Equal("text/plain", response.Texts[0].ContentType)
suite.Assert().Equal("Hello {{Name}}", response.Texts[0].Content)
suite.Require().Len(response.Substitutions, 1)
suite.Assert().Equal("Name", response.Substitutions[0].ID)
suite.Assert().Equal("John Doe", response.Substitutions[0].Default)
}

func (suite *ResponseManagementSuite) TestCanUnmarshalMessageTemplate() {
var response gcloudcx.ResponseManagementResponse

err := suite.UnmarshalData("response-message-template.json", &response)
suite.Require().NoError(err, "Failed to unmarshal response")
suite.Assert().Equal("response-02", response.Name)
suite.Assert().Equal(uuid.MustParse("A7F1F131-7E50-4117-982A-2D5C55C9ED5E"), response.ID)
suite.Assert().Equal(1, response.Version)
suite.Assert().Equal("MessagingTemplate", response.GetType())
suite.Assert().Equal(time.Date(2023, 7, 25, 7, 30, 10, 449000000, time.UTC), response.DateCreated)
suite.Require().NotNil(response.CreatedBy, "Respnose CreatedBy should not be nil")
suite.Assert().Equal(uuid.MustParse("DDA998ED-2258-4317-8070-2745465B8B28"), response.CreatedBy.ID)
suite.Require().Len(response.Libraries, 1)
suite.Assert().Equal(uuid.MustParse("2035D559-793E-4F4B-9A09-118D9C265EFD"), response.Libraries[0].ID)
suite.Assert().Equal("Test Library", response.Libraries[0].Name)
suite.Require().Len(response.Texts, 1)
suite.Assert().Equal("text/plain", response.Texts[0].ContentType)
suite.Assert().Equal("Hello {{Name}}", response.Texts[0].Content)
suite.Require().Len(response.Substitutions, 1)
suite.Assert().Equal("Name", response.Substitutions[0].ID)
suite.Assert().Equal("John Doe", response.Substitutions[0].Default)
suite.Assert().Equal("whatsApp", response.TemplateType)
suite.Assert().Equal("template-01", response.TemplateName)
suite.Assert().Equal("templates", response.TemplateNamespace)
suite.Assert().Equal("en_US", response.TemplateLanguage)
}

func (suite *ResponseManagementSuite) TestCanFetchLibraryByID() {
library, err := gcloudcx.Fetch[gcloudcx.ResponseManagementLibrary](context.Background(), suite.Client, suite.LibraryID)
if err != nil {
Expand Down
31 changes: 31 additions & 0 deletions testdata/response-campaignsms-template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"id": "86CABAAE-BD5E-4615-A4F2-712467E808F0",
"name": "response-01",
"version": 12,
"libraries": [
{
"id": "2035D559-793E-4F4B-9A09-118D9C265EFD",
"name": "Test Library",
"selfUri": "/api/v2/responsemanagement/libraries/2035D559-793E-4F4B-9A09-118D9C265EFD"
}
],
"texts": [
{
"content": "Hello {{Name}}",
"contentType": "text/plain"
}
],
"createdBy": {
"id": "DDA998ED-2258-4317-8070-2745465B8B28",
"selfUri": "/api/v2/users/DDA998ED-2258-4317-8070-2745465B8B28"
},
"dateCreated": "2023-07-25T07:30:10.449Z",
"substitutions": [
{
"id": "Name",
"defaultValue": "John Doe"
}
],
"responseType": "CampaignSmsTemplate",
"selfUri": "/api/v2/responsemanagement/responses/86CABAAE-BD5E-4615-A4F2-712467E808F0"
}
38 changes: 38 additions & 0 deletions testdata/response-message-template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"id": "A7F1F131-7E50-4117-982A-2D5C55C9ED5E",
"name": "response-02",
"version": 1,
"libraries": [
{
"id": "2035D559-793E-4F4B-9A09-118D9C265EFD",
"name": "Test Library",
"selfUri": "/api/v2/responsemanagement/libraries/2035D559-793E-4F4B-9A09-118D9C265EFD"
}
],
"texts": [
{
"content": "Hello {{Name}}",
"contentType": "text/plain"
}
],
"createdBy": {
"id": "DDA998ED-2258-4317-8070-2745465B8B28",
"selfUri": "/api/v2/users/DDA998ED-2258-4317-8070-2745465B8B28"
},
"dateCreated": "2023-07-25T07:30:10.449Z",
"substitutions": [
{
"id": "Name",
"defaultValue": "John Doe"
}
],
"responseType": "MessagingTemplate",
"messagingTemplate": {
"whatsApp": {
"name": "template-01",
"namespace": "templates",
"language": "en_US"
}
},
"selfUri": "/api/v2/responsemanagement/responses/A7F1F131-7E50-4117-982A-2D5C55C9ED5E"
}

0 comments on commit d82125a

Please sign in to comment.