From d82125af8294025af94978341021e3f1179c2806 Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Tue, 25 Jul 2023 11:50:26 +0200 Subject: [PATCH 1/2] Added support for MessagingTemplate (WhatsApp) Canned Responses --- responsemanagement_response.go | 96 +++++++++++++++++++-- responsemanagement_test.go | 76 ++++++++++++++-- testdata/response-campaignsms-template.json | 31 +++++++ testdata/response-message-template.json | 38 ++++++++ 4 files changed, 223 insertions(+), 18 deletions(-) create mode 100644 testdata/response-campaignsms-template.json create mode 100644 testdata/response-message-template.json diff --git a/responsemanagement_response.go b/responsemanagement_response.go index fb41fa8..1ead70a 100644 --- a/responsemanagement_response.go +++ b/responsemanagement_response.go @@ -2,6 +2,7 @@ package gcloudcx import ( "context" + "encoding/json" "strings" "text/template" "time" @@ -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 @@ -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 @@ -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 +} diff --git a/responsemanagement_test.go b/responsemanagement_test.go index 0dc5c5a..d48ca9f 100644 --- a/responsemanagement_test.go +++ b/responsemanagement_test.go @@ -2,7 +2,10 @@ package gcloudcx_test import ( "context" + "encoding/json" "fmt" + "os" + "path/filepath" "reflect" "strings" "testing" @@ -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") @@ -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, @@ -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 { diff --git a/testdata/response-campaignsms-template.json b/testdata/response-campaignsms-template.json new file mode 100644 index 0000000..7f9bf2a --- /dev/null +++ b/testdata/response-campaignsms-template.json @@ -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" +} diff --git a/testdata/response-message-template.json b/testdata/response-message-template.json new file mode 100644 index 0000000..82cd30d --- /dev/null +++ b/testdata/response-message-template.json @@ -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" +} From d95525545b165cb93694c17a6c71f3d7ef1210b5 Mon Sep 17 00:00:00 2001 From: Gildas Cherruel Date: Tue, 25 Jul 2023 11:59:47 +0200 Subject: [PATCH 2/2] Bumped to version 0.8.2 --- version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.go b/version.go index 99dd507..9020eda 100644 --- a/version.go +++ b/version.go @@ -4,7 +4,7 @@ package gcloudcx var commit string // VERSION is the version of this application -var VERSION = "0.8.1" + commit +var VERSION = "0.8.2" + commit // APP is the name of the application const APP string = "GCloudCX Client"