From 5abd33db514389ad4736cf1f0a51c1f2ae0faf06 Mon Sep 17 00:00:00 2001 From: Shruti Suryawanshi Date: Wed, 10 Jul 2024 12:18:39 -0400 Subject: [PATCH 1/6] added outbound_messagingcampaign resource --- ...genesyscloud_outbound_messagingcampaign.go | 50 ++ ...yscloud_outbound_messagingcampaign_test.go | 159 +++++++ ...ud_outbound_messagingcampaign_init_test.go | 72 +++ ...scloud_outbound_messagingcampaign_proxy.go | 165 +++++++ ...genesyscloud_outbound_messagingcampaign.go | 180 +++++++ ...cloud_outbound_messagingcampaign_schema.go | 325 +++++++++++++ ...yscloud_outbound_messagingcampaign_test.go | 440 ++++++++++++++++++ ...scloud_outbound_messagingcampaign_utils.go | 367 +++++++++++++++ .../tfexporter/tf_exporter_resource_test.go | 6 +- main.go | 2 + 10 files changed, 1763 insertions(+), 3 deletions(-) create mode 100644 genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go create mode 100644 genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go create mode 100644 genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go create mode 100644 genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_proxy.go create mode 100644 genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go create mode 100644 genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go create mode 100644 genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go create mode 100644 genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go diff --git a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go new file mode 100644 index 000000000..cf5a80a0b --- /dev/null +++ b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go @@ -0,0 +1,50 @@ +package outbound_messagingcampaign + +import ( + "context" + "fmt" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" + + "terraform-provider-genesyscloud/genesyscloud/provider" + "terraform-provider-genesyscloud/genesyscloud/util" +) + +/* + The data_source_genesyscloud_outbound_messagingcampaign.go contains the data source implementation + for the resource. +*/ + +// dataSourceOutboundMessagingcampaignRead retrieves by name the id in question +func dataSourceOutboundMessagingcampaignRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + sdkConfig := meta.(*provider.ProviderMeta).ClientConfig + outboundApi := platformclientv2.NewOutboundApiWithConfig(sdkConfig) + + name := d.Get("name").(string) + + return util.WithRetries(ctx, 15*time.Second, func() *retry.RetryError { + for pageNum := 1; ; pageNum++ { + const pageSize = 100 + sdkMessagingcampaignEntityListing, resp, getErr := outboundApi.GetOutboundMessagingcampaigns(pageSize, pageNum, "", "", "", "", []string{}, "", "", []string{}) + if getErr != nil { + return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("error requesting Outbound Messaging Campaign %s | error: %s", name, getErr), resp)) + } + + if sdkMessagingcampaignEntityListing.Entities == nil || len(*sdkMessagingcampaignEntityListing.Entities) == 0 { + return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("no Outbound Messaging Campaign found with name %s", name), resp)) + } + + for _, entity := range *sdkMessagingcampaignEntityListing.Entities { + if entity.Name != nil && *entity.Name == name { + d.SetId(*entity.Id) + return nil + } + } + } + }) +} diff --git a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go new file mode 100644 index 000000000..fcf985438 --- /dev/null +++ b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go @@ -0,0 +1,159 @@ +package outbound_messagingcampaign + +import ( + "fmt" + "strconv" + "terraform-provider-genesyscloud/genesyscloud/provider" + "terraform-provider-genesyscloud/genesyscloud/util" + "testing" + + obCallableTimeset "terraform-provider-genesyscloud/genesyscloud/outbound_callabletimeset" + obContactList "terraform-provider-genesyscloud/genesyscloud/outbound_contact_list" + obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" +) + +var TrueValue = "true" + +/* +This test can only pass in a test org because it requires an active provisioned sms phone number +Endpoint `POST /api/v2/routing/sms/phonenumbers` creates an active/valid phone number in test orgs only. +*/ +func TestAccDataSourceOutboundMessagingCampaign(t *testing.T) { + + var ( + resourceId = "campaign" + dataSourceId = "campaign_data" + digitalCampaignName = "Test Digital Campaign " + uuid.NewString() + + clfResourceId = "clf" + clfName = "Test CLF " + uuid.NewString() + contactListResourceId = "contact_list" + contactListName = "Test Contact List " + uuid.NewString() + column1 = "phone" + column2 = "zipcode" + + smsConfigSenderSMSPhoneNumber = "+19198793428" + + callableTimeSetResourceId = "callable_time_set" + callableTimeSetName = "Test CTS " + uuid.NewString() + callableTimeSetResource = obCallableTimeset.GenerateOutboundCallabletimeset( + callableTimeSetResourceId, + callableTimeSetName, + obCallableTimeset.GenerateCallableTimesBlock( + "Europe/Dublin", + obCallableTimeset.GenerateTimeSlotsBlock("07:00:00", "18:00:00", "3"), + obCallableTimeset.GenerateTimeSlotsBlock("09:30:00", "22:30:00", "5"), + ), + ) + + contactListResource = obContactList.GenerateOutboundContactList( + contactListResourceId, + contactListName, + util.NullValue, + util.NullValue, + []string{}, + []string{strconv.Quote(column1), strconv.Quote(column2)}, + util.FalseValue, + util.NullValue, + util.NullValue, + obContactList.GeneratePhoneColumnsBlock( + column1, + "cell", + strconv.Quote(column1), + ), + ) + + contactListFilterResource = obContactListFilter.GenerateOutboundContactListFilter( + clfResourceId, + clfName, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "", + obContactListFilter.GenerateOutboundContactListFilterClause( + "", + obContactListFilter.GenerateOutboundContactListFilterPredicates( + column1, + "alphabetic", + "EQUALS", + "XYZ", + "", + "", + ), + ), + ) + ) + + config, err := provider.AuthorizeSdk() + if err != nil { + t.Errorf("failed to authorize client: %v", err) + } + api := platformclientv2.NewRoutingApiWithConfig(config) + err = createRoutingSmsPhoneNumber(smsConfigSenderSMSPhoneNumber, api) + if err != nil { + t.Errorf("error creating sms phone number %s: %v", smsConfigSenderSMSPhoneNumber, err) + } + defer func() { + _, err := api.DeleteRoutingSmsPhonenumber(smsConfigSenderSMSPhoneNumber) + if err != nil { + t.Logf("error deleting phone number %s: %v", smsConfigSenderSMSPhoneNumber, err) + } + }() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { util.TestAccPreCheck(t) }, + ProviderFactories: provider.GetProviderFactories(providerResources, providerDataSources), + Steps: []resource.TestStep{ + { + Config: contactListResource + + contactListFilterResource + + callableTimeSetResource + + generateOutboundMessagingCampaignResource( + resourceId, + digitalCampaignName, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "", + "10", + util.FalseValue, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + generateOutboundMessagingCampaignSmsConfig( + column1, + column1, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "", + "", + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "DESC", + TrueValue, + ), + ) + generateOutboundMessagingCampaignDataSource( + dataSourceId, + digitalCampaignName, + "genesyscloud_outbound_messagingcampaign."+resourceId, + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrPair("data.genesyscloud_outbound_messagingcampaign."+dataSourceId, "id", + "genesyscloud_outbound_messagingcampaign."+resourceId, "id"), + ), + }, + }, + }) +} + +func generateOutboundMessagingCampaignDataSource(id string, name string, dependsOn string) string { + return fmt.Sprintf(` +data "genesyscloud_outbound_messagingcampaign" "%s" { + name = "%s" + depends_on = [%s] +} +`, id, name, dependsOn) +} diff --git a/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go b/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go new file mode 100644 index 000000000..44a810db0 --- /dev/null +++ b/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go @@ -0,0 +1,72 @@ +package outbound_messagingcampaign + +import ( + "sync" + obCallableTimeset "terraform-provider-genesyscloud/genesyscloud/outbound_callabletimeset" + outboundContactList "terraform-provider-genesyscloud/genesyscloud/outbound_contact_list" + obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" + obDnclist "terraform-provider-genesyscloud/genesyscloud/outbound_dnclist" + outboundRuleset "terraform-provider-genesyscloud/genesyscloud/outbound_ruleset" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +/* + The genesyscloud_outbound_messagingcampaign_init_test.go file is used to initialize the data sources and resources + used in testing the outbound_messagingcampaign resource. +*/ + +// providerDataSources holds a map of all registered datasources +var providerDataSources map[string]*schema.Resource + +// providerResources holds a map of all registered resources +var providerResources map[string]*schema.Resource + +type registerTestInstance struct { + resourceMapMutex sync.RWMutex + datasourceMapMutex sync.RWMutex +} + +// registerTestResources registers all resources used in the tests +func (r *registerTestInstance) registerTestResources() { + r.resourceMapMutex.Lock() + defer r.resourceMapMutex.Unlock() + + providerResources[resourceName] = ResourceOutboundMessagingcampaign() + providerResources["genesyscloud_outbound_contact_list"] = outboundContactList.ResourceOutboundContactList() + providerResources["genesyscloud_outbound_contactlistfilter"] = obContactListFilter.ResourceOutboundContactlistfilter() + providerResources["genesyscloud_outbound_ruleset"] = outboundRuleset.ResourceOutboundRuleset() + providerResources["genesyscloud_outbound_callabletimeset"] = obCallableTimeset.ResourceOutboundCallabletimeset() + providerResources["genesyscloud_outbound_dnclist"] = obDnclist.ResourceOutboundDncList() + +} + +// registerTestDataSources registers all data sources used in the tests. +func (r *registerTestInstance) registerTestDataSources() { + r.datasourceMapMutex.Lock() + defer r.datasourceMapMutex.Unlock() + + providerDataSources[resourceName] = DataSourceOutboundMessagingcampaign() + // TODO: Add references +} + +// initTestResources initializes all test resources and data sources. +func initTestResources() { + providerDataSources = make(map[string]*schema.Resource) + providerResources = make(map[string]*schema.Resource) + + regInstance := ®isterTestInstance{} + + regInstance.registerTestResources() + regInstance.registerTestDataSources() +} + +// TestMain is a "setup" function called by the testing framework when run the test +func TestMain(m *testing.M) { + // Run setup function before starting the test suite for the outbound_messagingcampaign package + initTestResources() + + // Run the test suite for the outbound_messagingcampaign package + m.Run() +} diff --git a/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_proxy.go b/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_proxy.go new file mode 100644 index 000000000..cc4f0a0c0 --- /dev/null +++ b/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_proxy.go @@ -0,0 +1,165 @@ +package outbound_messagingcampaign + +import ( + "context" + "fmt" + "log" + + "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" +) + +/* +The genesyscloud_outbound_messagingcampaign_proxy.go file contains the proxy structures and methods that interact +with the Genesys Cloud SDK. We use composition here for each function on the proxy so individual functions can be stubbed +out during testing. +*/ + +// internalProxy holds a proxy instance that can be used throughout the package +var internalProxy *outboundMessagingcampaignProxy + +// Type definitions for each func on our proxy so we can easily mock them out later +type createOutboundMessagingcampaignFunc func(ctx context.Context, p *outboundMessagingcampaignProxy, messagingCampaign *platformclientv2.Messagingcampaign) (*platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) +type getAllOutboundMessagingcampaignFunc func(ctx context.Context, p *outboundMessagingcampaignProxy) (*[]platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) +type getOutboundMessagingcampaignIdByNameFunc func(ctx context.Context, p *outboundMessagingcampaignProxy, name string) (id string, retryable bool, response *platformclientv2.APIResponse, err error) +type getOutboundMessagingcampaignByIdFunc func(ctx context.Context, p *outboundMessagingcampaignProxy, id string) (messagingCampaign *platformclientv2.Messagingcampaign, response *platformclientv2.APIResponse, err error) +type updateOutboundMessagingcampaignFunc func(ctx context.Context, p *outboundMessagingcampaignProxy, id string, messagingCampaign *platformclientv2.Messagingcampaign) (*platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) +type deleteOutboundMessagingcampaignFunc func(ctx context.Context, p *outboundMessagingcampaignProxy, id string) (messagingCampaign *platformclientv2.Messagingcampaign, response *platformclientv2.APIResponse, err error) + +// outboundMessagingcampaignProxy contains all of the methods that call genesys cloud APIs. +type outboundMessagingcampaignProxy struct { + clientConfig *platformclientv2.Configuration + outboundApi *platformclientv2.OutboundApi + createOutboundMessagingcampaignAttr createOutboundMessagingcampaignFunc + getAllOutboundMessagingcampaignAttr getAllOutboundMessagingcampaignFunc + getOutboundMessagingcampaignIdByNameAttr getOutboundMessagingcampaignIdByNameFunc + getOutboundMessagingcampaignByIdAttr getOutboundMessagingcampaignByIdFunc + updateOutboundMessagingcampaignAttr updateOutboundMessagingcampaignFunc + deleteOutboundMessagingcampaignAttr deleteOutboundMessagingcampaignFunc +} + +// newOutboundMessagingcampaignProxy initializes the outbound messagingcampaign proxy with all of the data needed to communicate with Genesys Cloud +func newOutboundMessagingcampaignProxy(clientConfig *platformclientv2.Configuration) *outboundMessagingcampaignProxy { + api := platformclientv2.NewOutboundApiWithConfig(clientConfig) + return &outboundMessagingcampaignProxy{ + clientConfig: clientConfig, + outboundApi: api, + createOutboundMessagingcampaignAttr: createOutboundMessagingcampaignFn, + getAllOutboundMessagingcampaignAttr: getAllOutboundMessagingcampaignFn, + getOutboundMessagingcampaignIdByNameAttr: getOutboundMessagingcampaignIdByNameFn, + getOutboundMessagingcampaignByIdAttr: getOutboundMessagingcampaignByIdFn, + updateOutboundMessagingcampaignAttr: updateOutboundMessagingcampaignFn, + deleteOutboundMessagingcampaignAttr: deleteOutboundMessagingcampaignFn, + } +} + +// getOutboundMessagingcampaignProxy acts as a singleton to for the internalProxy. It also ensures +// that we can still proxy our tests by directly setting internalProxy package variable +func getOutboundMessagingcampaignProxy(clientConfig *platformclientv2.Configuration) *outboundMessagingcampaignProxy { + if internalProxy == nil { + internalProxy = newOutboundMessagingcampaignProxy(clientConfig) + } + + return internalProxy +} + +// createOutboundMessagingcampaign creates a Genesys Cloud outbound messagingcampaign +func (p *outboundMessagingcampaignProxy) createOutboundMessagingcampaign(ctx context.Context, outboundMessagingcampaign *platformclientv2.Messagingcampaign) (*platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) { + return p.createOutboundMessagingcampaignAttr(ctx, p, outboundMessagingcampaign) +} + +// getOutboundMessagingcampaign retrieves all Genesys Cloud outbound messagingcampaign +func (p *outboundMessagingcampaignProxy) getAllOutboundMessagingcampaign(ctx context.Context) (*[]platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) { + return p.getAllOutboundMessagingcampaignAttr(ctx, p) +} + +// getOutboundMessagingcampaignIdByName returns a single Genesys Cloud outbound messagingcampaign by a name +func (p *outboundMessagingcampaignProxy) getOutboundMessagingcampaignIdByName(ctx context.Context, name string) (id string, retryable bool, response *platformclientv2.APIResponse, err error) { + return p.getOutboundMessagingcampaignIdByNameAttr(ctx, p, name) +} + +// getOutboundMessagingcampaignById returns a single Genesys Cloud outbound messagingcampaign by Id +func (p *outboundMessagingcampaignProxy) getOutboundMessagingcampaignById(ctx context.Context, id string) (outboundMessagingcampaign *platformclientv2.Messagingcampaign, response *platformclientv2.APIResponse, err error) { + return p.getOutboundMessagingcampaignByIdAttr(ctx, p, id) +} + +// updateOutboundMessagingcampaign updates a Genesys Cloud outbound messagingcampaign +func (p *outboundMessagingcampaignProxy) updateOutboundMessagingcampaign(ctx context.Context, id string, outboundMessagingcampaign *platformclientv2.Messagingcampaign) (*platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) { + return p.updateOutboundMessagingcampaignAttr(ctx, p, id, outboundMessagingcampaign) +} + +// deleteOutboundMessagingcampaign deletes a Genesys Cloud outbound messagingcampaign by Id +func (p *outboundMessagingcampaignProxy) deleteOutboundMessagingcampaign(ctx context.Context, id string) (messagingCampaign *platformclientv2.Messagingcampaign, response *platformclientv2.APIResponse, err error) { + return p.deleteOutboundMessagingcampaignAttr(ctx, p, id) +} + +// createOutboundMessagingcampaignFn is an implementation function for creating a Genesys Cloud outbound messagingcampaign +func createOutboundMessagingcampaignFn(ctx context.Context, p *outboundMessagingcampaignProxy, outboundMessagingcampaign *platformclientv2.Messagingcampaign) (*platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) { + return p.outboundApi.PostOutboundMessagingcampaigns(*outboundMessagingcampaign) +} + +// getAllOutboundMessagingcampaignFn is the implementation for retrieving all outbound messagingcampaign in Genesys Cloud +func getAllOutboundMessagingcampaignFn(ctx context.Context, p *outboundMessagingcampaignProxy) (*[]platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) { + var allMessagingCampaigns []platformclientv2.Messagingcampaign + const pageSize = 100 + + messagingCampaigns, resp, err := p.outboundApi.GetOutboundMessagingcampaigns(pageSize, 1, "", "", "", "", []string{}, "", "", []string{}) + if err != nil { + return nil, resp, fmt.Errorf("Failed to get messaging campaign: %v", err) + } + if messagingCampaigns.Entities == nil || len(*messagingCampaigns.Entities) == 0 { + return &allMessagingCampaigns, resp, nil + } + + allMessagingCampaigns = append(allMessagingCampaigns, *messagingCampaigns.Entities...) + + for pageNum := 2; pageNum <= *messagingCampaigns.PageCount; pageNum++ { + messagingCampaigns, resp, err := p.outboundApi.GetOutboundMessagingcampaigns(pageSize, pageNum, "", "", "", "", []string{}, "", "", []string{}) + if err != nil { + return nil, resp, fmt.Errorf("Failed to get messaging campaign: %v", err) + } + + if messagingCampaigns.Entities == nil || len(*messagingCampaigns.Entities) == 0 { + break + } + + allMessagingCampaigns = append(allMessagingCampaigns, *messagingCampaigns.Entities...) + } + + return &allMessagingCampaigns, resp, nil +} + +// getOutboundMessagingcampaignIdByNameFn is an implementation of the function to get a Genesys Cloud outbound messagingcampaign by name +func getOutboundMessagingcampaignIdByNameFn(ctx context.Context, p *outboundMessagingcampaignProxy, name string) (string, bool, *platformclientv2.APIResponse, error) { + messagingCampaigns, resp, err := getAllOutboundMessagingcampaignFn(ctx, p) + if err != nil { + return "", false, resp, err + } + + if messagingCampaigns == nil || len(*messagingCampaigns) == 0 { + return "", true, resp, fmt.Errorf("No outbound messagingcampaign found with name %s", name) + } + + for _, messagingCampaign := range *messagingCampaigns { + if *messagingCampaign.Name == name { + log.Printf("Retrieved the outbound messagingcampaign id %s by name %s", *messagingCampaign.Id, name) + return *messagingCampaign.Id, false, resp, nil + } + } + + return "", true, resp, fmt.Errorf("Unable to find outbound messagingcampaign with name %s", name) +} + +// getOutboundMessagingcampaignByIdFn is an implementation of the function to get a Genesys Cloud outbound messagingcampaign by Id +func getOutboundMessagingcampaignByIdFn(ctx context.Context, p *outboundMessagingcampaignProxy, id string) (outboundMessagingcampaign *platformclientv2.Messagingcampaign, response *platformclientv2.APIResponse, err error) { + return p.outboundApi.GetOutboundMessagingcampaign(id) +} + +// updateOutboundMessagingcampaignFn is an implementation of the function to update a Genesys Cloud outbound messagingcampaign +func updateOutboundMessagingcampaignFn(ctx context.Context, p *outboundMessagingcampaignProxy, id string, outboundMessagingcampaign *platformclientv2.Messagingcampaign) (*platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) { + return p.outboundApi.PutOutboundMessagingcampaign(id, *outboundMessagingcampaign) +} + +// deleteOutboundMessagingcampaignFn is an implementation function for deleting a Genesys Cloud outbound messagingcampaign +func deleteOutboundMessagingcampaignFn(ctx context.Context, p *outboundMessagingcampaignProxy, id string) (*platformclientv2.Messagingcampaign, *platformclientv2.APIResponse, error) { + return p.outboundApi.DeleteOutboundMessagingcampaign(id) +} diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go new file mode 100644 index 000000000..3a1869e91 --- /dev/null +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go @@ -0,0 +1,180 @@ +package outbound_messagingcampaign + +import ( + "context" + "errors" + "fmt" + "log" + "terraform-provider-genesyscloud/genesyscloud/provider" + resourceExporter "terraform-provider-genesyscloud/genesyscloud/resource_exporter" + "terraform-provider-genesyscloud/genesyscloud/util" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" + + "terraform-provider-genesyscloud/genesyscloud/consistency_checker" + + "terraform-provider-genesyscloud/genesyscloud/util/constants" + "terraform-provider-genesyscloud/genesyscloud/util/resourcedata" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" +) + +/* +The resource_genesyscloud_outbound_messagingcampaign.go contains all of the methods that perform the core logic for a resource. +*/ + +// getAllAuthOutboundMessagingcampaign retrieves all of the outbound messagingcampaign via Terraform in the Genesys Cloud and is used for the exporter +func getAllAuthOutboundMessagingcampaigns(ctx context.Context, clientConfig *platformclientv2.Configuration) (resourceExporter.ResourceIDMetaMap, diag.Diagnostics) { + proxy := getOutboundMessagingcampaignProxy(clientConfig) + resources := make( + resourceExporter.ResourceIDMetaMap) + + messagingCampaigns, resp, err := proxy.getAllOutboundMessagingcampaign(ctx) + if err != nil { + return nil, util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Error requesting page of Outbound Messagingcampaign error: %s", err), resp) + } + + for _, messagingCampaign := range *messagingCampaigns { + resources[*messagingCampaign.Id] = &resourceExporter.ResourceMeta{Name: *messagingCampaign.Name} + } + + return resources, nil +} + +// createOutboundMessagingcampaign is used by the outbound_messagingcampaign resource to create Genesys cloud outbound messagingcampaign +func createOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + sdkConfig := meta.(*provider.ProviderMeta).ClientConfig + proxy := getOutboundMessagingcampaignProxy(sdkConfig) + + outboundMessagingcampaign := getOutboundMessagingcampaignFromResourceData(d) + + msg, valid := validateSmsconfig(d.Get("sms_config").(*schema.Set)) + if !valid { + return util.BuildDiagnosticError(resourceName, "Configuration error", errors.New(msg)) + } + + log.Printf("Creating outbound messagingcampaign %s", *outboundMessagingcampaign.Name) + messagingCampaign, resp, err := proxy.createOutboundMessagingcampaign(ctx, &outboundMessagingcampaign) + if err != nil { + return util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Failed to create outbound messagingcampaign %s error: %s", *outboundMessagingcampaign.Name, err), resp) + } + + d.SetId(*messagingCampaign.Id) + log.Printf("Created outbound messagingcampaign %s", *messagingCampaign.Id) + return readOutboundMessagingcampaign(ctx, d, meta) +} + +// readOutboundMessagingcampaign is used by the outbound_messagingcampaign resource to read an outbound messagingcampaign from genesys cloud +func readOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + sdkConfig := meta.(*provider.ProviderMeta).ClientConfig + proxy := getOutboundMessagingcampaignProxy(sdkConfig) + cc := consistency_checker.NewConsistencyCheck(ctx, d, meta, ResourceOutboundMessagingcampaign(), constants.DefaultConsistencyChecks, resourceName) + + log.Printf("Reading outbound messagingcampaign %s", d.Id()) + + return util.WithRetriesForRead(ctx, d, func() *retry.RetryError { + messagingCampaign, resp, getErr := proxy.getOutboundMessagingcampaignById(ctx, d.Id()) + if getErr != nil { + if util.IsStatus404(resp) { + return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Failed to read Outbound Messagingcampaign %s | error: %s", d.Id(), getErr), resp)) + } + return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Failed to read Outbound Messagingcampaign %s | error: %s", d.Id(), getErr), resp)) + } + + resourcedata.SetNillableValue(d, "name", messagingCampaign.Name) + resourcedata.SetNillableReference(d, "division_id", messagingCampaign.Division) + resourcedata.SetNillableValue(d, "campaign_status", messagingCampaign.CampaignStatus) + resourcedata.SetNillableReference(d, "callable_time_set_id", messagingCampaign.CallableTimeSet) + resourcedata.SetNillableReference(d, "contact_list_id", messagingCampaign.ContactList) + if messagingCampaign.DncLists != nil { + _ = d.Set("dnc_list_ids", util.SdkDomainEntityRefArrToList(*messagingCampaign.DncLists)) + } + resourcedata.SetNillableValue(d, "always_running", messagingCampaign.AlwaysRunning) + resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "contact_sorts", messagingCampaign.ContactSorts, flattenContactSorts) + resourcedata.SetNillableValue(d, "messages_per_minute", messagingCampaign.MessagesPerMinute) + if messagingCampaign.RuleSets != nil { + _ = d.Set("rule_sets_ids", util.SdkDomainEntityRefArrToList(*messagingCampaign.RuleSets)) + } + if messagingCampaign.ContactListFilters != nil { + _ = d.Set("contact_list_filter_ids", util.SdkDomainEntityRefArrToList(*messagingCampaign.ContactListFilters)) + } + resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "errors", messagingCampaign.Errors, flattenRestErrorDetails) + resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "dynamic_contact_queueing_settings", messagingCampaign.DynamicContactQueueingSettings, flattenDynamicContactQueueingSettingss) + resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "email_config", messagingCampaign.EmailConfig, flattenEmailConfigs) + //resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "sms_config", messagingCampaign.SmsConfig, flattenSmsConfigs) + d.Set("sms_config", flattenSmsConfigs(messagingCampaign.SmsConfig)) + + log.Printf("Read outbound messagingcampaign %s %s", d.Id(), *messagingCampaign.Name) + return cc.CheckState(d) + }) +} + +// updateOutboundMessagingcampaign is used by the outbound_messagingcampaign resource to update an outbound messagingcampaign in Genesys Cloud +func updateOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + sdkConfig := meta.(*provider.ProviderMeta).ClientConfig + proxy := getOutboundMessagingcampaignProxy(sdkConfig) + + outboundMessagingcampaign := getOutboundMessagingcampaignFromResourceData(d) + + msg, valid := validateSmsconfig(d.Get("sms_config").(*schema.Set)) + + if !valid { + return util.BuildDiagnosticError(resourceName, "Configuration error", errors.New(msg)) + } + + log.Printf("Updating outbound messagingcampaign %s", *outboundMessagingcampaign.Name) + diagErr := util.RetryWhen(util.IsVersionMismatch, func() (*platformclientv2.APIResponse, diag.Diagnostics) { + // Get current Outbound Messagingcampaign version + outboundMessagingcampaignById, resp, getErr := proxy.getOutboundMessagingcampaignById(ctx, d.Id()) + if getErr != nil { + return resp, util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Failed to read Outbound Messagingcampaign %s error: %s", *outboundMessagingcampaign.Name, getErr), resp) + } + outboundMessagingcampaign.Version = outboundMessagingcampaignById.Version + messagingCampaign, resp, updateErr := proxy.updateOutboundMessagingcampaign(ctx, d.Id(), &outboundMessagingcampaign) + if updateErr != nil { + return resp, util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Failed to update Outbound Messagingcampaign %s error: %s", *messagingCampaign.Name, updateErr), resp) + } + return nil, nil + }) + if diagErr != nil { + return diagErr + } + + log.Printf("Updated outbound messagingcampaign %s", *outboundMessagingcampaign.Id) + return readOutboundMessagingcampaign(ctx, d, meta) +} + +// deleteOutboundMessagingcampaign is used by the outbound_messagingcampaign resource to delete an outbound messagingcampaign from Genesys cloud +func deleteOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + sdkConfig := meta.(*provider.ProviderMeta).ClientConfig + proxy := getOutboundMessagingcampaignProxy(sdkConfig) + + diagErr := util.RetryWhen(util.IsStatus400, func() (*platformclientv2.APIResponse, diag.Diagnostics) { + log.Printf("Deleting Outbound Messagingcampaign") + _, resp, err := proxy.deleteOutboundMessagingcampaign(ctx, d.Id()) + if err != nil { + return resp, util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Failed to delete outbound Messagingcampaign %s error: %s", d.Id(), err), resp) + } + return resp, nil + }) + if diagErr != nil { + return diagErr + } + + return util.WithRetries(ctx, 180*time.Second, func() *retry.RetryError { + _, resp, err := proxy.getOutboundMessagingcampaignById(ctx, d.Id()) + + if err != nil { + if util.IsStatus404(resp) { + log.Printf("Deleted outbound messagingcampaign %s", d.Id()) + return nil + } + return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Error deleting Outbound Messagingcampaign %s | error: %s", d.Id(), err), resp)) + } + + return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Outbound Messagingcampaign %s still exists", d.Id()), resp)) + }) +} diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go new file mode 100644 index 000000000..73b62ecc0 --- /dev/null +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go @@ -0,0 +1,325 @@ +package outbound_messagingcampaign + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + + "terraform-provider-genesyscloud/genesyscloud/provider" + resourceExporter "terraform-provider-genesyscloud/genesyscloud/resource_exporter" + registrar "terraform-provider-genesyscloud/genesyscloud/resource_register" +) + +/* +resource_genesycloud_outbound_messagingcampaign_schema.go holds four functions within it: + +1. The registration code that registers the Datasource, Resource and Exporter for the package. +2. The resource schema definitions for the outbound_messagingcampaign resource. +3. The datasource schema definitions for the outbound_messagingcampaign datasource. +4. The resource exporter configuration for the outbound_messagingcampaign exporter. +*/ +const resourceName = "genesyscloud_outbound_messagingcampaign" + +// SetRegistrar registers all of the resources, datasources and exporters in the package +func SetRegistrar(regInstance registrar.Registrar) { + regInstance.RegisterResource(resourceName, ResourceOutboundMessagingcampaign()) + regInstance.RegisterDataSource(resourceName, DataSourceOutboundMessagingcampaign()) + regInstance.RegisterExporter(resourceName, OutboundMessagingcampaignExporter()) +} + +var ( + fromEmailAddressResource = &schema.Resource{ + Schema: map[string]*schema.Schema{ + `domain_id`: { + Description: `The OutboundDomain used for the email address.`, + Required: true, + Type: schema.TypeString, + }, + `friendly_name`: { + Description: `The friendly name of the email address.`, + Optional: true, + Type: schema.TypeString, + }, + `local_part`: { + Description: `The local part of the email address.`, + Optional: true, + Type: schema.TypeString, + }, + }, + } + + replyToEmailAddressResource = &schema.Resource{ + Schema: map[string]*schema.Schema{ + `domain_id`: { + Description: `The InboundDomain used for the email address.`, + Required: true, + Type: schema.TypeString, + }, + `route_id`: { + Description: `The InboundRoute used for the email address.`, + Required: true, + Type: schema.TypeString, + }, + }, + } + + emailConfigResource = &schema.Resource{ + Schema: map[string]*schema.Schema{ + `email_columns`: { + Description: `The contact list columns specifying the email address(es) of the contact.`, + Required: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + `content_template_id`: { + Description: `The content template used to formulate the email to send to the contact.`, + Optional: true, + Type: schema.TypeString, + }, + `from_address`: { + Description: `The email address that will be used as the sender of the email.`, + Required: true, + Type: schema.TypeList, + MaxItems: 1, + Elem: fromEmailAddressResource, + }, + `reply_to_address`: { + Description: `The email address from which any reply will be sent.`, + Optional: true, + Type: schema.TypeList, + MaxItems: 1, + Elem: replyToEmailAddressResource, + }, + }, + } + + smsConfigResource = &schema.Resource{ + Schema: map[string]*schema.Schema{ + `message_column`: { + Description: `The Contact List column specifying the message to send to the contact.`, + Required: true, + Type: schema.TypeString, + }, + `phone_column`: { + Description: `The Contact List column specifying the phone number to send a message to.`, + Required: true, + Type: schema.TypeString, + }, + `sender_sms_phone_number`: { + Description: `A phone number provisioned for SMS communications in E.164 format. E.g. +13175555555 or +34234234234`, + Required: true, + Type: schema.TypeString, + }, + `content_template_id`: { + Description: `The content template used to formulate the message to send to the contact.`, + Optional: true, + Type: schema.TypeString, + }, + }, + } +) + +// ResourceOutboundMessagingcampaign registers the genesyscloud_outbound_messagingcampaign resource with Terraform +func ResourceOutboundMessagingcampaign() *schema.Resource { + contactSortResource := &schema.Resource{ + Schema: map[string]*schema.Schema{ + `field_name`: { + Description: `The field name by which to sort contacts.`, + Required: true, + Type: schema.TypeString, + }, + `direction`: { + Description: `The direction in which to sort contacts.`, + Optional: true, + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{`ASC`, `DESC`}, false), + Default: `ASC`, + }, + `numeric`: { + Description: `Whether or not the column contains numeric data.`, + Optional: true, + Type: schema.TypeBool, + }, + }, + } + + restErrorDetailResource := &schema.Resource{ + Schema: map[string]*schema.Schema{ + `error`: { + Description: `name of the error`, + Required: true, + Type: schema.TypeString, + }, + `details`: { + Description: `additional information regarding the error`, + Optional: true, + Type: schema.TypeString, + }, + }, + } + + dynamicContactQueueingSettingsResource := &schema.Resource{ + Schema: map[string]*schema.Schema{ + `sort`: { + Description: `Whether to sort contacts dynamically`, + Optional: true, + Type: schema.TypeBool, + }, + }, + } + + return &schema.Resource{ + Description: `Genesys Cloud outbound messagingcampaign`, + + CreateContext: provider.CreateWithPooledClient(createOutboundMessagingcampaign), + ReadContext: provider.ReadWithPooledClient(readOutboundMessagingcampaign), + UpdateContext: provider.UpdateWithPooledClient(updateOutboundMessagingcampaign), + DeleteContext: provider.DeleteWithPooledClient(deleteOutboundMessagingcampaign), + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + SchemaVersion: 1, + Schema: map[string]*schema.Schema{ + `name`: { + Description: `The campaign name.`, + Required: true, + Type: schema.TypeString, + }, + `division_id`: { + Description: `The division this entity belongs to.`, + Optional: true, + Computed: true, + Type: schema.TypeString, + }, + `campaign_status`: { + Description: `The current status of the messaging campaign. A messaging campaign may be turned 'on' or 'off'.`, + Optional: true, + Computed: true, + Type: schema.TypeString, + ValidateFunc: validation.StringInSlice([]string{`on`, `off`}, false), + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == `complete` && new == `on` { + return true + } + if old == `invalid` && new == `on` { + return true + } + if old == `stopping` && new == `off` { + return true + } + return false + }, + }, + `callable_time_set_id`: { + Description: `The callable time set for this messaging campaign.`, + Optional: true, + Type: schema.TypeString, + }, + `contact_list_id`: { + Description: `The contact list that this messaging campaign will send messages for.`, + Required: true, + Type: schema.TypeString, + }, + `dnc_list_ids`: { + Description: `The dnc lists to check before sending a message for this messaging campaign.`, + Optional: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + `always_running`: { + Description: `Whether this messaging campaign is always running`, + Optional: true, + Default: false, + Type: schema.TypeBool, + }, + `contact_sorts`: { + Description: `The order in which to sort contacts for dialing, based on up to four columns.`, + Optional: true, + Type: schema.TypeList, + Elem: contactSortResource, + }, + `messages_per_minute`: { + Description: `How many messages this messaging campaign will send per minute.`, + Required: true, + Type: schema.TypeInt, + }, + `rule_sets_ids`: { + Description: `Rule Sets to be applied while this campaign is sending messages`, + Optional: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + `contact_list_filter_ids`: { + Description: `The contact list filter to check before sending a message for this messaging campaign.`, + Optional: true, + Type: schema.TypeList, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + `errors`: { + Description: `A list of current error conditions associated with this messaging campaign.`, + Optional: true, + Type: schema.TypeList, + Elem: restErrorDetailResource, + }, + `dynamic_contact_queueing_settings`: { + Description: `Indicates (when true) that the campaign supports dynamic queueing of the contact list at the time of a request for contacts.`, + Optional: true, + Type: schema.TypeList, + MaxItems: 1, + Elem: dynamicContactQueueingSettingsResource, + }, + `email_config`: { + Description: `Configuration for this messaging campaign to send Email messages.`, + Optional: true, + Type: schema.TypeSet, + MaxItems: 1, + Elem: emailConfigResource, + }, + `sms_config`: { + Description: `Configuration for this messaging campaign to send SMS messages.`, + Optional: true, + Type: schema.TypeSet, + MaxItems: 1, + Elem: smsConfigResource, + }, + }, + } +} + +// OutboundMessagingcampaignExporter returns the resourceExporter object used to hold the genesyscloud_outbound_messagingcampaign exporter's config +func OutboundMessagingcampaignExporter() *resourceExporter.ResourceExporter { + return &resourceExporter.ResourceExporter{ + GetResourcesFunc: provider.GetAllWithPooledClient(getAllAuthOutboundMessagingcampaigns), + RefAttrs: map[string]*resourceExporter.RefAttrSettings{ + // TODO: Add any reference attributes here + `division_id`: {RefType: "genesyscloud_auth_division"}, + `contact_list_id`: {RefType: "genesyscloud_outbound_contact_list"}, + `contact_list_filter_ids`: {RefType: "genesyscloud_outbound_contactlistfilter"}, + `rule_sets`: {RefType: "genesyscloud_outbound_ruleset"}, + `dnc_list_ids`: {RefType: "genesyscloud_outbound_dnclist"}, + `callable_time_set_id`: {RefType: "genesyscloud_outbound_callabletimeset"}, + // /api/v2/responsemanagement/responses/{responseId} + `sms_config.content_template_id`: {}, + `email_config.content_template_id`: {}, + }, + } +} + +// DataSourceOutboundMessagingcampaign registers the genesyscloud_outbound_messagingcampaign data source +func DataSourceOutboundMessagingcampaign() *schema.Resource { + return &schema.Resource{ + Description: `Data source for Genesys Cloud Outbound Messaging Campaign. Select a Outbound Messaging Campaign by name.`, + + ReadContext: provider.ReadWithPooledClient(dataSourceOutboundMessagingcampaignRead), + Importer: &schema.ResourceImporter{ + StateContext: schema.ImportStatePassthroughContext, + }, + SchemaVersion: 1, + Schema: map[string]*schema.Schema{ + "name": { + Description: `Outbound Messaging Campaign name.`, + Type: schema.TypeString, + Optional: true, + }, + }, + } +} diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go new file mode 100644 index 000000000..e1e3760b5 --- /dev/null +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go @@ -0,0 +1,440 @@ +package outbound_messagingcampaign + +import ( + "fmt" + "net/http" + "strconv" + "strings" + obDnclist "terraform-provider-genesyscloud/genesyscloud/outbound_dnclist" + "terraform-provider-genesyscloud/genesyscloud/provider" + "terraform-provider-genesyscloud/genesyscloud/util" + "testing" + "time" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" + "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" + + obCallableTimeset "terraform-provider-genesyscloud/genesyscloud/outbound_callabletimeset" + obContactList "terraform-provider-genesyscloud/genesyscloud/outbound_contact_list" + obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" +) + +/* +This test can only pass in a test org because it requires an active provisioned sms phone number +Endpoint `POST /api/v2/routing/sms/phonenumbers` creates an active/valid phone number in test orgs only. +*/ +func TestAccResourceOutboundMessagingCampaign(t *testing.T) { + + t.Parallel() + var ( + // Contact list + contactListResourceId = "contact_list" + contactListName = "Contact List " + uuid.NewString() + column1 = "phone" + column2 = "zipcode" + contactListResource = obContactList.GenerateOutboundContactList( + contactListResourceId, + contactListName, + util.NullValue, + util.NullValue, + []string{}, + []string{strconv.Quote(column1), strconv.Quote(column2)}, + util.NullValue, + util.NullValue, + util.NullValue, + obContactList.GeneratePhoneColumnsBlock( + column1, + "cell", + strconv.Quote(column1), + ), + ) + + // Messaging Campaign + resourceId = "messaging_campaign" + name = "Test Messaging Campaign " + uuid.NewString() + messagesPerMin = "10" + alwaysRunning = util.FalseValue + smsConfigMessageColumn = column1 + smsConfigPhoneColumn = column1 + smsConfigSenderSMSPhoneNumber = "+19198793429" + + // Messaging Campaign Updated fields + nameUpdate = "Test Messaging Campaign " + uuid.NewString() + messagesPerMinUpdate = "15" + alwaysRunningUpdate = TrueValue + + // DNC List + dncListResourceId = "dnc_list" + dncListName = "Test DNC List " + uuid.NewString() + dncListResource = obDnclist.GenerateOutboundDncListBasic( + dncListResourceId, + dncListName, + ) + + // Contact List Filter + clfResourceId = "contact_list_filter" + clfName = "Contact List Filter " + uuid.NewString() + contactListFilterResource = obContactListFilter.GenerateOutboundContactListFilter( + clfResourceId, + clfName, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "", + obContactListFilter.GenerateOutboundContactListFilterClause( + "", + obContactListFilter.GenerateOutboundContactListFilterPredicates( + column1, + "alphabetic", + "EQUALS", + "XYZ", + "", + "", + ), + ), + ) + + callableTimeSetResourceId = "callable_time_set" + callableTimeSetName = "Test CTS " + uuid.NewString() + callableTimeSetResource = obCallableTimeset.GenerateOutboundCallabletimeset( + callableTimeSetResourceId, + callableTimeSetName, + obCallableTimeset.GenerateCallableTimesBlock( + "Europe/Dublin", + obCallableTimeset.GenerateTimeSlotsBlock("07:00:00", "18:00:00", "3"), + obCallableTimeset.GenerateTimeSlotsBlock("09:30:00", "22:30:00", "5"), + ), + ) + ) + + config, err := provider.AuthorizeSdk() + if err != nil { + t.Errorf("failed to authorize client: %v", err) + } + api := platformclientv2.NewRoutingApiWithConfig(config) + err = createRoutingSmsPhoneNumber(smsConfigSenderSMSPhoneNumber, api) + if err != nil { + t.Errorf("error creating sms phone number %s: %v", smsConfigSenderSMSPhoneNumber, err) + } + defer func() { + _, err := api.DeleteRoutingSmsPhonenumber(smsConfigSenderSMSPhoneNumber) + if err != nil { + t.Logf("error deleting phone number %s: %v", smsConfigSenderSMSPhoneNumber, err) + } + }() + + resource.Test(t, resource.TestCase{ + PreCheck: func() { util.TestAccPreCheck(t) }, + ProviderFactories: provider.GetProviderFactories(providerResources, providerDataSources), + Steps: []resource.TestStep{ + { + Config: dncListResource + + contactListResource + + contactListFilterResource + + callableTimeSetResource + + generateOutboundMessagingCampaignResource( + resourceId, + name, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "off", + messagesPerMin, + alwaysRunning, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn, + smsConfigPhoneColumn, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "", + "", + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "DESC", + TrueValue, + ), + generateDynamicContactQueueingSettingsBlock(util.TrueValue), + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", name), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMin), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "always_running", alwaysRunning), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "campaign_status", "off"), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.message_column", smsConfigMessageColumn), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.phone_column", smsConfigPhoneColumn), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.sender_sms_phone_number", smsConfigSenderSMSPhoneNumber), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.field_name", column1), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.direction", "ASC"), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.numeric", util.FalseValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.field_name", column2), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "DESC"), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", TrueValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "dynamic_contact_queueing_settings.0.sort", TrueValue), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "dnc_list_ids.0", + "genesyscloud_outbound_dnclist."+dncListResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_filter_ids.0", + "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", + "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), + provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), + ), + }, + { + Config: dncListResource + + contactListResource + + contactListFilterResource + + callableTimeSetResource + + generateOutboundMessagingCampaignResource( + resourceId, + name, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "on", + messagesPerMin, + alwaysRunning, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn, + smsConfigPhoneColumn, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "", + "", + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "DESC", + TrueValue, + ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), + ), + Check: resource.ComposeTestCheckFunc( + // Check that the DiffSuppressFunc is working + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", name), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMin), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "always_running", alwaysRunning), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.message_column", smsConfigMessageColumn), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.phone_column", smsConfigPhoneColumn), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.sender_sms_phone_number", smsConfigSenderSMSPhoneNumber), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.field_name", column1), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.direction", "ASC"), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.numeric", util.FalseValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.field_name", column2), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "DESC"), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", TrueValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "dynamic_contact_queueing_settings.0.sort", util.FalseValue), + util.VerifyAttributeInArrayOfPotentialValues("genesyscloud_outbound_messagingcampaign."+resourceId, "campaign_status", []string{"on", "complete"}), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "dnc_list_ids.0", + "genesyscloud_outbound_dnclist."+dncListResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_filter_ids.0", + "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", + "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), + provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), + ), + }, + { + // Update + Config: dncListResource + + contactListResource + + contactListFilterResource + + callableTimeSetResource + + generateOutboundMessagingCampaignResource( + resourceId, + nameUpdate, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "on", + messagesPerMinUpdate, + alwaysRunningUpdate, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn, + smsConfigPhoneColumn, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "DESC", + TrueValue, + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "", + "", + ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), + ), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", nameUpdate), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMinUpdate), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "always_running", alwaysRunningUpdate), + util.VerifyAttributeInArrayOfPotentialValues("genesyscloud_outbound_messagingcampaign."+resourceId, "campaign_status", []string{"on", "complete"}), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.message_column", smsConfigMessageColumn), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.phone_column", smsConfigPhoneColumn), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.sender_sms_phone_number", smsConfigSenderSMSPhoneNumber), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.field_name", column1), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.direction", "DESC"), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.numeric", TrueValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.field_name", column2), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "ASC"), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", util.FalseValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "dynamic_contact_queueing_settings.0.sort", util.FalseValue), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_filter_ids.0", + "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", + "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), + provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), + ), + }, + { + ResourceName: "genesyscloud_outbound_messagingcampaign." + resourceId, + ImportState: true, + ImportStateVerify: true, + }, + }, + CheckDestroy: testVerifyOutboundMessagingCampaignDestroyed, + }) +} + +func createRoutingSmsPhoneNumber(inputSmsPhoneNumber string, api *platformclientv2.RoutingApi) error { + var ( + phoneNumberType = "local" + countryCode = "US" + status string + maxRetries = 10 + ) + _, resp, err := api.GetRoutingSmsPhonenumber(inputSmsPhoneNumber, "compliance") + if resp.StatusCode == 200 { + // Number already exists + return nil + } else if resp.StatusCode == http.StatusNotFound { + body := platformclientv2.Smsphonenumberprovision{ + PhoneNumber: &inputSmsPhoneNumber, + PhoneNumberType: &phoneNumberType, + CountryCode: &countryCode, + } + // POST /api/v2/routing/sms/phonenumbers + address, _, err := api.PostRoutingSmsPhonenumbers(body) + if err != nil { + return err + } + // Ensure status transitions to complete before proceeding + for i := 0; i <= maxRetries; i++ { + time.Sleep(3 * time.Second) + // GET /api/v2/routing/sms/phonenumbers/{addressId} + sdkSmsPhoneNumber, _, err := api.GetRoutingSmsPhonenumber(*address.PhoneNumber, "compliance") + if err != nil { + return err + } + status = *sdkSmsPhoneNumber.ProvisioningStatus.State + if status == "Running" { + if i == maxRetries { + return fmt.Errorf(`sms phone number status did not transition to "Completed" within max retries %v`, maxRetries) + } + continue + } + break + } + if status == "Failed" { + return fmt.Errorf(`sms phone number provisioning failed`) + } + } else if err != nil { + return fmt.Errorf("error checking for sms phone number %v: %v", inputSmsPhoneNumber, err) + } + return nil +} + +func generateOutboundMessagingCampaignResource( + resourceId string, + name string, + contactListId string, + campaignStatus string, + messagesPerMinute string, + alwaysRunning string, + callableTimeSetId string, + dncListIds []string, + contactListFilterIds []string, + nestedBlocks ...string, +) string { + if callableTimeSetId != "" { + callableTimeSetId = fmt.Sprintf(`callable_time_set_id = %s`, callableTimeSetId) + } + if alwaysRunning != "" { + alwaysRunning = fmt.Sprintf(`always_running = %s`, alwaysRunning) + } + if campaignStatus != "" { + campaignStatus = fmt.Sprintf(`campaign_status = "%s"`, campaignStatus) + } + return fmt.Sprintf(` +resource "genesyscloud_outbound_messagingcampaign" "%s" { + name = "%s" + contact_list_id = %s + %s + messages_per_minute = %s + %s + %s + dnc_list_ids = [%s] + contact_list_filter_ids = [%s] + %s +} +`, resourceId, name, contactListId, campaignStatus, messagesPerMinute, alwaysRunning, callableTimeSetId, + strings.Join(dncListIds, ", "), strings.Join(contactListFilterIds, ", "), strings.Join(nestedBlocks, "\n")) +} + +func generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn string, + smsConfigPhoneColumn string, + smsConfigSenderSMSPhoneNumber string, +) string { + return fmt.Sprintf(` + sms_config { + message_column = "%s" + phone_column = "%s" + sender_sms_phone_number = "%s" + } +`, smsConfigMessageColumn, smsConfigPhoneColumn, smsConfigSenderSMSPhoneNumber) +} + +func generateDynamicContactQueueingSettingsBlock(sort string) string { + return fmt.Sprintf(` + dynamic_contact_queueing_settings { + sort = %s + } + `, sort) +} + +func testVerifyOutboundMessagingCampaignDestroyed(state *terraform.State) error { + outboundAPI := platformclientv2.NewOutboundApi() + for _, rs := range state.RootModule().Resources { + if rs.Type != "genesyscloud_outbound_messagingcampaign" { + continue + } + campaign, resp, err := outboundAPI.GetOutboundMessagingcampaign(rs.Primary.ID) + if campaign != nil { + return fmt.Errorf("messaging campaign (%s) still exists", rs.Primary.ID) + } else if util.IsStatus404(resp) { + // Messaging Campaign not found as expected + continue + } else { + // Unexpected error + return fmt.Errorf("unexpected error: %s", err) + } + } + // Success. All messaging campaigns destroyed + return nil +} diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go new file mode 100644 index 000000000..bfe94f26d --- /dev/null +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go @@ -0,0 +1,367 @@ +package outbound_messagingcampaign + +import ( + "fmt" + "terraform-provider-genesyscloud/genesyscloud/util" + "terraform-provider-genesyscloud/genesyscloud/util/resourcedata" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" +) + +/* +The resource_genesyscloud_outbound_messagingcampaign_utils.go file contains various helper methods to marshal +and unmarshal data into formats consumable by Terraform and/or Genesys Cloud. +*/ + +// getOutboundMessagingcampaignFromResourceData maps data from schema ResourceData object to a platformclientv2.Messagingcampaign +func getOutboundMessagingcampaignFromResourceData(d *schema.ResourceData) platformclientv2.Messagingcampaign { + return platformclientv2.Messagingcampaign{ + Name: platformclientv2.String(d.Get("name").(string)), + Division: util.BuildSdkDomainEntityRef(d, "division_id"), + CampaignStatus: platformclientv2.String(d.Get("campaign_status").(string)), + CallableTimeSet: util.BuildSdkDomainEntityRef(d, "callable_time_set_id"), + ContactList: util.BuildSdkDomainEntityRef(d, "contact_list_id"), + DncLists: util.BuildSdkDomainEntityRefArr(d, "dnc_list_ids"), + AlwaysRunning: platformclientv2.Bool(d.Get("always_running").(bool)), + ContactSorts: buildContactSorts(d.Get("contact_sorts").([]interface{})), + MessagesPerMinute: platformclientv2.Int(d.Get("messages_per_minute").(int)), + //RuleSets: util.BuildSdkDomainEntityRefArr(d, "rule_sets"), + ContactListFilters: util.BuildSdkDomainEntityRefArr(d, "contact_list_filter_ids"), + //Errors: buildRestErrorDetails(d.Get("errors").([]interface{})), + DynamicContactQueueingSettings: buildDynamicContactQueueingSettingss(d.Get("dynamic_contact_queueing_settings").([]interface{})), + //EmailConfig: buildEmailConfigs(d.Get("email_config").(*schema.Set)), + SmsConfig: buildSmsConfigs(d.Get("sms_config").(*schema.Set)), + } +} + +// buildContactSorts maps an []interface{} into a Genesys Cloud *[]platformclientv2.Contactsort +func buildContactSorts(contactSorts []interface{}) *[]platformclientv2.Contactsort { + if contactSorts == nil { + return nil + } + sdkContactSortSlice := make([]platformclientv2.Contactsort, 0) + for _, configContactSort := range contactSorts { + var sdkContactSort platformclientv2.Contactsort + contactsortMap := configContactSort.(map[string]interface{}) + if fieldName := contactsortMap["field_name"].(string); fieldName != "" { + sdkContactSort.FieldName = &fieldName + } + if direction := contactsortMap["direction"].(string); direction != "" { + sdkContactSort.Direction = &direction + } + if numeric, ok := contactsortMap["numeric"].(bool); ok { + sdkContactSort.Numeric = platformclientv2.Bool(numeric) + } + + sdkContactSortSlice = append(sdkContactSortSlice, sdkContactSort) + } + return &sdkContactSortSlice +} + +// buildRestErrorDetails maps an []interface{} into a Genesys Cloud *[]platformclientv2.Resterrordetail +func buildRestErrorDetails(restErrorDetails []interface{}) *[]platformclientv2.Resterrordetail { + restErrorDetailsSlice := make([]platformclientv2.Resterrordetail, 0) + for _, restErrorDetail := range restErrorDetails { + var sdkRestErrorDetail platformclientv2.Resterrordetail + restErrorDetailsMap, ok := restErrorDetail.(map[string]interface{}) + if !ok { + continue + } + + resourcedata.BuildSDKStringValueIfNotNil(&sdkRestErrorDetail.VarError, restErrorDetailsMap, "error") + resourcedata.BuildSDKStringValueIfNotNil(&sdkRestErrorDetail.Details, restErrorDetailsMap, "details") + + restErrorDetailsSlice = append(restErrorDetailsSlice, sdkRestErrorDetail) + } + + return &restErrorDetailsSlice +} + +// buildDynamicContactQueueingSettingss maps an []interface{} into a Genesys Cloud *[]platformclientv2.Dynamiccontactqueueingsettings +func buildDynamicContactQueueingSettingss(settings []interface{}) *platformclientv2.Dynamiccontactqueueingsettings { + if settings == nil || len(settings) < 1 { + return nil + } + var sdkDcqSettings platformclientv2.Dynamiccontactqueueingsettings + dcqSetting, ok := settings[0].(map[string]interface{}) + if !ok { + return nil + } + if sort, ok := dcqSetting["sort"].(bool); ok { + sdkDcqSettings.Sort = &sort + } + return &sdkDcqSettings +} + +// buildFromEmailAddresss maps an []interface{} into a Genesys Cloud *[]platformclientv2.Fromemailaddress +func buildFromEmailAddresss(fromEmailAddresss []interface{}) *platformclientv2.Fromemailaddress { + fromEmailAddresssSlice := make([]platformclientv2.Fromemailaddress, 0) + for _, fromEmailAddress := range fromEmailAddresss { + var sdkFromEmailAddress platformclientv2.Fromemailaddress + fromEmailAddresssMap, ok := fromEmailAddress.(map[string]interface{}) + if !ok { + continue + } + + sdkFromEmailAddress.Domain = &platformclientv2.Domainentityref{Id: platformclientv2.String(fromEmailAddresssMap["domain_id"].(string))} + resourcedata.BuildSDKStringValueIfNotNil(&sdkFromEmailAddress.FriendlyName, fromEmailAddresssMap, "friendly_name") + resourcedata.BuildSDKStringValueIfNotNil(&sdkFromEmailAddress.LocalPart, fromEmailAddresssMap, "local_part") + + fromEmailAddresssSlice = append(fromEmailAddresssSlice, sdkFromEmailAddress) + } + + return &fromEmailAddresssSlice[0] +} + +// buildReplyToEmailAddresss maps an []interface{} into a Genesys Cloud *[]platformclientv2.Replytoemailaddress +func buildReplyToEmailAddresss(replyToEmailAddresss []interface{}) *platformclientv2.Replytoemailaddress { + replyToEmailAddresssSlice := make([]platformclientv2.Replytoemailaddress, 0) + for _, replyToEmailAddress := range replyToEmailAddresss { + var sdkReplyToEmailAddress platformclientv2.Replytoemailaddress + replyToEmailAddresssMap, ok := replyToEmailAddress.(map[string]interface{}) + if !ok { + continue + } + + sdkReplyToEmailAddress.Domain = &platformclientv2.Domainentityref{Id: platformclientv2.String(replyToEmailAddresssMap["domain_id"].(string))} + sdkReplyToEmailAddress.Route = &platformclientv2.Domainentityref{Id: platformclientv2.String(replyToEmailAddresssMap["route_id"].(string))} + + replyToEmailAddresssSlice = append(replyToEmailAddresssSlice, sdkReplyToEmailAddress) + } + + return &replyToEmailAddresssSlice[0] +} + +// buildEmailConfigs maps an []interface{} into a Genesys Cloud *[]platformclientv2.Emailconfig +func buildEmailConfigs(emailConfigs *schema.Set) *platformclientv2.Emailconfig { + if emailConfigs == nil { + return nil + } + + var sdkEmailConfig platformclientv2.Emailconfig + emailConfigList := emailConfigs.List() + if len(emailConfigList) > 0 { + emailConfigsMap := emailConfigList[0].(map[string]interface{}) + resourcedata.BuildSDKStringArrayValueIfNotNil(&sdkEmailConfig.EmailColumns, emailConfigsMap, "email_columns") + sdkEmailConfig.ContentTemplate = &platformclientv2.Domainentityref{Id: platformclientv2.String(emailConfigsMap["content_template_id"].(string))} + resourcedata.BuildSDKInterfaceArrayValueIfNotNil(&sdkEmailConfig.FromAddress, emailConfigsMap, "from_address", buildFromEmailAddresss) + resourcedata.BuildSDKInterfaceArrayValueIfNotNil(&sdkEmailConfig.ReplyToAddress, emailConfigsMap, "reply_to_address", buildReplyToEmailAddresss) + } + + return &sdkEmailConfig +} + +// buildSmsConfigs maps an []interface{} into a Genesys Cloud *platformclientv2.Smsconfig +func buildSmsConfigs(smsConfigs *schema.Set) *platformclientv2.Smsconfig { + if smsConfigs == nil { + return nil + } + var sdkSmsconfig platformclientv2.Smsconfig + smsconfigList := smsConfigs.List() + if len(smsconfigList) > 0 { + smsconfigMap := smsconfigList[0].(map[string]interface{}) + if messageColumn := smsconfigMap["message_column"].(string); messageColumn != "" { + sdkSmsconfig.MessageColumn = &messageColumn + } + if phoneColumn := smsconfigMap["phone_column"].(string); phoneColumn != "" { + sdkSmsconfig.PhoneColumn = &phoneColumn + } + if senderSmsPhoneNumber := smsconfigMap["sender_sms_phone_number"].(string); senderSmsPhoneNumber != "" { + sdkSmsconfig.SenderSmsPhoneNumber = &platformclientv2.Smsphonenumberref{ + PhoneNumber: &senderSmsPhoneNumber, + } + } + if contentTemplateId := smsconfigMap["content_template_id"].(string); contentTemplateId != "" { + sdkSmsconfig.ContentTemplate = &platformclientv2.Domainentityref{Id: &contentTemplateId} + } + } + + return &sdkSmsconfig +} + +// flattenContactSorts maps a Genesys Cloud *[]platformclientv2.Contactsort into a []interface{} +func flattenContactSorts(contactSorts *[]platformclientv2.Contactsort) []interface{} { + if len(*contactSorts) == 0 { + return nil + } + + var contactSortList []interface{} + for _, contactSort := range *contactSorts { + contactSortMap := make(map[string]interface{}) + + resourcedata.SetMapValueIfNotNil(contactSortMap, "field_name", contactSort.FieldName) + resourcedata.SetMapValueIfNotNil(contactSortMap, "direction", contactSort.Direction) + resourcedata.SetMapValueIfNotNil(contactSortMap, "numeric", contactSort.Numeric) + + contactSortList = append(contactSortList, contactSortMap) + } + + return contactSortList +} + +// flattenRestErrorDetails maps a Genesys Cloud *[]platformclientv2.Resterrordetail into a []interface{} +func flattenRestErrorDetails(restErrorDetails *[]platformclientv2.Resterrordetail) []interface{} { + if len(*restErrorDetails) == 0 { + return nil + } + + var restErrorDetailList []interface{} + for _, restErrorDetail := range *restErrorDetails { + restErrorDetailMap := make(map[string]interface{}) + + resourcedata.SetMapValueIfNotNil(restErrorDetailMap, "error", restErrorDetail.VarError) + resourcedata.SetMapValueIfNotNil(restErrorDetailMap, "details", restErrorDetail.Details) + + restErrorDetailList = append(restErrorDetailList, restErrorDetailMap) + } + + return restErrorDetailList +} + +// flattenDynamicContactQueueingSettingss maps a Genesys Cloud *[]platformclientv2.Dynamiccontactqueueingsettings into a []interface{} +func flattenDynamicContactQueueingSettingss(dynamicContactQueueingSettingss *platformclientv2.Dynamiccontactqueueingsettings) []interface{} { + if dynamicContactQueueingSettingss == nil { + return nil + } + + var dynamicContactQueueingSettingsList []interface{} + dynamicContactQueueingSettingsMap := make(map[string]interface{}) + + resourcedata.SetMapValueIfNotNil(dynamicContactQueueingSettingsMap, "sort", dynamicContactQueueingSettingss.Sort) + + dynamicContactQueueingSettingsList = append(dynamicContactQueueingSettingsList, dynamicContactQueueingSettingsMap) + + return dynamicContactQueueingSettingsList +} + +// flattenFromEmailAddresss maps a Genesys Cloud *[]platformclientv2.Fromemailaddress into a []interface{} +func flattenFromEmailAddresss(fromEmailAddresss *platformclientv2.Fromemailaddress) []interface{} { + if fromEmailAddresss == nil { + return nil + } + + var fromEmailAddressList []interface{} + fromEmailAddressMap := make(map[string]interface{}) + + resourcedata.SetMapReferenceValueIfNotNil(fromEmailAddressMap, "domain_id", fromEmailAddresss.Domain) + resourcedata.SetMapValueIfNotNil(fromEmailAddressMap, "friendly_name", fromEmailAddresss.FriendlyName) + resourcedata.SetMapValueIfNotNil(fromEmailAddressMap, "local_part", fromEmailAddresss.LocalPart) + fromEmailAddressList = append(fromEmailAddressList, fromEmailAddressMap) + return fromEmailAddressList +} + +// flattenReplyToEmailAddresss maps a Genesys Cloud *[]platformclientv2.Replytoemailaddress into a []interface{} +func flattenReplyToEmailAddresss(replyToEmailAddresss *platformclientv2.Replytoemailaddress) []interface{} { + if replyToEmailAddresss == nil { + return nil + } + + var replyToEmailAddressList []interface{} + replyToEmailAddressMap := make(map[string]interface{}) + + resourcedata.SetMapReferenceValueIfNotNil(replyToEmailAddressMap, "domain_id", replyToEmailAddresss.Domain) + resourcedata.SetMapReferenceValueIfNotNil(replyToEmailAddressMap, "route_id", replyToEmailAddresss.Route) + replyToEmailAddressList = append(replyToEmailAddressList, replyToEmailAddressMap) + return replyToEmailAddressList +} + +// flattenEmailConfigs maps a Genesys Cloud *[]platformclientv2.Emailconfig into a []interface{} +func flattenEmailConfigs(emailConfigs *platformclientv2.Emailconfig) []interface{} { + if emailConfigs == nil { + return nil + } + + var emailConfigList []interface{} + emailConfigMap := make(map[string]interface{}) + + resourcedata.SetMapStringArrayValueIfNotNil(emailConfigMap, "email_columns", emailConfigs.EmailColumns) + resourcedata.SetMapReferenceValueIfNotNil(emailConfigMap, "content_template_id", emailConfigs.ContentTemplate) + resourcedata.SetMapInterfaceArrayWithFuncIfNotNil(emailConfigMap, "from_address", emailConfigs.FromAddress, flattenFromEmailAddresss) + resourcedata.SetMapInterfaceArrayWithFuncIfNotNil(emailConfigMap, "reply_to_address", emailConfigs.ReplyToAddress, flattenReplyToEmailAddresss) + + emailConfigList = append(emailConfigList, emailConfigMap) + + return emailConfigList +} + +// flattenSmsPhoneNumberRefs maps a Genesys Cloud *[]platformclientv2.Smsphonenumberref into a []interface{} +func flattenSmsPhoneNumberRefs(smsPhoneNumberRefs *platformclientv2.Smsphonenumberref) []interface{} { + if smsPhoneNumberRefs == nil { + return nil + } + + var smsPhoneNumberRefList []interface{} + smsPhoneNumberRefMap := make(map[string]interface{}) + + resourcedata.SetMapValueIfNotNil(smsPhoneNumberRefMap, "phone_number", smsPhoneNumberRefs.PhoneNumber) + + smsPhoneNumberRefList = append(smsPhoneNumberRefList, smsPhoneNumberRefMap) + + return smsPhoneNumberRefList +} + +// flattenSmsConfigs maps a Genesys Cloud *platformclientv2.Smsconfig into a []interface{} +func flattenSmsConfigs(smsconfig *platformclientv2.Smsconfig) *schema.Set { + if smsconfig == nil { + return nil + } + + smsconfigSet := schema.NewSet(schema.HashResource(smsConfigResource), []interface{}{}) + smsconfigMap := make(map[string]interface{}) + + if smsconfig.MessageColumn != nil { + smsconfigMap["message_column"] = *smsconfig.MessageColumn + } + if smsconfig.PhoneColumn != nil { + smsconfigMap["phone_column"] = *smsconfig.PhoneColumn + } + if smsconfig.SenderSmsPhoneNumber != nil { + if smsconfig.SenderSmsPhoneNumber.PhoneNumber != nil { + smsconfigMap["sender_sms_phone_number"] = *smsconfig.SenderSmsPhoneNumber.PhoneNumber + } + } + if smsconfig.ContentTemplate != nil { + smsconfigMap["content_template_id"] = *smsconfig.ContentTemplate.Id + } + + smsconfigSet.Add(smsconfigMap) + + return smsconfigSet +} + +func validateSmsconfig(smsconfig *schema.Set) (string, bool) { + if smsconfig == nil { + return "", true + } + + smsconfigList := smsconfig.List() + if len(smsconfigList) > 0 { + smsconfigMap := smsconfigList[0].(map[string]interface{}) + messageColumn, _ := smsconfigMap["message_column"].(string) + contentTemplateId, _ := smsconfigMap["content_template_id"].(string) + if messageColumn == "" && contentTemplateId == "" { + return "Either message_column or content_template_id is required.", false + } else if messageColumn != "" && contentTemplateId != "" { + return "Only one of message_column or content_template_id can be defined", false + } + } + + return "", true +} + +func GenerateOutboundMessagingCampaignContactSort(fieldName string, direction string, numeric string) string { + if direction != "" { + direction = fmt.Sprintf(`direction = "%s"`, direction) + } + if numeric != "" { + numeric = fmt.Sprintf(`numeric = %s`, numeric) + } + return fmt.Sprintf(` + contact_sorts { + field_name = "%s" + %s + %s + } +`, fieldName, direction, numeric) +} diff --git a/genesyscloud/tfexporter/tf_exporter_resource_test.go b/genesyscloud/tfexporter/tf_exporter_resource_test.go index a0e4d44aa..315a28f0d 100644 --- a/genesyscloud/tfexporter/tf_exporter_resource_test.go +++ b/genesyscloud/tfexporter/tf_exporter_resource_test.go @@ -31,7 +31,6 @@ import ( "terraform-provider-genesyscloud/genesyscloud/oauth_client" oAuthSettings "terraform-provider-genesyscloud/genesyscloud/organization_authentication_settings" oAuthPairing "terraform-provider-genesyscloud/genesyscloud/orgauthorization_pairing" - ob "terraform-provider-genesyscloud/genesyscloud/outbound" outboundAttemptLimit "terraform-provider-genesyscloud/genesyscloud/outbound_attempt_limit" obCallableTimeset "terraform-provider-genesyscloud/genesyscloud/outbound_callabletimeset" obCallResponseSet "terraform-provider-genesyscloud/genesyscloud/outbound_callanalysisresponseset" @@ -42,6 +41,7 @@ import ( obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" obDncList "terraform-provider-genesyscloud/genesyscloud/outbound_dnclist" obfst "terraform-provider-genesyscloud/genesyscloud/outbound_filespecificationtemplate" + obMessagingCampaign "terraform-provider-genesyscloud/genesyscloud/outbound_messagingcampaign" obRuleset "terraform-provider-genesyscloud/genesyscloud/outbound_ruleset" obSequence "terraform-provider-genesyscloud/genesyscloud/outbound_sequence" obSettings "terraform-provider-genesyscloud/genesyscloud/outbound_settings" @@ -184,7 +184,7 @@ func (r *registerTestInstance) registerTestResources() { providerResources["genesyscloud_outbound_contact_list"] = outboundContactList.ResourceOutboundContactList() providerResources["genesyscloud_outbound_contact_list_contact"] = outboundContactListContact.ResourceOutboundContactListContact() providerResources["genesyscloud_outbound_contactlistfilter"] = obContactListFilter.ResourceOutboundContactlistfilter() - providerResources["genesyscloud_outbound_messagingcampaign"] = ob.ResourceOutboundMessagingCampaign() + providerResources["genesyscloud_outbound_messagingcampaign"] = obMessagingCampaign.ResourceOutboundMessagingcampaign() providerResources["genesyscloud_outbound_sequence"] = obSequence.ResourceOutboundSequence() providerResources["genesyscloud_outbound_dnclist"] = obDncList.ResourceOutboundDncList() providerResources["genesyscloud_outbound_campaignrule"] = obCampaignRule.ResourceOutboundCampaignrule() @@ -250,7 +250,7 @@ func (r *registerTestInstance) registerTestExporters() { RegisterExporter("genesyscloud_outbound_contact_list", outboundContactList.OutboundContactListExporter()) RegisterExporter("genesyscloud_outbound_contact_list_contact", outboundContactListContact.ContactExporter()) RegisterExporter("genesyscloud_outbound_contactlistfilter", obContactListFilter.OutboundContactlistfilterExporter()) - RegisterExporter("genesyscloud_outbound_messagingcampaign", ob.OutboundMessagingcampaignExporter()) + RegisterExporter("genesyscloud_outbound_messagingcampaign", obMessagingCampaign.OutboundMessagingcampaignExporter()) RegisterExporter("genesyscloud_outbound_sequence", obSequence.OutboundSequenceExporter()) RegisterExporter("genesyscloud_outbound_dnclist", obDncList.OutboundDncListExporter()) RegisterExporter("genesyscloud_outbound_campaignrule", obCampaignRule.OutboundCampaignruleExporter()) diff --git a/main.go b/main.go index ad44a2841..ba9273ba2 100644 --- a/main.go +++ b/main.go @@ -50,6 +50,7 @@ import ( obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" obDncList "terraform-provider-genesyscloud/genesyscloud/outbound_dnclist" obfst "terraform-provider-genesyscloud/genesyscloud/outbound_filespecificationtemplate" + obMessagingCampaign "terraform-provider-genesyscloud/genesyscloud/outbound_messagingcampaign" obs "terraform-provider-genesyscloud/genesyscloud/outbound_ruleset" obSequence "terraform-provider-genesyscloud/genesyscloud/outbound_sequence" obSettings "terraform-provider-genesyscloud/genesyscloud/outbound_settings" @@ -182,6 +183,7 @@ func registerResources() { obCampaign.SetRegistrar(regInstance) //Registering outbound campaign obContactList.SetRegistrar(regInstance) //Registering outbound contact list obContactListFilter.SetRegistrar(regInstance) //Registering outbound contact list filter + obMessagingCampaign.SetRegistrar(regInstance) //Registering outbound messaging campaign obSequence.SetRegistrar(regInstance) //Registering outbound sequence obCampaignRule.SetRegistrar(regInstance) //Registering outbound campaignrule obSettings.SetRegistrar(regInstance) //Registering outbound settings From 907a37461e35d520cb2fb5e5524ec45d7ccd646f Mon Sep 17 00:00:00 2001 From: Shruti Suryawanshi Date: Thu, 11 Jul 2024 13:18:55 -0400 Subject: [PATCH 2/6] added testcases for outbound messaging campaign --- docs/resources/outbound_messagingcampaign.md | 88 ++- ...rce_genesyscloud_outbound_cattemptlimit.go | 4 +- ...genesyscloud_outbound_messagingcampaign.go | 62 -- ...yscloud_outbound_messagingcampaign_test.go | 159 ----- .../resource_genesyscloud_outbound_init.go | 3 - ...esource_genesyscloud_outbound_init_test.go | 5 +- ...genesyscloud_outbound_messagingcampaign.go | 545 ------------------ ...yscloud_outbound_messagingcampaign_test.go | 426 -------------- ...e_genesyscloud_outbound_campaign_schema.go | 9 +- ...rce_genesyscloud_outbound_campaign_test.go | 10 +- ...genesyscloud_outbound_messagingcampaign.go | 32 +- ...yscloud_outbound_messagingcampaign_test.go | 3 +- ...ud_outbound_messagingcampaign_init_test.go | 9 +- ...genesyscloud_outbound_messagingcampaign.go | 6 +- ...cloud_outbound_messagingcampaign_schema.go | 29 +- ...yscloud_outbound_messagingcampaign_test.go | 4 +- ...scloud_outbound_messagingcampaign_utils.go | 67 ++- 17 files changed, 167 insertions(+), 1294 deletions(-) delete mode 100644 genesyscloud/outbound/data_source_genesyscloud_outbound_messagingcampaign.go delete mode 100644 genesyscloud/outbound/data_source_genesyscloud_outbound_messagingcampaign_test.go delete mode 100644 genesyscloud/outbound/resource_genesyscloud_outbound_messagingcampaign.go delete mode 100644 genesyscloud/outbound/resource_genesyscloud_outbound_messagingcampaign_test.go diff --git a/docs/resources/outbound_messagingcampaign.md b/docs/resources/outbound_messagingcampaign.md index 718a9ed07..36d3f9c18 100644 --- a/docs/resources/outbound_messagingcampaign.md +++ b/docs/resources/outbound_messagingcampaign.md @@ -2,11 +2,11 @@ page_title: "genesyscloud_outbound_messagingcampaign Resource - terraform-provider-genesyscloud" subcategory: "" description: |- - Genesys Cloud Outbound Messaging Campaign + Genesys Cloud outbound messagingcampaign --- # genesyscloud_outbound_messagingcampaign (Resource) -Genesys Cloud Outbound Messaging Campaign +Genesys Cloud outbound messagingcampaign ## API Usage The following Genesys Cloud APIs are used by this resource. Ensure your OAuth Client has been granted the necessary scopes and permissions to perform these operations: @@ -54,7 +54,6 @@ resource "genesyscloud_outbound_messagingcampaign" "example_outbound_messagingca - `contact_list_id` (String) The contact list that this messaging campaign will send messages for. - `messages_per_minute` (Number) How many messages this messaging campaign will send per minute. - `name` (String) The campaign name. -- `sms_config` (Block Set, Min: 1, Max: 1) Configuration for this messaging campaign to send SMS messages. (see [below for nested schema](#nestedblock--sms_config)) ### Optional @@ -65,34 +64,95 @@ resource "genesyscloud_outbound_messagingcampaign" "example_outbound_messagingca - `contact_sorts` (Block List) The order in which to sort contacts for dialing, based on up to four columns. (see [below for nested schema](#nestedblock--contact_sorts)) - `division_id` (String) The division this entity belongs to. - `dnc_list_ids` (List of String) The dnc lists to check before sending a message for this messaging campaign. +- `dynamic_contact_queueing_settings` (Block List, Max: 1) Indicates (when true) that the campaign supports dynamic queueing of the contact list at the time of a request for contacts. (see [below for nested schema](#nestedblock--dynamic_contact_queueing_settings)) +- `email_config` (Block Set, Max: 1) Configuration for this messaging campaign to send Email messages. (see [below for nested schema](#nestedblock--email_config)) +- `errors` (Block List) A list of current error conditions associated with this messaging campaign. (see [below for nested schema](#nestedblock--errors)) +- `rule_sets_ids` (List of String) Rule Sets to be applied while this campaign is sending messages +- `sms_config` (Block Set, Max: 1) Configuration for this messaging campaign to send SMS messages. (see [below for nested schema](#nestedblock--sms_config)) ### Read-Only - `id` (String) The ID of this resource. - -### Nested Schema for `sms_config` + +### Nested Schema for `contact_sorts` Required: -- `phone_column` (String) The Contact List column specifying the phone number to send a message to. -- `sender_sms_phone_number` (String) A phone number provisioned for SMS communications in E.164 format. E.g. +13175555555 or +34234234234 +- `field_name` (String) The field name by which to sort contacts. Optional: -- `content_template_id` (String) The content template used to formulate the message to send to the contact. Either message_column or content_template_id is required. -- `message_column` (String) The Contact List column specifying the message to send to the contact. Either message_column or content_template_id is required. +- `direction` (String) The direction in which to sort contacts. Defaults to `ASC`. +- `numeric` (Boolean) Whether or not the column contains numeric data. Defaults to `false`. - -### Nested Schema for `contact_sorts` + +### Nested Schema for `dynamic_contact_queueing_settings` + +Optional: + +- `sort` (Boolean) Whether to sort contacts dynamically + + + +### Nested Schema for `email_config` Required: -- `field_name` (String) The field name by which to sort contacts. +- `email_columns` (List of String) The contact list columns specifying the email address(es) of the contact. +- `from_address` (Block List, Min: 1, Max: 1) The email address that will be used as the sender of the email. (see [below for nested schema](#nestedblock--email_config--from_address)) Optional: -- `direction` (String) The direction in which to sort contacts. Defaults to `ASC`. -- `numeric` (Boolean) Whether or not the column contains numeric data. Defaults to `false`. +- `content_template_id` (String) The content template used to formulate the email to send to the contact. +- `reply_to_address` (Block List, Max: 1) The email address from which any reply will be sent. (see [below for nested schema](#nestedblock--email_config--reply_to_address)) + + +### Nested Schema for `email_config.from_address` + +Required: + +- `domain_id` (String) The OutboundDomain used for the email address. + +Optional: + +- `friendly_name` (String) The friendly name of the email address. +- `local_part` (String) The local part of the email address. + + + +### Nested Schema for `email_config.reply_to_address` + +Required: + +- `domain_id` (String) The InboundDomain used for the email address. +- `route_id` (String) The InboundRoute used for the email address. + + + + +### Nested Schema for `errors` + +Required: + +- `error` (String) name of the error + +Optional: + +- `details` (String) additional information regarding the error + + + +### Nested Schema for `sms_config` + +Required: + +- `phone_column` (String) The Contact List column specifying the phone number to send a message to. +- `sender_sms_phone_number` (String) A phone number provisioned for SMS communications in E.164 format. E.g. +13175555555 or +34234234234 + +Optional: + +- `content_template_id` (String) The content template used to formulate the message to send to the contact. +- `message_column` (String) The Contact List column specifying the message to send to the contact. diff --git a/genesyscloud/outbound/data_source_genesyscloud_outbound_cattemptlimit.go b/genesyscloud/outbound/data_source_genesyscloud_outbound_cattemptlimit.go index a76adebbc..6c4738e16 100644 --- a/genesyscloud/outbound/data_source_genesyscloud_outbound_cattemptlimit.go +++ b/genesyscloud/outbound/data_source_genesyscloud_outbound_cattemptlimit.go @@ -38,10 +38,10 @@ func dataSourceOutboundAttemptLimitRead(ctx context.Context, d *schema.ResourceD const pageSize = 100 attemptLimits, resp, getErr := outboundAPI.GetOutboundAttemptlimits(pageSize, pageNum, true, "", name, "", "") if getErr != nil { - return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("error requesting attempt limit %s | error: %s", name, getErr), resp)) + return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError("genesyscloud_outbound_attemptlimit", fmt.Sprintf("error requesting attempt limit %s | error: %s", name, getErr), resp)) } if attemptLimits.Entities == nil || len(*attemptLimits.Entities) == 0 { - return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("no attempt limits found with name %s", name), resp)) + return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError("genesyscloud_outbound_attemptlimit", fmt.Sprintf("no attempt limits found with name %s", name), resp)) } attemptLimit := (*attemptLimits.Entities)[0] d.SetId(*attemptLimit.Id) diff --git a/genesyscloud/outbound/data_source_genesyscloud_outbound_messagingcampaign.go b/genesyscloud/outbound/data_source_genesyscloud_outbound_messagingcampaign.go deleted file mode 100644 index a6b3bae39..000000000 --- a/genesyscloud/outbound/data_source_genesyscloud_outbound_messagingcampaign.go +++ /dev/null @@ -1,62 +0,0 @@ -package outbound - -import ( - "context" - "fmt" - "terraform-provider-genesyscloud/genesyscloud/provider" - "terraform-provider-genesyscloud/genesyscloud/util" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" -) - -func dataSourceOutboundMessagingcampaign() *schema.Resource { - return &schema.Resource{ - Description: `Data source for Genesys Cloud Outbound Messaging Campaign. Select a Outbound Messaging Campaign by name.`, - - ReadContext: provider.ReadWithPooledClient(dataSourceOutboundMessagingcampaignRead), - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - SchemaVersion: 1, - Schema: map[string]*schema.Schema{ - "name": { - Description: `Outbound Messaging Campaign name.`, - Type: schema.TypeString, - Optional: true, - }, - }, - } -} - -func dataSourceOutboundMessagingcampaignRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - sdkConfig := meta.(*provider.ProviderMeta).ClientConfig - outboundApi := platformclientv2.NewOutboundApiWithConfig(sdkConfig) - - name := d.Get("name").(string) - - return util.WithRetries(ctx, 15*time.Second, func() *retry.RetryError { - for pageNum := 1; ; pageNum++ { - const pageSize = 100 - sdkMessagingcampaignEntityListing, resp, getErr := outboundApi.GetOutboundMessagingcampaigns(pageSize, pageNum, "", "", "", "", []string{}, "", "", []string{}) - if getErr != nil { - return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("error requesting Outbound Messaging Campaign %s | error: %s", name, getErr), resp)) - } - - if sdkMessagingcampaignEntityListing.Entities == nil || len(*sdkMessagingcampaignEntityListing.Entities) == 0 { - return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("no Outbound Messaging Campaign found with name %s", name), resp)) - } - - for _, entity := range *sdkMessagingcampaignEntityListing.Entities { - if entity.Name != nil && *entity.Name == name { - d.SetId(*entity.Id) - return nil - } - } - } - }) -} diff --git a/genesyscloud/outbound/data_source_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound/data_source_genesyscloud_outbound_messagingcampaign_test.go deleted file mode 100644 index 56192696e..000000000 --- a/genesyscloud/outbound/data_source_genesyscloud_outbound_messagingcampaign_test.go +++ /dev/null @@ -1,159 +0,0 @@ -package outbound - -import ( - "fmt" - "strconv" - "terraform-provider-genesyscloud/genesyscloud/provider" - "terraform-provider-genesyscloud/genesyscloud/util" - "testing" - - obCallableTimeset "terraform-provider-genesyscloud/genesyscloud/outbound_callabletimeset" - obContactList "terraform-provider-genesyscloud/genesyscloud/outbound_contact_list" - obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" - - "github.com/google/uuid" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" -) - -var TrueValue = "true" - -/* -This test can only pass in a test org because it requires an active provisioned sms phone number -Endpoint `POST /api/v2/routing/sms/phonenumbers` creates an active/valid phone number in test orgs only. -*/ -func TestAccDataSourceOutboundMessagingCampaign(t *testing.T) { - - var ( - resourceId = "campaign" - dataSourceId = "campaign_data" - digitalCampaignName = "Test Digital Campaign " + uuid.NewString() - - clfResourceId = "clf" - clfName = "Test CLF " + uuid.NewString() - contactListResourceId = "contact_list" - contactListName = "Test Contact List " + uuid.NewString() - column1 = "phone" - column2 = "zipcode" - - smsConfigSenderSMSPhoneNumber = "+19198793428" - - callableTimeSetResourceId = "callable_time_set" - callableTimeSetName = "Test CTS " + uuid.NewString() - callableTimeSetResource = obCallableTimeset.GenerateOutboundCallabletimeset( - callableTimeSetResourceId, - callableTimeSetName, - obCallableTimeset.GenerateCallableTimesBlock( - "Europe/Dublin", - obCallableTimeset.GenerateTimeSlotsBlock("07:00:00", "18:00:00", "3"), - obCallableTimeset.GenerateTimeSlotsBlock("09:30:00", "22:30:00", "5"), - ), - ) - - contactListResource = obContactList.GenerateOutboundContactList( - contactListResourceId, - contactListName, - util.NullValue, - util.NullValue, - []string{}, - []string{strconv.Quote(column1), strconv.Quote(column2)}, - util.FalseValue, - util.NullValue, - util.NullValue, - obContactList.GeneratePhoneColumnsBlock( - column1, - "cell", - strconv.Quote(column1), - ), - ) - - contactListFilterResource = obContactListFilter.GenerateOutboundContactListFilter( - clfResourceId, - clfName, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "", - obContactListFilter.GenerateOutboundContactListFilterClause( - "", - obContactListFilter.GenerateOutboundContactListFilterPredicates( - column1, - "alphabetic", - "EQUALS", - "XYZ", - "", - "", - ), - ), - ) - ) - - config, err := provider.AuthorizeSdk() - if err != nil { - t.Errorf("failed to authorize client: %v", err) - } - api := platformclientv2.NewRoutingApiWithConfig(config) - err = createRoutingSmsPhoneNumber(smsConfigSenderSMSPhoneNumber, api) - if err != nil { - t.Errorf("error creating sms phone number %s: %v", smsConfigSenderSMSPhoneNumber, err) - } - defer func() { - _, err := api.DeleteRoutingSmsPhonenumber(smsConfigSenderSMSPhoneNumber) - if err != nil { - t.Logf("error deleting phone number %s: %v", smsConfigSenderSMSPhoneNumber, err) - } - }() - - resource.Test(t, resource.TestCase{ - PreCheck: func() { util.TestAccPreCheck(t) }, - ProviderFactories: provider.GetProviderFactories(providerResources, providerDataSources), - Steps: []resource.TestStep{ - { - Config: contactListResource + - contactListFilterResource + - callableTimeSetResource + - generateOutboundMessagingCampaignResource( - resourceId, - digitalCampaignName, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "", - "10", - util.FalseValue, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - column1, - column1, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "", - "", - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "DESC", - TrueValue, - ), - ) + generateOutboundMessagingCampaignDataSource( - dataSourceId, - digitalCampaignName, - "genesyscloud_outbound_messagingcampaign."+resourceId, - ), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttrPair("data.genesyscloud_outbound_messagingcampaign."+dataSourceId, "id", - "genesyscloud_outbound_messagingcampaign."+resourceId, "id"), - ), - }, - }, - }) -} - -func generateOutboundMessagingCampaignDataSource(id string, name string, dependsOn string) string { - return fmt.Sprintf(` -data "genesyscloud_outbound_messagingcampaign" "%s" { - name = "%s" - depends_on = [%s] -} -`, id, name, dependsOn) -} diff --git a/genesyscloud/outbound/resource_genesyscloud_outbound_init.go b/genesyscloud/outbound/resource_genesyscloud_outbound_init.go index 34f5cd69b..501591edc 100644 --- a/genesyscloud/outbound/resource_genesyscloud_outbound_init.go +++ b/genesyscloud/outbound/resource_genesyscloud_outbound_init.go @@ -7,7 +7,4 @@ import ( func SetRegistrar(l registrar.Registrar) { l.RegisterDataSource("genesyscloud_outbound_attempt_limit", DataSourceOutboundAttemptLimit()) - l.RegisterDataSource("genesyscloud_outbound_messagingcampaign", dataSourceOutboundMessagingcampaign()) - l.RegisterResource("genesyscloud_outbound_messagingcampaign", ResourceOutboundMessagingCampaign()) - l.RegisterExporter("genesyscloud_outbound_messagingcampaign", OutboundMessagingcampaignExporter()) } diff --git a/genesyscloud/outbound/resource_genesyscloud_outbound_init_test.go b/genesyscloud/outbound/resource_genesyscloud_outbound_init_test.go index b72b52e53..4478a6fb8 100644 --- a/genesyscloud/outbound/resource_genesyscloud_outbound_init_test.go +++ b/genesyscloud/outbound/resource_genesyscloud_outbound_init_test.go @@ -10,6 +10,7 @@ import ( obContactList "terraform-provider-genesyscloud/genesyscloud/outbound_contact_list" obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" obDnclist "terraform-provider-genesyscloud/genesyscloud/outbound_dnclist" + outboundMessagingcampaign "terraform-provider-genesyscloud/genesyscloud/outbound_messagingcampaign" obRuleset "terraform-provider-genesyscloud/genesyscloud/outbound_ruleset" outboundSequence "terraform-provider-genesyscloud/genesyscloud/outbound_sequence" routingQueue "terraform-provider-genesyscloud/genesyscloud/routing_queue" @@ -37,7 +38,7 @@ func (r *registerTestInstance) registerTestResources() { providerResources["genesyscloud_outbound_attempt_limit"] = obAttemptLimit.ResourceOutboundAttemptLimit() providerResources["genesyscloud_outbound_contactlistfilter"] = obContactListFilter.ResourceOutboundContactlistfilter() providerResources["genesyscloud_outbound_contact_list"] = obContactList.ResourceOutboundContactList() - providerResources["genesyscloud_outbound_messagingcampaign"] = ResourceOutboundMessagingCampaign() + providerResources["genesyscloud_outbound_messagingcampaign"] = outboundMessagingcampaign.ResourceOutboundMessagingcampaign() providerResources["genesyscloud_outbound_sequence"] = outboundSequence.ResourceOutboundSequence() // external package dependencies for outbound @@ -59,7 +60,7 @@ func (r *registerTestInstance) registerTestDataSources() { providerDataSources["genesyscloud_outbound_attempt_limit"] = obAttemptLimit.DataSourceOutboundAttemptLimit() providerDataSources["genesyscloud_outbound_campaignrule"] = outboundCampaignrule.DataSourceOutboundCampaignrule() providerDataSources["genesyscloud_outbound_contact_list"] = obContactList.DataSourceOutboundContactList() - providerDataSources["genesyscloud_outbound_messagingcampaign"] = dataSourceOutboundMessagingcampaign() + providerDataSources["genesyscloud_outbound_messagingcampaign"] = outboundMessagingcampaign.DataSourceOutboundMessagingcampaign() providerDataSources["genesyscloud_outbound_contactlistfilter"] = obContactListFilter.DataSourceOutboundContactlistfilter() providerDataSources["genesyscloud_outbound_sequence"] = outboundSequence.DataSourceOutboundSequence() diff --git a/genesyscloud/outbound/resource_genesyscloud_outbound_messagingcampaign.go b/genesyscloud/outbound/resource_genesyscloud_outbound_messagingcampaign.go deleted file mode 100644 index 1c1a11c11..000000000 --- a/genesyscloud/outbound/resource_genesyscloud_outbound_messagingcampaign.go +++ /dev/null @@ -1,545 +0,0 @@ -package outbound - -import ( - "context" - "errors" - "fmt" - "log" - "terraform-provider-genesyscloud/genesyscloud/provider" - "terraform-provider-genesyscloud/genesyscloud/util" - "terraform-provider-genesyscloud/genesyscloud/util/constants" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" - - "terraform-provider-genesyscloud/genesyscloud/consistency_checker" - - resourceExporter "terraform-provider-genesyscloud/genesyscloud/resource_exporter" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" -) - -const ( - resourceName = "genesyscloud_outbound_messagingcampaign" -) - -var ( - OutboundmessagingcampaigncontactsortResource = &schema.Resource{ - Schema: map[string]*schema.Schema{ - `field_name`: { - Description: `The field name by which to sort contacts.`, - Required: true, - Type: schema.TypeString, - }, - `direction`: { - Description: `The direction in which to sort contacts.`, - Optional: true, - Type: schema.TypeString, - ValidateFunc: validation.StringInSlice([]string{`ASC`, `DESC`}, false), - Default: `ASC`, - }, - `numeric`: { - Description: `Whether or not the column contains numeric data.`, - Optional: true, - Type: schema.TypeBool, - Default: false, - }, - }, - } - - outboundmessagingcampaignsmsconfigResource = &schema.Resource{ - Schema: map[string]*schema.Schema{ - `message_column`: { - Description: `The Contact List column specifying the message to send to the contact. Either message_column or content_template_id is required.`, - Optional: true, - Type: schema.TypeString, - }, - `phone_column`: { - Description: `The Contact List column specifying the phone number to send a message to.`, - Required: true, - Type: schema.TypeString, - }, - `sender_sms_phone_number`: { - Description: `A phone number provisioned for SMS communications in E.164 format. E.g. +13175555555 or +34234234234`, - Required: true, - Type: schema.TypeString, - }, - `content_template_id`: { - Description: `The content template used to formulate the message to send to the contact. Either message_column or content_template_id is required.`, - Optional: true, - Type: schema.TypeString, - }, - }, - } -) - -func ResourceOutboundMessagingCampaign() *schema.Resource { - return &schema.Resource{ - Description: `Genesys Cloud Outbound Messaging Campaign`, - - CreateContext: provider.CreateWithPooledClient(createOutboundMessagingcampaign), - ReadContext: provider.ReadWithPooledClient(readOutboundMessagingcampaign), - UpdateContext: provider.UpdateWithPooledClient(updateOutboundMessagingcampaign), - DeleteContext: provider.DeleteWithPooledClient(deleteOutboundMessagingcampaign), - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - SchemaVersion: 1, - Schema: map[string]*schema.Schema{ - `name`: { - Description: `The campaign name.`, - Required: true, - Type: schema.TypeString, - }, - `division_id`: { - Description: `The division this entity belongs to.`, - Optional: true, - Computed: true, - Type: schema.TypeString, - }, - `callable_time_set_id`: { - Description: `The callable time set for this messaging campaign.`, - Optional: true, - Type: schema.TypeString, - }, - `contact_list_id`: { - Description: `The contact list that this messaging campaign will send messages for.`, - Required: true, - Type: schema.TypeString, - }, - `dnc_list_ids`: { - Description: `The dnc lists to check before sending a message for this messaging campaign.`, - Optional: true, - Type: schema.TypeList, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - `campaign_status`: { - Description: `The current status of the messaging campaign. A messaging campaign may be turned 'on' or 'off'.`, - Optional: true, - Computed: true, - Type: schema.TypeString, - ValidateFunc: validation.StringInSlice([]string{`on`, `off`}, false), - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - if old == `complete` && new == `on` { - return true - } - if old == `invalid` && new == `on` { - return true - } - if old == `stopping` && new == `off` { - return true - } - return false - }, - }, - `always_running`: { - Description: `Whether this messaging campaign is always running`, - Optional: true, - Default: false, - Type: schema.TypeBool, - }, - `contact_sorts`: { - Description: `The order in which to sort contacts for dialing, based on up to four columns.`, - Optional: true, - Type: schema.TypeList, - Elem: OutboundmessagingcampaigncontactsortResource, - }, - `messages_per_minute`: { - Description: `How many messages this messaging campaign will send per minute.`, - Required: true, - Type: schema.TypeInt, - }, - `contact_list_filter_ids`: { - Description: `The contact list filter to check before sending a message for this messaging campaign.`, - Optional: true, - Type: schema.TypeList, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - `sms_config`: { - Description: `Configuration for this messaging campaign to send SMS messages.`, - Required: true, - MaxItems: 1, - Type: schema.TypeSet, - Elem: outboundmessagingcampaignsmsconfigResource, - }, - }, - } -} - -func getAllOutboundMessagingcampaign(_ context.Context, clientConfig *platformclientv2.Configuration) (resourceExporter.ResourceIDMetaMap, diag.Diagnostics) { - resources := make(resourceExporter.ResourceIDMetaMap) - outboundApi := platformclientv2.NewOutboundApiWithConfig(clientConfig) - - for pageNum := 1; ; pageNum++ { - const pageSize = 100 - sdkMessagingcampaignEntityListing, resp, getErr := outboundApi.GetOutboundMessagingcampaigns(pageSize, pageNum, "", "", "", "", []string{}, "", "", []string{}) - if getErr != nil { - return nil, util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Error requesting page of Outbound Messagingcampaign error: %s", getErr), resp) - } - - if sdkMessagingcampaignEntityListing.Entities == nil || len(*sdkMessagingcampaignEntityListing.Entities) == 0 { - break - } - - for _, entity := range *sdkMessagingcampaignEntityListing.Entities { - resources[*entity.Id] = &resourceExporter.ResourceMeta{Name: *entity.Name} - } - } - - return resources, nil -} - -func OutboundMessagingcampaignExporter() *resourceExporter.ResourceExporter { - return &resourceExporter.ResourceExporter{ - GetResourcesFunc: provider.GetAllWithPooledClient(getAllOutboundMessagingcampaign), - RefAttrs: map[string]*resourceExporter.RefAttrSettings{ - `division_id`: {RefType: "genesyscloud_auth_division"}, - `contact_list_id`: {RefType: "genesyscloud_outbound_contact_list"}, - `contact_list_filter_ids`: {RefType: "genesyscloud_outbound_contactlistfilter"}, - `dnc_list_ids`: {RefType: "genesyscloud_outbound_dnclist"}, - `callable_time_set_id`: {RefType: "genesyscloud_outbound_callabletimeset"}, - // /api/v2/responsemanagement/responses/{responseId} - `sms_config.content_template_id`: {}, - }, - } -} - -func createOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - name := d.Get("name").(string) - alwaysRunning := d.Get("always_running").(bool) - messagesPerMinute := d.Get("messages_per_minute").(int) - campaignStatus := d.Get("campaign_status").(string) - - sdkConfig := meta.(*provider.ProviderMeta).ClientConfig - outboundApi := platformclientv2.NewOutboundApiWithConfig(sdkConfig) - - sdkmessagingcampaign := platformclientv2.Messagingcampaign{ - Division: util.BuildSdkDomainEntityRef(d, "division_id"), - CallableTimeSet: util.BuildSdkDomainEntityRef(d, "callable_time_set_id"), - ContactList: util.BuildSdkDomainEntityRef(d, "contact_list_id"), - DncLists: util.BuildSdkDomainEntityRefArr(d, "dnc_list_ids"), - AlwaysRunning: &alwaysRunning, - ContactSorts: buildSdkoutboundmessagingcampaignContactsortSlice(d.Get("contact_sorts").([]interface{})), - MessagesPerMinute: &messagesPerMinute, - ContactListFilters: util.BuildSdkDomainEntityRefArr(d, "contact_list_filter_ids"), - SmsConfig: buildSdkoutboundmessagingcampaignSmsconfig(d.Get("sms_config").(*schema.Set)), - } - - if name != "" { - sdkmessagingcampaign.Name = &name - } - - if campaignStatus != "" { - sdkmessagingcampaign.CampaignStatus = &campaignStatus - } - - msg, valid := validateSmsconfig(d.Get("sms_config").(*schema.Set)) - - if !valid { - return util.BuildDiagnosticError(resourceName, "Configuration error", errors.New(msg)) - } - - log.Printf("Creating Outbound Messagingcampaign %s", name) - outboundMessagingcampaign, resp, err := outboundApi.PostOutboundMessagingcampaigns(sdkmessagingcampaign) - if err != nil { - return util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Failed to create outbound messagingcampaign %s error: %s", name, err), resp) - } - - d.SetId(*outboundMessagingcampaign.Id) - - log.Printf("Created Outbound Messagingcampaign %s %s", name, *outboundMessagingcampaign.Id) - return readOutboundMessagingcampaign(ctx, d, meta) -} - -func updateOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - name := d.Get("name").(string) - alwaysRunning := d.Get("always_running").(bool) - messagesPerMinute := d.Get("messages_per_minute").(int) - campaignStatus := d.Get("campaign_status").(string) - - sdkConfig := meta.(*provider.ProviderMeta).ClientConfig - outboundApi := platformclientv2.NewOutboundApiWithConfig(sdkConfig) - - sdkmessagingcampaign := platformclientv2.Messagingcampaign{ - Division: util.BuildSdkDomainEntityRef(d, "division_id"), - CallableTimeSet: util.BuildSdkDomainEntityRef(d, "callable_time_set_id"), - ContactList: util.BuildSdkDomainEntityRef(d, "contact_list_id"), - DncLists: util.BuildSdkDomainEntityRefArr(d, "dnc_list_ids"), - AlwaysRunning: &alwaysRunning, - ContactSorts: buildSdkoutboundmessagingcampaignContactsortSlice(d.Get("contact_sorts").([]interface{})), - MessagesPerMinute: &messagesPerMinute, - ContactListFilters: util.BuildSdkDomainEntityRefArr(d, "contact_list_filter_ids"), - SmsConfig: buildSdkoutboundmessagingcampaignSmsconfig(d.Get("sms_config").(*schema.Set)), - } - - if name != "" { - sdkmessagingcampaign.Name = &name - } - - if campaignStatus != "" { - sdkmessagingcampaign.CampaignStatus = &campaignStatus - } - - msg, valid := validateSmsconfig(d.Get("sms_config").(*schema.Set)) - - if !valid { - return util.BuildDiagnosticError(resourceName, "Configuration error", errors.New(msg)) - } - - log.Printf("Updating Outbound Messagingcampaign %s", name) - diagErr := util.RetryWhen(util.IsVersionMismatch, func() (*platformclientv2.APIResponse, diag.Diagnostics) { - // Get current Outbound Messagingcampaign version - outboundMessagingcampaign, resp, getErr := outboundApi.GetOutboundMessagingcampaign(d.Id()) - if getErr != nil { - return resp, util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Failed to read Outbound Messagingcampaign %s error: %s", name, getErr), resp) - } - sdkmessagingcampaign.Version = outboundMessagingcampaign.Version - outboundMessagingcampaign, resp, updateErr := outboundApi.PutOutboundMessagingcampaign(d.Id(), sdkmessagingcampaign) - if updateErr != nil { - return resp, util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Failed to update Outbound Messagingcampaign %s error: %s", name, updateErr), resp) - } - return nil, nil - }) - if diagErr != nil { - return diagErr - } - - log.Printf("Updated Outbound Messagingcampaign %s", name) - return readOutboundMessagingcampaign(ctx, d, meta) -} - -func readOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - sdkConfig := meta.(*provider.ProviderMeta).ClientConfig - outboundApi := platformclientv2.NewOutboundApiWithConfig(sdkConfig) - cc := consistency_checker.NewConsistencyCheck(ctx, d, meta, ResourceOutboundMessagingCampaign(), constants.DefaultConsistencyChecks, resourceName) - - log.Printf("Reading Outbound Messagingcampaign %s", d.Id()) - - return util.WithRetriesForRead(ctx, d, func() *retry.RetryError { - sdkmessagingcampaign, resp, getErr := outboundApi.GetOutboundMessagingcampaign(d.Id()) - if getErr != nil { - if util.IsStatus404(resp) { - return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Failed to read Outbound Messagingcampaign %s | error: %s", d.Id(), getErr), resp)) - } - return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Failed to read Outbound Messagingcampaign %s | error: %s", d.Id(), getErr), resp)) - } - - if sdkmessagingcampaign.Name != nil { - d.Set("name", *sdkmessagingcampaign.Name) - } - if sdkmessagingcampaign.Division != nil && sdkmessagingcampaign.Division.Id != nil { - d.Set("division_id", *sdkmessagingcampaign.Division.Id) - } - if sdkmessagingcampaign.CallableTimeSet != nil && sdkmessagingcampaign.CallableTimeSet.Id != nil { - d.Set("callable_time_set_id", *sdkmessagingcampaign.CallableTimeSet.Id) - } - if sdkmessagingcampaign.ContactList != nil && sdkmessagingcampaign.ContactList.Id != nil { - d.Set("contact_list_id", *sdkmessagingcampaign.ContactList.Id) - } - if sdkmessagingcampaign.CampaignStatus != nil { - d.Set("campaign_status", *sdkmessagingcampaign.CampaignStatus) - } - if sdkmessagingcampaign.DncLists != nil { - var dncListIds []string - for _, dnc := range *sdkmessagingcampaign.DncLists { - dncListIds = append(dncListIds, *dnc.Id) - } - d.Set("dnc_list_ids", dncListIds) - } - if sdkmessagingcampaign.AlwaysRunning != nil { - d.Set("always_running", *sdkmessagingcampaign.AlwaysRunning) - } - if sdkmessagingcampaign.ContactSorts != nil { - d.Set("contact_sorts", flattenSdkOutboundMessagingCampaignContactsortSlice(*sdkmessagingcampaign.ContactSorts)) - } - if sdkmessagingcampaign.MessagesPerMinute != nil { - d.Set("messages_per_minute", *sdkmessagingcampaign.MessagesPerMinute) - } - if sdkmessagingcampaign.ContactListFilters != nil { - var contactListFilterIds []string - for _, clf := range *sdkmessagingcampaign.ContactListFilters { - contactListFilterIds = append(contactListFilterIds, *clf.Id) - } - d.Set("contact_list_filter_ids", contactListFilterIds) - } - if sdkmessagingcampaign.SmsConfig != nil { - d.Set("sms_config", flattenSdkOutboundMessagingCampaignSmsconfig(sdkmessagingcampaign.SmsConfig)) - } - - log.Printf("Read Outbound Messagingcampaign %s %s", d.Id(), *sdkmessagingcampaign.Name) - return cc.CheckState(d) - }) -} - -func deleteOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { - sdkConfig := meta.(*provider.ProviderMeta).ClientConfig - outboundApi := platformclientv2.NewOutboundApiWithConfig(sdkConfig) - - diagErr := util.RetryWhen(util.IsStatus400, func() (*platformclientv2.APIResponse, diag.Diagnostics) { - log.Printf("Deleting Outbound Messagingcampaign") - _, resp, err := outboundApi.DeleteOutboundMessagingcampaign(d.Id()) - if err != nil { - return resp, util.BuildAPIDiagnosticError(resourceName, fmt.Sprintf("Failed to delete outbound Messagingcampaign %s error: %s", d.Id(), err), resp) - } - return resp, nil - }) - if diagErr != nil { - return diagErr - } - - return util.WithRetries(ctx, 30*time.Second, func() *retry.RetryError { - _, resp, err := outboundApi.GetOutboundMessagingcampaign(d.Id()) - if err != nil { - if util.IsStatus404(resp) { - // Outbound Messagingcampaign deleted - log.Printf("Deleted Outbound Messagingcampaign %s", d.Id()) - return nil - } - return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Error deleting Outbound Messagingcampaign %s | error: %s", d.Id(), err), resp)) - } - - return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Outbound Messagingcampaign %s still exists", d.Id()), resp)) - }) -} - -func buildSdkoutboundmessagingcampaignContactsortSlice(contactSort []interface{}) *[]platformclientv2.Contactsort { - if contactSort == nil { - return nil - } - sdkContactSortSlice := make([]platformclientv2.Contactsort, 0) - for _, configContactSort := range contactSort { - var sdkContactSort platformclientv2.Contactsort - contactsortMap := configContactSort.(map[string]interface{}) - if fieldName := contactsortMap["field_name"].(string); fieldName != "" { - sdkContactSort.FieldName = &fieldName - } - if direction := contactsortMap["direction"].(string); direction != "" { - sdkContactSort.Direction = &direction - } - if numeric, ok := contactsortMap["numeric"].(bool); ok { - sdkContactSort.Numeric = platformclientv2.Bool(numeric) - } - - sdkContactSortSlice = append(sdkContactSortSlice, sdkContactSort) - } - return &sdkContactSortSlice -} - -func buildSdkoutboundmessagingcampaignSmsconfig(smsconfig *schema.Set) *platformclientv2.Smsconfig { - if smsconfig == nil { - return nil - } - var sdkSmsconfig platformclientv2.Smsconfig - smsconfigList := smsconfig.List() - if len(smsconfigList) > 0 { - smsconfigMap := smsconfigList[0].(map[string]interface{}) - if messageColumn := smsconfigMap["message_column"].(string); messageColumn != "" { - sdkSmsconfig.MessageColumn = &messageColumn - } - if phoneColumn := smsconfigMap["phone_column"].(string); phoneColumn != "" { - sdkSmsconfig.PhoneColumn = &phoneColumn - } - if senderSmsPhoneNumber := smsconfigMap["sender_sms_phone_number"].(string); senderSmsPhoneNumber != "" { - sdkSmsconfig.SenderSmsPhoneNumber = &platformclientv2.Smsphonenumberref{ - PhoneNumber: &senderSmsPhoneNumber, - } - } - if contentTemplateId := smsconfigMap["content_template_id"].(string); contentTemplateId != "" { - sdkSmsconfig.ContentTemplate = &platformclientv2.Domainentityref{Id: &contentTemplateId} - } - } - - return &sdkSmsconfig -} - -func flattenSdkOutboundMessagingCampaignContactsortSlice(contactSorts []platformclientv2.Contactsort) []interface{} { - if len(contactSorts) == 0 { - return nil - } - - contactSortList := make([]interface{}, 0) - for _, contactsort := range contactSorts { - contactSortMap := make(map[string]interface{}) - - if contactsort.FieldName != nil { - contactSortMap["field_name"] = *contactsort.FieldName - } - if contactsort.Direction != nil { - contactSortMap["direction"] = *contactsort.Direction - } - if contactsort.Numeric != nil { - contactSortMap["numeric"] = *contactsort.Numeric - } - - contactSortList = append(contactSortList, contactSortMap) - } - - return contactSortList -} - -func flattenSdkOutboundMessagingCampaignSmsconfig(smsconfig *platformclientv2.Smsconfig) *schema.Set { - if smsconfig == nil { - return nil - } - - smsconfigSet := schema.NewSet(schema.HashResource(outboundmessagingcampaignsmsconfigResource), []interface{}{}) - smsconfigMap := make(map[string]interface{}) - - if smsconfig.MessageColumn != nil { - smsconfigMap["message_column"] = *smsconfig.MessageColumn - } - if smsconfig.PhoneColumn != nil { - smsconfigMap["phone_column"] = *smsconfig.PhoneColumn - } - if smsconfig.SenderSmsPhoneNumber != nil { - if smsconfig.SenderSmsPhoneNumber.PhoneNumber != nil { - smsconfigMap["sender_sms_phone_number"] = *smsconfig.SenderSmsPhoneNumber.PhoneNumber - } - } - if smsconfig.ContentTemplate != nil { - smsconfigMap["content_template_id"] = *smsconfig.ContentTemplate.Id - } - - smsconfigSet.Add(smsconfigMap) - - return smsconfigSet -} - -func GenerateOutboundMessagingCampaignContactSort(fieldName string, direction string, numeric string) string { - if direction != "" { - direction = fmt.Sprintf(`direction = "%s"`, direction) - } - if numeric != "" { - numeric = fmt.Sprintf(`numeric = %s`, numeric) - } - return fmt.Sprintf(` - contact_sorts { - field_name = "%s" - %s - %s - } -`, fieldName, direction, numeric) -} - -func validateSmsconfig(smsconfig *schema.Set) (string, bool) { - if smsconfig == nil { - return "", true - } - - smsconfigList := smsconfig.List() - if len(smsconfigList) > 0 { - smsconfigMap := smsconfigList[0].(map[string]interface{}) - messageColumn, _ := smsconfigMap["message_column"].(string) - contentTemplateId, _ := smsconfigMap["content_template_id"].(string) - if messageColumn == "" && contentTemplateId == "" { - return "Either message_column or content_template_id is required.", false - } else if messageColumn != "" && contentTemplateId != "" { - return "Only one of message_column or content_template_id can be defined", false - } - } - - return "", true -} diff --git a/genesyscloud/outbound/resource_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound/resource_genesyscloud_outbound_messagingcampaign_test.go deleted file mode 100644 index 7f4e83de3..000000000 --- a/genesyscloud/outbound/resource_genesyscloud_outbound_messagingcampaign_test.go +++ /dev/null @@ -1,426 +0,0 @@ -package outbound - -import ( - "fmt" - "net/http" - "strconv" - "strings" - obDnclist "terraform-provider-genesyscloud/genesyscloud/outbound_dnclist" - "terraform-provider-genesyscloud/genesyscloud/provider" - "terraform-provider-genesyscloud/genesyscloud/util" - "testing" - "time" - - "github.com/google/uuid" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" - - obCallableTimeset "terraform-provider-genesyscloud/genesyscloud/outbound_callabletimeset" - obContactList "terraform-provider-genesyscloud/genesyscloud/outbound_contact_list" - obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" -) - -/* -This test can only pass in a test org because it requires an active provisioned sms phone number -Endpoint `POST /api/v2/routing/sms/phonenumbers` creates an active/valid phone number in test orgs only. -*/ -func TestAccResourceOutboundMessagingCampaign(t *testing.T) { - - t.Parallel() - var ( - // Contact list - contactListResourceId = "contact_list" - contactListName = "Contact List " + uuid.NewString() - column1 = "phone" - column2 = "zipcode" - contactListResource = obContactList.GenerateOutboundContactList( - contactListResourceId, - contactListName, - util.NullValue, - util.NullValue, - []string{}, - []string{strconv.Quote(column1), strconv.Quote(column2)}, - util.NullValue, - util.NullValue, - util.NullValue, - obContactList.GeneratePhoneColumnsBlock( - column1, - "cell", - strconv.Quote(column1), - ), - ) - - // Messaging Campaign - resourceId = "messaging_campaign" - name = "Test Messaging Campaign " + uuid.NewString() - messagesPerMin = "10" - alwaysRunning = util.FalseValue - smsConfigMessageColumn = column1 - smsConfigPhoneColumn = column1 - smsConfigSenderSMSPhoneNumber = "+19198793429" - - // Messaging Campaign Updated fields - nameUpdate = "Test Messaging Campaign " + uuid.NewString() - messagesPerMinUpdate = "15" - alwaysRunningUpdate = TrueValue - - // DNC List - dncListResourceId = "dnc_list" - dncListName = "Test DNC List " + uuid.NewString() - dncListResource = obDnclist.GenerateOutboundDncListBasic( - dncListResourceId, - dncListName, - ) - - // Contact List Filter - clfResourceId = "contact_list_filter" - clfName = "Contact List Filter " + uuid.NewString() - contactListFilterResource = obContactListFilter.GenerateOutboundContactListFilter( - clfResourceId, - clfName, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "", - obContactListFilter.GenerateOutboundContactListFilterClause( - "", - obContactListFilter.GenerateOutboundContactListFilterPredicates( - column1, - "alphabetic", - "EQUALS", - "XYZ", - "", - "", - ), - ), - ) - - callableTimeSetResourceId = "callable_time_set" - callableTimeSetName = "Test CTS " + uuid.NewString() - callableTimeSetResource = obCallableTimeset.GenerateOutboundCallabletimeset( - callableTimeSetResourceId, - callableTimeSetName, - obCallableTimeset.GenerateCallableTimesBlock( - "Europe/Dublin", - obCallableTimeset.GenerateTimeSlotsBlock("07:00:00", "18:00:00", "3"), - obCallableTimeset.GenerateTimeSlotsBlock("09:30:00", "22:30:00", "5"), - ), - ) - ) - - config, err := provider.AuthorizeSdk() - if err != nil { - t.Errorf("failed to authorize client: %v", err) - } - api := platformclientv2.NewRoutingApiWithConfig(config) - err = createRoutingSmsPhoneNumber(smsConfigSenderSMSPhoneNumber, api) - if err != nil { - t.Errorf("error creating sms phone number %s: %v", smsConfigSenderSMSPhoneNumber, err) - } - defer func() { - _, err := api.DeleteRoutingSmsPhonenumber(smsConfigSenderSMSPhoneNumber) - if err != nil { - t.Logf("error deleting phone number %s: %v", smsConfigSenderSMSPhoneNumber, err) - } - }() - - resource.Test(t, resource.TestCase{ - PreCheck: func() { util.TestAccPreCheck(t) }, - ProviderFactories: provider.GetProviderFactories(providerResources, providerDataSources), - Steps: []resource.TestStep{ - { - Config: dncListResource + - contactListResource + - contactListFilterResource + - callableTimeSetResource + - generateOutboundMessagingCampaignResource( - resourceId, - name, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "off", - messagesPerMin, - alwaysRunning, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn, - smsConfigPhoneColumn, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "", - "", - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "DESC", - TrueValue, - ), - ), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", name), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMin), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "always_running", alwaysRunning), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "campaign_status", "off"), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.message_column", smsConfigMessageColumn), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.phone_column", smsConfigPhoneColumn), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.sender_sms_phone_number", smsConfigSenderSMSPhoneNumber), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.field_name", column1), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.direction", "ASC"), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.numeric", util.FalseValue), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.field_name", column2), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "DESC"), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", TrueValue), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "dnc_list_ids.0", - "genesyscloud_outbound_dnclist."+dncListResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_filter_ids.0", - "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", - "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), - provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), - ), - }, - { - Config: dncListResource + - contactListResource + - contactListFilterResource + - callableTimeSetResource + - generateOutboundMessagingCampaignResource( - resourceId, - name, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "on", - messagesPerMin, - alwaysRunning, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn, - smsConfigPhoneColumn, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "", - "", - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "DESC", - TrueValue, - ), - ), - Check: resource.ComposeTestCheckFunc( - // Check that the DiffSuppressFunc is working - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", name), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMin), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "always_running", alwaysRunning), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.message_column", smsConfigMessageColumn), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.phone_column", smsConfigPhoneColumn), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.sender_sms_phone_number", smsConfigSenderSMSPhoneNumber), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.field_name", column1), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.direction", "ASC"), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.numeric", util.FalseValue), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.field_name", column2), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "DESC"), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", TrueValue), - util.VerifyAttributeInArrayOfPotentialValues("genesyscloud_outbound_messagingcampaign."+resourceId, "campaign_status", []string{"on", "complete"}), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "dnc_list_ids.0", - "genesyscloud_outbound_dnclist."+dncListResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_filter_ids.0", - "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", - "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), - provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), - ), - }, - { - // Update - Config: dncListResource + - contactListResource + - contactListFilterResource + - callableTimeSetResource + - generateOutboundMessagingCampaignResource( - resourceId, - nameUpdate, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "on", - messagesPerMinUpdate, - alwaysRunningUpdate, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn, - smsConfigPhoneColumn, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "DESC", - TrueValue, - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "", - "", - ), - ), - Check: resource.ComposeTestCheckFunc( - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", nameUpdate), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMinUpdate), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "always_running", alwaysRunningUpdate), - util.VerifyAttributeInArrayOfPotentialValues("genesyscloud_outbound_messagingcampaign."+resourceId, "campaign_status", []string{"on", "complete"}), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.message_column", smsConfigMessageColumn), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.phone_column", smsConfigPhoneColumn), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "sms_config.0.sender_sms_phone_number", smsConfigSenderSMSPhoneNumber), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.field_name", column1), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.direction", "DESC"), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.0.numeric", TrueValue), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.field_name", column2), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "ASC"), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", util.FalseValue), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_filter_ids.0", - "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", - "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), - provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), - ), - }, - { - ResourceName: "genesyscloud_outbound_messagingcampaign." + resourceId, - ImportState: true, - ImportStateVerify: true, - }, - }, - CheckDestroy: testVerifyOutboundMessagingCampaignDestroyed, - }) -} - -func createRoutingSmsPhoneNumber(inputSmsPhoneNumber string, api *platformclientv2.RoutingApi) error { - var ( - phoneNumberType = "local" - countryCode = "US" - status string - maxRetries = 10 - ) - _, resp, err := api.GetRoutingSmsPhonenumber(inputSmsPhoneNumber, "compliance") - if resp.StatusCode == 200 { - // Number already exists - return nil - } else if resp.StatusCode == http.StatusNotFound { - body := platformclientv2.Smsphonenumberprovision{ - PhoneNumber: &inputSmsPhoneNumber, - PhoneNumberType: &phoneNumberType, - CountryCode: &countryCode, - } - // POST /api/v2/routing/sms/phonenumbers - address, _, err := api.PostRoutingSmsPhonenumbers(body) - if err != nil { - return err - } - // Ensure status transitions to complete before proceeding - for i := 0; i <= maxRetries; i++ { - time.Sleep(3 * time.Second) - // GET /api/v2/routing/sms/phonenumbers/{addressId} - sdkSmsPhoneNumber, _, err := api.GetRoutingSmsPhonenumber(*address.PhoneNumber, "compliance") - if err != nil { - return err - } - status = *sdkSmsPhoneNumber.ProvisioningStatus.State - if status == "Running" { - if i == maxRetries { - return fmt.Errorf(`sms phone number status did not transition to "Completed" within max retries %v`, maxRetries) - } - continue - } - break - } - if status == "Failed" { - return fmt.Errorf(`sms phone number provisioning failed`) - } - } else if err != nil { - return fmt.Errorf("error checking for sms phone number %v: %v", inputSmsPhoneNumber, err) - } - return nil -} - -func generateOutboundMessagingCampaignResource( - resourceId string, - name string, - contactListId string, - campaignStatus string, - messagesPerMinute string, - alwaysRunning string, - callableTimeSetId string, - dncListIds []string, - contactListFilterIds []string, - nestedBlocks ...string, -) string { - if callableTimeSetId != "" { - callableTimeSetId = fmt.Sprintf(`callable_time_set_id = %s`, callableTimeSetId) - } - if alwaysRunning != "" { - alwaysRunning = fmt.Sprintf(`always_running = %s`, alwaysRunning) - } - if campaignStatus != "" { - campaignStatus = fmt.Sprintf(`campaign_status = "%s"`, campaignStatus) - } - return fmt.Sprintf(` -resource "genesyscloud_outbound_messagingcampaign" "%s" { - name = "%s" - contact_list_id = %s - %s - messages_per_minute = %s - %s - %s - dnc_list_ids = [%s] - contact_list_filter_ids = [%s] - %s -} -`, resourceId, name, contactListId, campaignStatus, messagesPerMinute, alwaysRunning, callableTimeSetId, - strings.Join(dncListIds, ", "), strings.Join(contactListFilterIds, ", "), strings.Join(nestedBlocks, "\n")) -} - -func generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn string, - smsConfigPhoneColumn string, - smsConfigSenderSMSPhoneNumber string, -) string { - return fmt.Sprintf(` - sms_config { - message_column = "%s" - phone_column = "%s" - sender_sms_phone_number = "%s" - } -`, smsConfigMessageColumn, smsConfigPhoneColumn, smsConfigSenderSMSPhoneNumber) -} - -func testVerifyOutboundMessagingCampaignDestroyed(state *terraform.State) error { - outboundAPI := platformclientv2.NewOutboundApi() - for _, rs := range state.RootModule().Resources { - if rs.Type != "genesyscloud_outbound_messagingcampaign" { - continue - } - campaign, resp, err := outboundAPI.GetOutboundMessagingcampaign(rs.Primary.ID) - if campaign != nil { - return fmt.Errorf("messaging campaign (%s) still exists", rs.Primary.ID) - } else if util.IsStatus404(resp) { - // Messaging Campaign not found as expected - continue - } else { - // Unexpected error - return fmt.Errorf("unexpected error: %s", err) - } - } - // Success. All messaging campaigns destroyed - return nil -} diff --git a/genesyscloud/outbound_campaign/resource_genesyscloud_outbound_campaign_schema.go b/genesyscloud/outbound_campaign/resource_genesyscloud_outbound_campaign_schema.go index 7462f78c1..4a798f51f 100644 --- a/genesyscloud/outbound_campaign/resource_genesyscloud_outbound_campaign_schema.go +++ b/genesyscloud/outbound_campaign/resource_genesyscloud_outbound_campaign_schema.go @@ -1,12 +1,13 @@ package outbound_campaign import ( - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - "terraform-provider-genesyscloud/genesyscloud/outbound" + outboundMessagingcampaign "terraform-provider-genesyscloud/genesyscloud/outbound_messagingcampaign" "terraform-provider-genesyscloud/genesyscloud/provider" resourceExporter "terraform-provider-genesyscloud/genesyscloud/resource_exporter" registrar "terraform-provider-genesyscloud/genesyscloud/resource_register" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" ) /* @@ -169,7 +170,7 @@ func ResourceOutboundCampaign() *schema.Resource { Description: `The order in which to sort contacts for dialing, based on up to four columns.`, Optional: true, Type: schema.TypeList, - Elem: outbound.OutboundmessagingcampaigncontactsortResource, + Elem: outboundMessagingcampaign.ContactSortResource, }, `no_answer_timeout`: { Description: `How long to wait before dispositioning a call as 'no-answer'. Default 30 seconds. Only applicable to non-preview campaigns.`, diff --git a/genesyscloud/outbound_campaign/resource_genesyscloud_outbound_campaign_test.go b/genesyscloud/outbound_campaign/resource_genesyscloud_outbound_campaign_test.go index 55a7c5004..452975ba8 100644 --- a/genesyscloud/outbound_campaign/resource_genesyscloud_outbound_campaign_test.go +++ b/genesyscloud/outbound_campaign/resource_genesyscloud_outbound_campaign_test.go @@ -6,8 +6,8 @@ import ( "strconv" "strings" "terraform-provider-genesyscloud/genesyscloud/architect_flow" - "terraform-provider-genesyscloud/genesyscloud/outbound" obDnclist "terraform-provider-genesyscloud/genesyscloud/outbound_dnclist" + outboundMessagingcampaign "terraform-provider-genesyscloud/genesyscloud/outbound_messagingcampaign" "terraform-provider-genesyscloud/genesyscloud/provider" "terraform-provider-genesyscloud/genesyscloud/util" "testing" @@ -216,7 +216,7 @@ func TestAccResourceOutboundCampaignBasic(t *testing.T) { []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, generatePhoneColumnNoTypeBlock("Cell"), - outbound.GenerateOutboundMessagingCampaignContactSort( + outboundMessagingcampaign.GenerateOutboundMessagingCampaignContactSort( contactSortFieldName, contactSortDirection, contactSortNumeric, @@ -285,7 +285,7 @@ func TestAccResourceOutboundCampaignBasic(t *testing.T) { []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, generatePhoneColumnNoTypeBlock("Cell"), - outbound.GenerateOutboundMessagingCampaignContactSort( + outboundMessagingcampaign.GenerateOutboundMessagingCampaignContactSort( contactSortFieldName, contactSortDirection, contactSortNumeric, @@ -354,7 +354,7 @@ func TestAccResourceOutboundCampaignBasic(t *testing.T) { []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, generatePhoneColumnNoTypeBlock("Cell"), - outbound.GenerateOutboundMessagingCampaignContactSort( + outboundMessagingcampaign.GenerateOutboundMessagingCampaignContactSort( contactSortFieldName, contactSortDirection, contactSortNumeric, @@ -831,7 +831,7 @@ func TestAccResourceOutboundCampaignWithScriptId(t *testing.T) { []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, generatePhoneColumnNoTypeBlock("Cell"), - outbound.GenerateOutboundMessagingCampaignContactSort( + outboundMessagingcampaign.GenerateOutboundMessagingCampaignContactSort( contactSortFieldName, contactSortDirection, contactSortNumeric, diff --git a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go index cf5a80a0b..af1710560 100644 --- a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go +++ b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go @@ -7,7 +7,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/mypurecloud/platform-client-sdk-go/v133/platformclientv2" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" @@ -23,28 +22,23 @@ import ( // dataSourceOutboundMessagingcampaignRead retrieves by name the id in question func dataSourceOutboundMessagingcampaignRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { sdkConfig := meta.(*provider.ProviderMeta).ClientConfig - outboundApi := platformclientv2.NewOutboundApiWithConfig(sdkConfig) + outboundApi := getOutboundMessagingcampaignProxy(sdkConfig) name := d.Get("name").(string) return util.WithRetries(ctx, 15*time.Second, func() *retry.RetryError { - for pageNum := 1; ; pageNum++ { - const pageSize = 100 - sdkMessagingcampaignEntityListing, resp, getErr := outboundApi.GetOutboundMessagingcampaigns(pageSize, pageNum, "", "", "", "", []string{}, "", "", []string{}) - if getErr != nil { - return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("error requesting Outbound Messaging Campaign %s | error: %s", name, getErr), resp)) - } - - if sdkMessagingcampaignEntityListing.Entities == nil || len(*sdkMessagingcampaignEntityListing.Entities) == 0 { - return retry.RetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("no Outbound Messaging Campaign found with name %s", name), resp)) - } - - for _, entity := range *sdkMessagingcampaignEntityListing.Entities { - if entity.Name != nil && *entity.Name == name { - d.SetId(*entity.Id) - return nil - } - } + messagingCampaignId, retryable, resp, err := outboundApi.getOutboundMessagingcampaignIdByName(ctx, name) + + if err != nil && !retryable { + return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Error searching outbound messagingcampaign %s: %s", name, err), resp)) } + + if retryable { + return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("No outbound messagingcampaign found with name %s", name), resp)) + + } + + d.SetId(messagingCampaignId) + return nil }) } diff --git a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go index fcf985438..a2c85fb65 100644 --- a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go +++ b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go @@ -114,7 +114,7 @@ func TestAccDataSourceOutboundMessagingCampaign(t *testing.T) { resourceId, digitalCampaignName, "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "", + "off", "10", util.FalseValue, "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", @@ -135,6 +135,7 @@ func TestAccDataSourceOutboundMessagingCampaign(t *testing.T) { "DESC", TrueValue, ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), ) + generateOutboundMessagingCampaignDataSource( dataSourceId, digitalCampaignName, diff --git a/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go b/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go index 44a810db0..0539ada06 100644 --- a/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go +++ b/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go @@ -3,10 +3,10 @@ package outbound_messagingcampaign import ( "sync" obCallableTimeset "terraform-provider-genesyscloud/genesyscloud/outbound_callabletimeset" - outboundContactList "terraform-provider-genesyscloud/genesyscloud/outbound_contact_list" + obContactList "terraform-provider-genesyscloud/genesyscloud/outbound_contact_list" obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" obDnclist "terraform-provider-genesyscloud/genesyscloud/outbound_dnclist" - outboundRuleset "terraform-provider-genesyscloud/genesyscloud/outbound_ruleset" + obRuleset "terraform-provider-genesyscloud/genesyscloud/outbound_ruleset" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -34,12 +34,11 @@ func (r *registerTestInstance) registerTestResources() { defer r.resourceMapMutex.Unlock() providerResources[resourceName] = ResourceOutboundMessagingcampaign() - providerResources["genesyscloud_outbound_contact_list"] = outboundContactList.ResourceOutboundContactList() + providerResources["genesyscloud_outbound_contact_list"] = obContactList.ResourceOutboundContactList() providerResources["genesyscloud_outbound_contactlistfilter"] = obContactListFilter.ResourceOutboundContactlistfilter() - providerResources["genesyscloud_outbound_ruleset"] = outboundRuleset.ResourceOutboundRuleset() + providerResources["genesyscloud_outbound_ruleset"] = obRuleset.ResourceOutboundRuleset() providerResources["genesyscloud_outbound_callabletimeset"] = obCallableTimeset.ResourceOutboundCallabletimeset() providerResources["genesyscloud_outbound_dnclist"] = obDnclist.ResourceOutboundDncList() - } // registerTestDataSources registers all data sources used in the tests. diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go index 3a1869e91..db4fa2ef4 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go @@ -103,8 +103,8 @@ func readOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, } resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "errors", messagingCampaign.Errors, flattenRestErrorDetails) resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "dynamic_contact_queueing_settings", messagingCampaign.DynamicContactQueueingSettings, flattenDynamicContactQueueingSettingss) - resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "email_config", messagingCampaign.EmailConfig, flattenEmailConfigs) - //resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "sms_config", messagingCampaign.SmsConfig, flattenSmsConfigs) + //TODO: add email configs in future + // resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "email_config", messagingCampaign.EmailConfig, flattenEmailConfigs) d.Set("sms_config", flattenSmsConfigs(messagingCampaign.SmsConfig)) log.Printf("Read outbound messagingcampaign %s %s", d.Id(), *messagingCampaign.Name) @@ -143,7 +143,7 @@ func updateOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData return diagErr } - log.Printf("Updated outbound messagingcampaign %s", *outboundMessagingcampaign.Id) + log.Printf("Updated outbound messagingcampaign") return readOutboundMessagingcampaign(ctx, d, meta) } diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go index 73b62ecc0..51837859e 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go @@ -96,7 +96,7 @@ var ( Schema: map[string]*schema.Schema{ `message_column`: { Description: `The Contact List column specifying the message to send to the contact.`, - Required: true, + Optional: true, Type: schema.TypeString, }, `phone_column`: { @@ -116,11 +116,8 @@ var ( }, }, } -) -// ResourceOutboundMessagingcampaign registers the genesyscloud_outbound_messagingcampaign resource with Terraform -func ResourceOutboundMessagingcampaign() *schema.Resource { - contactSortResource := &schema.Resource{ + ContactSortResource = &schema.Resource{ Schema: map[string]*schema.Schema{ `field_name`: { Description: `The field name by which to sort contacts.`, @@ -138,9 +135,14 @@ func ResourceOutboundMessagingcampaign() *schema.Resource { Description: `Whether or not the column contains numeric data.`, Optional: true, Type: schema.TypeBool, + Default: false, }, }, } +) + +// ResourceOutboundMessagingcampaign registers the genesyscloud_outbound_messagingcampaign resource with Terraform +func ResourceOutboundMessagingcampaign() *schema.Resource { restErrorDetailResource := &schema.Resource{ Schema: map[string]*schema.Schema{ @@ -235,7 +237,7 @@ func ResourceOutboundMessagingcampaign() *schema.Resource { Description: `The order in which to sort contacts for dialing, based on up to four columns.`, Optional: true, Type: schema.TypeList, - Elem: contactSortResource, + Elem: ContactSortResource, }, `messages_per_minute`: { Description: `How many messages this messaging campaign will send per minute.`, @@ -291,12 +293,15 @@ func OutboundMessagingcampaignExporter() *resourceExporter.ResourceExporter { GetResourcesFunc: provider.GetAllWithPooledClient(getAllAuthOutboundMessagingcampaigns), RefAttrs: map[string]*resourceExporter.RefAttrSettings{ // TODO: Add any reference attributes here - `division_id`: {RefType: "genesyscloud_auth_division"}, - `contact_list_id`: {RefType: "genesyscloud_outbound_contact_list"}, - `contact_list_filter_ids`: {RefType: "genesyscloud_outbound_contactlistfilter"}, - `rule_sets`: {RefType: "genesyscloud_outbound_ruleset"}, - `dnc_list_ids`: {RefType: "genesyscloud_outbound_dnclist"}, - `callable_time_set_id`: {RefType: "genesyscloud_outbound_callabletimeset"}, + `division_id`: {RefType: "genesyscloud_auth_division"}, + `contact_list_id`: {RefType: "genesyscloud_outbound_contact_list"}, + `contact_list_filter_ids`: {RefType: "genesyscloud_outbound_contactlistfilter"}, + `rule_sets`: {RefType: "genesyscloud_outbound_ruleset"}, + `dnc_list_ids`: {RefType: "genesyscloud_outbound_dnclist"}, + `callable_time_set_id`: {RefType: "genesyscloud_outbound_callabletimeset"}, + `route_id`: {RefType: "genesyscloud_routing_email_route"}, + `email_config.from_address.route_id`: {RefType: "genesyscloud_routing_email_route"}, + `email_config.from_address.domain_id`: {RefType: "genesyscloud_routing_email_domain"}, // /api/v2/responsemanagement/responses/{responseId} `sms_config.content_template_id`: {}, `email_config.content_template_id`: {}, diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go index e1e3760b5..db2cb160a 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go @@ -157,7 +157,7 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { "DESC", TrueValue, ), - generateDynamicContactQueueingSettingsBlock(util.TrueValue), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", name), @@ -173,7 +173,7 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.field_name", column2), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "DESC"), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", TrueValue), - resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "dynamic_contact_queueing_settings.0.sort", TrueValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "dynamic_contact_queueing_settings.0.sort", util.FalseValue), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "dnc_list_ids.0", diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go index bfe94f26d..a921ae232 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go @@ -16,22 +16,24 @@ and unmarshal data into formats consumable by Terraform and/or Genesys Cloud. // getOutboundMessagingcampaignFromResourceData maps data from schema ResourceData object to a platformclientv2.Messagingcampaign func getOutboundMessagingcampaignFromResourceData(d *schema.ResourceData) platformclientv2.Messagingcampaign { + return platformclientv2.Messagingcampaign{ - Name: platformclientv2.String(d.Get("name").(string)), - Division: util.BuildSdkDomainEntityRef(d, "division_id"), - CampaignStatus: platformclientv2.String(d.Get("campaign_status").(string)), - CallableTimeSet: util.BuildSdkDomainEntityRef(d, "callable_time_set_id"), - ContactList: util.BuildSdkDomainEntityRef(d, "contact_list_id"), - DncLists: util.BuildSdkDomainEntityRefArr(d, "dnc_list_ids"), - AlwaysRunning: platformclientv2.Bool(d.Get("always_running").(bool)), - ContactSorts: buildContactSorts(d.Get("contact_sorts").([]interface{})), - MessagesPerMinute: platformclientv2.Int(d.Get("messages_per_minute").(int)), - //RuleSets: util.BuildSdkDomainEntityRefArr(d, "rule_sets"), - ContactListFilters: util.BuildSdkDomainEntityRefArr(d, "contact_list_filter_ids"), - //Errors: buildRestErrorDetails(d.Get("errors").([]interface{})), + Name: platformclientv2.String(d.Get("name").(string)), + Division: util.BuildSdkDomainEntityRef(d, "division_id"), + CampaignStatus: platformclientv2.String(d.Get("campaign_status").(string)), + CallableTimeSet: util.BuildSdkDomainEntityRef(d, "callable_time_set_id"), + ContactList: util.BuildSdkDomainEntityRef(d, "contact_list_id"), + DncLists: util.BuildSdkDomainEntityRefArr(d, "dnc_list_ids"), + AlwaysRunning: platformclientv2.Bool(d.Get("always_running").(bool)), + ContactSorts: buildContactSorts(d.Get("contact_sorts").([]interface{})), + MessagesPerMinute: platformclientv2.Int(d.Get("messages_per_minute").(int)), + RuleSets: util.BuildSdkDomainEntityRefArr(d, "rule_sets"), + ContactListFilters: util.BuildSdkDomainEntityRefArr(d, "contact_list_filter_ids"), + Errors: buildRestErrorDetails(d.Get("errors").([]interface{})), DynamicContactQueueingSettings: buildDynamicContactQueueingSettingss(d.Get("dynamic_contact_queueing_settings").([]interface{})), - //EmailConfig: buildEmailConfigs(d.Get("email_config").(*schema.Set)), - SmsConfig: buildSmsConfigs(d.Get("sms_config").(*schema.Set)), + SmsConfig: buildSmsConfigs(d.Get("sms_config").(*schema.Set)), + //TODO: add email configs in future + // EmailConfig: buildEmailConfigs(d.Get("email_config").(*schema.Set)), } } @@ -285,22 +287,6 @@ func flattenEmailConfigs(emailConfigs *platformclientv2.Emailconfig) []interface return emailConfigList } -// flattenSmsPhoneNumberRefs maps a Genesys Cloud *[]platformclientv2.Smsphonenumberref into a []interface{} -func flattenSmsPhoneNumberRefs(smsPhoneNumberRefs *platformclientv2.Smsphonenumberref) []interface{} { - if smsPhoneNumberRefs == nil { - return nil - } - - var smsPhoneNumberRefList []interface{} - smsPhoneNumberRefMap := make(map[string]interface{}) - - resourcedata.SetMapValueIfNotNil(smsPhoneNumberRefMap, "phone_number", smsPhoneNumberRefs.PhoneNumber) - - smsPhoneNumberRefList = append(smsPhoneNumberRefList, smsPhoneNumberRefMap) - - return smsPhoneNumberRefList -} - // flattenSmsConfigs maps a Genesys Cloud *platformclientv2.Smsconfig into a []interface{} func flattenSmsConfigs(smsconfig *platformclientv2.Smsconfig) *schema.Set { if smsconfig == nil { @@ -330,6 +316,25 @@ func flattenSmsConfigs(smsconfig *platformclientv2.Smsconfig) *schema.Set { return smsconfigSet } +func validateEmailconfig(emailConfig *schema.Set) (string, bool) { + if emailConfig == nil { + return "", true + } + + emailConfigList := emailConfig.List() + if len(emailConfigList) > 0 { + emailConfigMap := emailConfigList[0].(map[string]interface{}) + emailColumn, _ := emailConfigMap["email_columns"].(string) + if emailColumn == "" { + return "Message_column is required.", false + } + } else { + return "", false + } + + return "", true +} + func validateSmsconfig(smsconfig *schema.Set) (string, bool) { if smsconfig == nil { return "", true @@ -345,6 +350,8 @@ func validateSmsconfig(smsconfig *schema.Set) (string, bool) { } else if messageColumn != "" && contentTemplateId != "" { return "Only one of message_column or content_template_id can be defined", false } + } else { + return "", false } return "", true From cce09118a12fe82f833abeceed4ad5f6a513a883 Mon Sep 17 00:00:00 2001 From: Shruti Suryawanshi Date: Fri, 12 Jul 2024 09:30:55 -0400 Subject: [PATCH 3/6] rule_set_ids changes --- ...genesyscloud_outbound_messagingcampaign.go | 4 +- ...yscloud_outbound_messagingcampaign_test.go | 63 +++--- ...genesyscloud_outbound_messagingcampaign.go | 2 +- ...cloud_outbound_messagingcampaign_schema.go | 4 +- ...yscloud_outbound_messagingcampaign_test.go | 197 +++++++++++------- ...scloud_outbound_messagingcampaign_utils.go | 2 +- 6 files changed, 160 insertions(+), 112 deletions(-) diff --git a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go index af1710560..c44835d9e 100644 --- a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go +++ b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign.go @@ -22,12 +22,12 @@ import ( // dataSourceOutboundMessagingcampaignRead retrieves by name the id in question func dataSourceOutboundMessagingcampaignRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { sdkConfig := meta.(*provider.ProviderMeta).ClientConfig - outboundApi := getOutboundMessagingcampaignProxy(sdkConfig) + proxy := getOutboundMessagingcampaignProxy(sdkConfig) name := d.Get("name").(string) return util.WithRetries(ctx, 15*time.Second, func() *retry.RetryError { - messagingCampaignId, retryable, resp, err := outboundApi.getOutboundMessagingcampaignIdByName(ctx, name) + messagingCampaignId, retryable, resp, err := proxy.getOutboundMessagingcampaignIdByName(ctx, name) if err != nil && !retryable { return retry.NonRetryableError(util.BuildWithRetriesApiDiagnosticError(resourceName, fmt.Sprintf("Error searching outbound messagingcampaign %s: %s", name, err), resp)) diff --git a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go index a2c85fb65..784b2b726 100644 --- a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go +++ b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go @@ -50,6 +50,9 @@ func TestAccDataSourceOutboundMessagingCampaign(t *testing.T) { ), ) + // Rule Set + ruleSetResourceId = "rule_set" + contactListResource = obContactList.GenerateOutboundContactList( contactListResourceId, contactListName, @@ -110,33 +113,39 @@ func TestAccDataSourceOutboundMessagingCampaign(t *testing.T) { Config: contactListResource + contactListFilterResource + callableTimeSetResource + - generateOutboundMessagingCampaignResource( - resourceId, - digitalCampaignName, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "off", - "10", - util.FalseValue, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - column1, - column1, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "", - "", - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "DESC", - TrueValue, - ), - generateDynamicContactQueueingSettingsBlock(util.FalseValue), - ) + generateOutboundMessagingCampaignDataSource( + fmt.Sprintf(` + resource "genesyscloud_outbound_ruleset" "%s" { + name = "%s" + contact_list_id = genesyscloud_outbound_contact_list.%s.id + } `, ruleSetResourceId, "tf ruleset "+uuid.NewString(), contactListResourceId, + ) + generateOutboundMessagingCampaignResource( + resourceId, + digitalCampaignName, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "off", + "10", + util.FalseValue, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, + generateOutboundMessagingCampaignSmsConfig( + column1, + column1, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "", + "", + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "DESC", + TrueValue, + ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), + ) + generateOutboundMessagingCampaignDataSource( dataSourceId, digitalCampaignName, "genesyscloud_outbound_messagingcampaign."+resourceId, diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go index db4fa2ef4..1781e095b 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign.go @@ -96,7 +96,7 @@ func readOutboundMessagingcampaign(ctx context.Context, d *schema.ResourceData, resourcedata.SetNillableValueWithInterfaceArrayWithFunc(d, "contact_sorts", messagingCampaign.ContactSorts, flattenContactSorts) resourcedata.SetNillableValue(d, "messages_per_minute", messagingCampaign.MessagesPerMinute) if messagingCampaign.RuleSets != nil { - _ = d.Set("rule_sets_ids", util.SdkDomainEntityRefArrToList(*messagingCampaign.RuleSets)) + _ = d.Set("rule_set_ids", util.SdkDomainEntityRefArrToList(*messagingCampaign.RuleSets)) } if messagingCampaign.ContactListFilters != nil { _ = d.Set("contact_list_filter_ids", util.SdkDomainEntityRefArrToList(*messagingCampaign.ContactListFilters)) diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go index 51837859e..36ca5b365 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go @@ -244,7 +244,7 @@ func ResourceOutboundMessagingcampaign() *schema.Resource { Required: true, Type: schema.TypeInt, }, - `rule_sets_ids`: { + `rule_set_ids`: { Description: `Rule Sets to be applied while this campaign is sending messages`, Optional: true, Type: schema.TypeList, @@ -296,7 +296,7 @@ func OutboundMessagingcampaignExporter() *resourceExporter.ResourceExporter { `division_id`: {RefType: "genesyscloud_auth_division"}, `contact_list_id`: {RefType: "genesyscloud_outbound_contact_list"}, `contact_list_filter_ids`: {RefType: "genesyscloud_outbound_contactlistfilter"}, - `rule_sets`: {RefType: "genesyscloud_outbound_ruleset"}, + `rule_set_ids`: {RefType: "genesyscloud_outbound_ruleset"}, `dnc_list_ids`: {RefType: "genesyscloud_outbound_dnclist"}, `callable_time_set_id`: {RefType: "genesyscloud_outbound_callabletimeset"}, `route_id`: {RefType: "genesyscloud_routing_email_route"}, diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go index db2cb160a..cb4fde791 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go @@ -105,6 +105,14 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { obCallableTimeset.GenerateTimeSlotsBlock("09:30:00", "22:30:00", "5"), ), ) + + // Rule Set + ruleSetResourceId = "rule_set" + ruleSetResource = generateOutboundCampaignRuleSetConfig( + ruleSetResourceId, + "tf ruleset "+uuid.NewString(), + contactListResourceId, + ) ) config, err := provider.AuthorizeSdk() @@ -132,33 +140,34 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { contactListResource + contactListFilterResource + callableTimeSetResource + - generateOutboundMessagingCampaignResource( - resourceId, - name, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "off", - messagesPerMin, - alwaysRunning, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn, - smsConfigPhoneColumn, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "", - "", - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "DESC", - TrueValue, - ), - generateDynamicContactQueueingSettingsBlock(util.FalseValue), + ruleSetResource + generateOutboundMessagingCampaignResource( + resourceId, + name, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "off", + messagesPerMin, + alwaysRunning, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, + []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn, + smsConfigPhoneColumn, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "", + "", ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "DESC", + TrueValue, + ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), + ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", name), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMin), @@ -182,6 +191,8 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "rule_set_ids.0", + "genesyscloud_outbound_ruleset."+ruleSetResourceId, "id"), provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), ), }, @@ -190,33 +201,38 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { contactListResource + contactListFilterResource + callableTimeSetResource + - generateOutboundMessagingCampaignResource( - resourceId, - name, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "on", - messagesPerMin, - alwaysRunning, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn, - smsConfigPhoneColumn, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "", - "", - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "DESC", - TrueValue, - ), - generateDynamicContactQueueingSettingsBlock(util.FalseValue), + generateOutboundCampaignRuleSetConfig( + ruleSetResourceId, + "tf ruleset "+uuid.NewString(), + contactListResourceId, + ) + generateOutboundMessagingCampaignResource( + resourceId, + name, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "on", + messagesPerMin, + alwaysRunning, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, + generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn, + smsConfigPhoneColumn, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "", + "", + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "DESC", + TrueValue, ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), + ), Check: resource.ComposeTestCheckFunc( // Check that the DiffSuppressFunc is working resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", name), @@ -241,6 +257,8 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "rule_set_ids.0", + "genesyscloud_outbound_ruleset."+ruleSetResourceId, "id"), provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), ), }, @@ -250,33 +268,38 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { contactListResource + contactListFilterResource + callableTimeSetResource + - generateOutboundMessagingCampaignResource( - resourceId, - nameUpdate, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "on", - messagesPerMinUpdate, - alwaysRunningUpdate, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn, - smsConfigPhoneColumn, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "DESC", - TrueValue, - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "", - "", - ), - generateDynamicContactQueueingSettingsBlock(util.FalseValue), + generateOutboundCampaignRuleSetConfig( + ruleSetResourceId, + "tf ruleset "+uuid.NewString(), + contactListResourceId, + ) + generateOutboundMessagingCampaignResource( + resourceId, + nameUpdate, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "on", + messagesPerMinUpdate, + alwaysRunningUpdate, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, + generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn, + smsConfigPhoneColumn, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "DESC", + TrueValue, ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "", + "", + ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), + ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", nameUpdate), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMinUpdate), @@ -298,6 +321,8 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), + resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "rule_set_ids.0", + "genesyscloud_outbound_ruleset."+ruleSetResourceId, "id"), provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), ), }, @@ -369,6 +394,7 @@ func generateOutboundMessagingCampaignResource( callableTimeSetId string, dncListIds []string, contactListFilterIds []string, + ruleSetIds []string, nestedBlocks ...string, ) string { if callableTimeSetId != "" { @@ -390,10 +416,23 @@ resource "genesyscloud_outbound_messagingcampaign" "%s" { %s dnc_list_ids = [%s] contact_list_filter_ids = [%s] + rule_set_ids = [%s] %s } `, resourceId, name, contactListId, campaignStatus, messagesPerMinute, alwaysRunning, callableTimeSetId, - strings.Join(dncListIds, ", "), strings.Join(contactListFilterIds, ", "), strings.Join(nestedBlocks, "\n")) + strings.Join(dncListIds, ", "), strings.Join(contactListFilterIds, ", "), strings.Join(ruleSetIds, ", "), strings.Join(nestedBlocks, "\n")) +} + +func generateOutboundCampaignRuleSetConfig( + resourceIdRuleSet string, + nameRuleSet string, + contactListResourceIdRuleSet string, +) string { + return fmt.Sprintf(` + resource "genesyscloud_outbound_ruleset" "%s" { + name = "%s" + contact_list_id = genesyscloud_outbound_contact_list.%s.id + } `, resourceIdRuleSet, nameRuleSet, contactListResourceIdRuleSet) } func generateOutboundMessagingCampaignSmsConfig( diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go index a921ae232..3151a702d 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go @@ -27,7 +27,7 @@ func getOutboundMessagingcampaignFromResourceData(d *schema.ResourceData) platfo AlwaysRunning: platformclientv2.Bool(d.Get("always_running").(bool)), ContactSorts: buildContactSorts(d.Get("contact_sorts").([]interface{})), MessagesPerMinute: platformclientv2.Int(d.Get("messages_per_minute").(int)), - RuleSets: util.BuildSdkDomainEntityRefArr(d, "rule_sets"), + RuleSets: util.BuildSdkDomainEntityRefArr(d, "rule_set_ids"), ContactListFilters: util.BuildSdkDomainEntityRefArr(d, "contact_list_filter_ids"), Errors: buildRestErrorDetails(d.Get("errors").([]interface{})), DynamicContactQueueingSettings: buildDynamicContactQueueingSettingss(d.Get("dynamic_contact_queueing_settings").([]interface{})), From 27c6b4447b9d51eeb024451f82eae6e7f7f1f604 Mon Sep 17 00:00:00 2001 From: Shruti Suryawanshi Date: Fri, 12 Jul 2024 09:33:45 -0400 Subject: [PATCH 4/6] updated docs --- docs/resources/outbound_messagingcampaign.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/resources/outbound_messagingcampaign.md b/docs/resources/outbound_messagingcampaign.md index 36d3f9c18..7c455a41e 100644 --- a/docs/resources/outbound_messagingcampaign.md +++ b/docs/resources/outbound_messagingcampaign.md @@ -67,7 +67,7 @@ resource "genesyscloud_outbound_messagingcampaign" "example_outbound_messagingca - `dynamic_contact_queueing_settings` (Block List, Max: 1) Indicates (when true) that the campaign supports dynamic queueing of the contact list at the time of a request for contacts. (see [below for nested schema](#nestedblock--dynamic_contact_queueing_settings)) - `email_config` (Block Set, Max: 1) Configuration for this messaging campaign to send Email messages. (see [below for nested schema](#nestedblock--email_config)) - `errors` (Block List) A list of current error conditions associated with this messaging campaign. (see [below for nested schema](#nestedblock--errors)) -- `rule_sets_ids` (List of String) Rule Sets to be applied while this campaign is sending messages +- `rule_set_ids` (List of String) Rule Sets to be applied while this campaign is sending messages - `sms_config` (Block Set, Max: 1) Configuration for this messaging campaign to send SMS messages. (see [below for nested schema](#nestedblock--sms_config)) ### Read-Only From 9c04037e14725ef4cdb4a367cd9d6bbff13c5277 Mon Sep 17 00:00:00 2001 From: Shruti Suryawanshi Date: Fri, 12 Jul 2024 09:48:24 -0400 Subject: [PATCH 5/6] minor fix for contactfilter --- .../resource_genesyscloud_outbound_messagingcampaign_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go index cb4fde791..e0a4cc191 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go @@ -149,8 +149,8 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { alwaysRunning, "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, generateOutboundMessagingCampaignSmsConfig( smsConfigMessageColumn, smsConfigPhoneColumn, From 464ec6e505704be816e033f20476b974b6a81824 Mon Sep 17 00:00:00 2001 From: Shruti Suryawanshi Date: Fri, 12 Jul 2024 17:23:42 -0400 Subject: [PATCH 6/6] added digitalRuleSet Api call for Testcases --- ...yscloud_outbound_messagingcampaign_test.go | 72 +++--- ...ud_outbound_messagingcampaign_init_test.go | 2 - ...cloud_outbound_messagingcampaign_schema.go | 4 +- ...yscloud_outbound_messagingcampaign_test.go | 207 ++++++++---------- ...scloud_outbound_messagingcampaign_utils.go | 22 ++ 5 files changed, 151 insertions(+), 156 deletions(-) diff --git a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go index 784b2b726..b6e8a4951 100644 --- a/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go +++ b/genesyscloud/outbound_messagingcampaign/data_source_genesyscloud_outbound_messagingcampaign_test.go @@ -50,9 +50,6 @@ func TestAccDataSourceOutboundMessagingCampaign(t *testing.T) { ), ) - // Rule Set - ruleSetResourceId = "rule_set" - contactListResource = obContactList.GenerateOutboundContactList( contactListResourceId, contactListName, @@ -105,6 +102,14 @@ func TestAccDataSourceOutboundMessagingCampaign(t *testing.T) { } }() + // Rule Set + testRuleSetId, err := GetOutboundDigitalRuleSets() + + if err != nil || testRuleSetId == "" { + testRuleSetId = "cb0f5633-53db-4e52-933e-0538f15a08bc" + t.Log("Error retrieving Rule Set Id") + } + resource.Test(t, resource.TestCase{ PreCheck: func() { util.TestAccPreCheck(t) }, ProviderFactories: provider.GetProviderFactories(providerResources, providerDataSources), @@ -113,39 +118,34 @@ func TestAccDataSourceOutboundMessagingCampaign(t *testing.T) { Config: contactListResource + contactListFilterResource + callableTimeSetResource + - fmt.Sprintf(` - resource "genesyscloud_outbound_ruleset" "%s" { - name = "%s" - contact_list_id = genesyscloud_outbound_contact_list.%s.id - } `, ruleSetResourceId, "tf ruleset "+uuid.NewString(), contactListResourceId, - ) + generateOutboundMessagingCampaignResource( - resourceId, - digitalCampaignName, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "off", - "10", - util.FalseValue, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - column1, - column1, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "", - "", - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "DESC", - TrueValue, - ), - generateDynamicContactQueueingSettingsBlock(util.FalseValue), - ) + generateOutboundMessagingCampaignDataSource( + generateOutboundMessagingCampaignResource( + resourceId, + digitalCampaignName, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "off", + "10", + util.FalseValue, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + []string{strconv.Quote(testRuleSetId)}, + generateOutboundMessagingCampaignSmsConfig( + column1, + column1, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "", + "", + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "DESC", + TrueValue, + ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), + ) + generateOutboundMessagingCampaignDataSource( dataSourceId, digitalCampaignName, "genesyscloud_outbound_messagingcampaign."+resourceId, diff --git a/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go b/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go index 0539ada06..1cc3cf6b8 100644 --- a/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go +++ b/genesyscloud/outbound_messagingcampaign/genesyscloud_outbound_messagingcampaign_init_test.go @@ -6,7 +6,6 @@ import ( obContactList "terraform-provider-genesyscloud/genesyscloud/outbound_contact_list" obContactListFilter "terraform-provider-genesyscloud/genesyscloud/outbound_contactlistfilter" obDnclist "terraform-provider-genesyscloud/genesyscloud/outbound_dnclist" - obRuleset "terraform-provider-genesyscloud/genesyscloud/outbound_ruleset" "testing" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" @@ -36,7 +35,6 @@ func (r *registerTestInstance) registerTestResources() { providerResources[resourceName] = ResourceOutboundMessagingcampaign() providerResources["genesyscloud_outbound_contact_list"] = obContactList.ResourceOutboundContactList() providerResources["genesyscloud_outbound_contactlistfilter"] = obContactListFilter.ResourceOutboundContactlistfilter() - providerResources["genesyscloud_outbound_ruleset"] = obRuleset.ResourceOutboundRuleset() providerResources["genesyscloud_outbound_callabletimeset"] = obCallableTimeset.ResourceOutboundCallabletimeset() providerResources["genesyscloud_outbound_dnclist"] = obDnclist.ResourceOutboundDncList() } diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go index 36ca5b365..a2d30438e 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_schema.go @@ -249,7 +249,7 @@ func ResourceOutboundMessagingcampaign() *schema.Resource { Optional: true, Type: schema.TypeList, Elem: &schema.Schema{Type: schema.TypeString}, - }, + }, // /api/v2/outbound/digitalrulesets `contact_list_filter_ids`: { Description: `The contact list filter to check before sending a message for this messaging campaign.`, Optional: true, @@ -296,10 +296,8 @@ func OutboundMessagingcampaignExporter() *resourceExporter.ResourceExporter { `division_id`: {RefType: "genesyscloud_auth_division"}, `contact_list_id`: {RefType: "genesyscloud_outbound_contact_list"}, `contact_list_filter_ids`: {RefType: "genesyscloud_outbound_contactlistfilter"}, - `rule_set_ids`: {RefType: "genesyscloud_outbound_ruleset"}, `dnc_list_ids`: {RefType: "genesyscloud_outbound_dnclist"}, `callable_time_set_id`: {RefType: "genesyscloud_outbound_callabletimeset"}, - `route_id`: {RefType: "genesyscloud_routing_email_route"}, `email_config.from_address.route_id`: {RefType: "genesyscloud_routing_email_route"}, `email_config.from_address.domain_id`: {RefType: "genesyscloud_routing_email_domain"}, // /api/v2/responsemanagement/responses/{responseId} diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go index e0a4cc191..d3791d67d 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_test.go @@ -105,14 +105,6 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { obCallableTimeset.GenerateTimeSlotsBlock("09:30:00", "22:30:00", "5"), ), ) - - // Rule Set - ruleSetResourceId = "rule_set" - ruleSetResource = generateOutboundCampaignRuleSetConfig( - ruleSetResourceId, - "tf ruleset "+uuid.NewString(), - contactListResourceId, - ) ) config, err := provider.AuthorizeSdk() @@ -131,6 +123,14 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { } }() + // Rule Set + testRuleSetId, err := GetOutboundDigitalRuleSets() + + if err != nil || testRuleSetId == "" { + testRuleSetId = "cb0f5633-53db-4e52-933e-0538f15a08bc" + t.Log("Error retrieving Rule Set Id") + } + resource.Test(t, resource.TestCase{ PreCheck: func() { util.TestAccPreCheck(t) }, ProviderFactories: provider.GetProviderFactories(providerResources, providerDataSources), @@ -140,34 +140,34 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { contactListResource + contactListFilterResource + callableTimeSetResource + - ruleSetResource + generateOutboundMessagingCampaignResource( - resourceId, - name, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "off", - messagesPerMin, - alwaysRunning, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn, - smsConfigPhoneColumn, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "", - "", - ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "DESC", - TrueValue, + generateOutboundMessagingCampaignResource( + resourceId, + name, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "off", + messagesPerMin, + alwaysRunning, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + []string{strconv.Quote(testRuleSetId)}, + generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn, + smsConfigPhoneColumn, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "", + "", + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "DESC", + TrueValue, + ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), ), - generateDynamicContactQueueingSettingsBlock(util.FalseValue), - ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", name), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMin), @@ -183,6 +183,7 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "DESC"), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", TrueValue), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "dynamic_contact_queueing_settings.0.sort", util.FalseValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "rule_set_ids.0", testRuleSetId), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "dnc_list_ids.0", @@ -191,8 +192,6 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "rule_set_ids.0", - "genesyscloud_outbound_ruleset."+ruleSetResourceId, "id"), provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), ), }, @@ -201,38 +200,34 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { contactListResource + contactListFilterResource + callableTimeSetResource + - generateOutboundCampaignRuleSetConfig( - ruleSetResourceId, - "tf ruleset "+uuid.NewString(), - contactListResourceId, - ) + generateOutboundMessagingCampaignResource( - resourceId, - name, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "on", - messagesPerMin, - alwaysRunning, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn, - smsConfigPhoneColumn, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "", - "", + generateOutboundMessagingCampaignResource( + resourceId, + name, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "on", + messagesPerMin, + alwaysRunning, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + []string{strconv.Quote(testRuleSetId)}, + generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn, + smsConfigPhoneColumn, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "", + "", + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "DESC", + TrueValue, + ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "DESC", - TrueValue, - ), - generateDynamicContactQueueingSettingsBlock(util.FalseValue), - ), Check: resource.ComposeTestCheckFunc( // Check that the DiffSuppressFunc is working resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", name), @@ -248,6 +243,7 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "DESC"), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", TrueValue), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "dynamic_contact_queueing_settings.0.sort", util.FalseValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "rule_set_ids.0", testRuleSetId), util.VerifyAttributeInArrayOfPotentialValues("genesyscloud_outbound_messagingcampaign."+resourceId, "campaign_status", []string{"on", "complete"}), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), @@ -257,8 +253,6 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "rule_set_ids.0", - "genesyscloud_outbound_ruleset."+ruleSetResourceId, "id"), provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), ), }, @@ -268,38 +262,34 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { contactListResource + contactListFilterResource + callableTimeSetResource + - generateOutboundCampaignRuleSetConfig( - ruleSetResourceId, - "tf ruleset "+uuid.NewString(), - contactListResourceId, - ) + generateOutboundMessagingCampaignResource( - resourceId, - nameUpdate, - "genesyscloud_outbound_contact_list."+contactListResourceId+".id", - "on", - messagesPerMinUpdate, - alwaysRunningUpdate, - "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", - []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, - []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, - []string{"genesyscloud_outbound_ruleset." + ruleSetResourceId + ".id"}, - generateOutboundMessagingCampaignSmsConfig( - smsConfigMessageColumn, - smsConfigPhoneColumn, - smsConfigSenderSMSPhoneNumber, - ), - GenerateOutboundMessagingCampaignContactSort( - column1, - "DESC", - TrueValue, + generateOutboundMessagingCampaignResource( + resourceId, + nameUpdate, + "genesyscloud_outbound_contact_list."+contactListResourceId+".id", + "on", + messagesPerMinUpdate, + alwaysRunningUpdate, + "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId+".id", + []string{"genesyscloud_outbound_dnclist." + dncListResourceId + ".id"}, + []string{"genesyscloud_outbound_contactlistfilter." + clfResourceId + ".id"}, + []string{strconv.Quote(testRuleSetId)}, + generateOutboundMessagingCampaignSmsConfig( + smsConfigMessageColumn, + smsConfigPhoneColumn, + smsConfigSenderSMSPhoneNumber, + ), + GenerateOutboundMessagingCampaignContactSort( + column1, + "DESC", + TrueValue, + ), + GenerateOutboundMessagingCampaignContactSort( + column2, + "", + "", + ), + generateDynamicContactQueueingSettingsBlock(util.FalseValue), ), - GenerateOutboundMessagingCampaignContactSort( - column2, - "", - "", - ), - generateDynamicContactQueueingSettingsBlock(util.FalseValue), - ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "name", nameUpdate), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "messages_per_minute", messagesPerMinUpdate), @@ -314,6 +304,7 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.field_name", column2), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.direction", "ASC"), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_sorts.1.numeric", util.FalseValue), + resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "rule_set_ids.0", testRuleSetId), resource.TestCheckResourceAttr("genesyscloud_outbound_messagingcampaign."+resourceId, "dynamic_contact_queueing_settings.0.sort", util.FalseValue), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "callable_time_set_id", "genesyscloud_outbound_callabletimeset."+callableTimeSetResourceId, "id"), @@ -321,8 +312,6 @@ func TestAccResourceOutboundMessagingCampaign(t *testing.T) { "genesyscloud_outbound_contactlistfilter."+clfResourceId, "id"), resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "contact_list_id", "genesyscloud_outbound_contact_list."+contactListResourceId, "id"), - resource.TestCheckResourceAttrPair("genesyscloud_outbound_messagingcampaign."+resourceId, "rule_set_ids.0", - "genesyscloud_outbound_ruleset."+ruleSetResourceId, "id"), provider.TestDefaultHomeDivision("genesyscloud_outbound_messagingcampaign."+resourceId), ), }, @@ -423,18 +412,6 @@ resource "genesyscloud_outbound_messagingcampaign" "%s" { strings.Join(dncListIds, ", "), strings.Join(contactListFilterIds, ", "), strings.Join(ruleSetIds, ", "), strings.Join(nestedBlocks, "\n")) } -func generateOutboundCampaignRuleSetConfig( - resourceIdRuleSet string, - nameRuleSet string, - contactListResourceIdRuleSet string, -) string { - return fmt.Sprintf(` - resource "genesyscloud_outbound_ruleset" "%s" { - name = "%s" - contact_list_id = genesyscloud_outbound_contact_list.%s.id - } `, resourceIdRuleSet, nameRuleSet, contactListResourceIdRuleSet) -} - func generateOutboundMessagingCampaignSmsConfig( smsConfigMessageColumn string, smsConfigPhoneColumn string, diff --git a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go index 3151a702d..b4c55aee3 100644 --- a/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go +++ b/genesyscloud/outbound_messagingcampaign/resource_genesyscloud_outbound_messagingcampaign_utils.go @@ -2,6 +2,7 @@ package outbound_messagingcampaign import ( "fmt" + "terraform-provider-genesyscloud/genesyscloud/provider" "terraform-provider-genesyscloud/genesyscloud/util" "terraform-provider-genesyscloud/genesyscloud/util/resourcedata" @@ -372,3 +373,24 @@ func GenerateOutboundMessagingCampaignContactSort(fieldName string, direction st } `, fieldName, direction, numeric) } + +// GetOutboundDigitalrulesets invokes GET /api/v2/outbound/digitalrulesets +func GetOutboundDigitalRuleSets() (string, error) { + config, err := provider.AuthorizeSdk() + if err != nil { + return "", err + } + + outboundApi := platformclientv2.NewOutboundApiWithConfig(config) + outboundRuleSets, _, err := outboundApi.GetOutboundDigitalrulesets(1, 1, "", "", "", []string{}) + + if outboundRuleSets.Entities == nil || len(*outboundRuleSets.Entities) == 0 { + return "", err + } + + if len(*outboundRuleSets.Entities) > 0 { + ruleSet := (*outboundRuleSets.Entities)[0] + return *ruleSet.Id, nil + } + return "", err +}