Skip to content

Commit

Permalink
Merge pull request incentro-ecx#26 from incentro-dc/feat/webhooks
Browse files Browse the repository at this point in the history
feat: added webhook resource
  • Loading branch information
Thomas De Meyer authored Sep 28, 2022
2 parents 86ec446 + 769817f commit 442dcd9
Show file tree
Hide file tree
Showing 9 changed files with 263 additions and 4 deletions.
1 change: 1 addition & 0 deletions commercelayer/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func Provider() *schema.Provider {
"commercelayer_merchant": resourceMerchant(),
"commercelayer_price_list": resourcePriceList(),
"commercelayer_customer_group": resourceCustomerGroup(),
"commercelayer_webhook": resourceWebhook(),
},
ConfigureContextFunc: providerConfigureFunc,
}
Expand Down
5 changes: 3 additions & 2 deletions commercelayer/resource_address.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import (

func resourceAddress() *schema.Resource {
return &schema.Resource{
Description: "Get notified when specific events occur on a Commercelayer store. For more information, see " +
"Addresss Overview.",
Description: "Addresses can be associated with orders as their shipping or billing addresses. Add a " +
"Google or Bing geocoder to a market if you want its addresses to be automatically geocoded. Customers " +
"can save their most-used addresses in their address books (as customer addresses).",
ReadContext: resourceAddressReadFunc,
CreateContext: resourceAddressCreateFunc,
UpdateContext: resourceAddressUpdateFunc,
Expand Down
168 changes: 168 additions & 0 deletions commercelayer/resource_webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
package commercelayer

import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
commercelayer "github.com/incentro-dc/go-commercelayer-sdk/api"
)

func resourceWebhook() *schema.Resource {
return &schema.Resource{
Description: "A webhook object is returned as part of the response body of each successful list, retrieve, " +
"create or update API call to the /api/webhooks endpoint.",
ReadContext: resourceWebhookReadFunc,
CreateContext: resourceWebhookCreateFunc,
UpdateContext: resourceWebhookUpdateFunc,
DeleteContext: resourceWebhookDeleteFunc,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Schema: map[string]*schema.Schema{
"id": {
Description: "The webhook unique identifier",
Type: schema.TypeString,
Computed: true,
},
"attributes": {
Description: "Resource attributes",
Type: schema.TypeList,
MaxItems: 1,
MinItems: 1,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"name": {
Description: "Unique name for the webhook.",
Type: schema.TypeString,
Optional: true,
Default: "webhook",
},
"topic": {
Description: "The identifier of the resource/event that will trigger the webhook.",
Type: schema.TypeString,
Required: true,
},
"callback_url": {
Description: "URI where the webhook subscription should send the POST request when the " +
"event occurs.",
Type: schema.TypeString,
Required: true,
},
"include_resources": {
Description: "List of related resources that should be included in the webhook body.",
Type: schema.TypeList,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
},
"reference": {
Description: "A string that you can use to add any external identifier to the resource. This " +
"can be useful for integrating the resource to an external system, like an ERP, a " +
"marketing tool, a CRM, or whatever.",
Type: schema.TypeString,
Optional: true,
},
"reference_origin": {
Description: "Any identifier of the third party system that defines the reference code",
Type: schema.TypeString,
Optional: true,
},
"metadata": {
Description: "Set of key-value pairs that you can attach to the resource. This can be useful " +
"for storing additional information about the resource in a structured format",
Type: schema.TypeMap,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Optional: true,
},
},
},
},
},
}
}

func resourceWebhookReadFunc(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics {
c := i.(*commercelayer.APIClient)

resp, _, err := c.WebhooksApi.GETWebhooksWebhookId(ctx, d.Id()).Execute()
if err != nil {
return diagErr(err)
}

webhook, ok := resp.GetDataOk()
if !ok {
d.SetId("")
return nil
}

d.SetId(webhook.GetId())

return nil
}

func resourceWebhookCreateFunc(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics {
c := i.(*commercelayer.APIClient)

attributes := d.Get("attributes").([]interface{})[0].(map[string]interface{})

webhookCreate := commercelayer.WebhookCreate{
Data: commercelayer.WebhookCreateData{
Type: webhookType,
Attributes: commercelayer.POSTWebhooks201ResponseDataAttributes{
Name: stringRef(attributes["name"]),
Topic: attributes["topic"].(string),
CallbackUrl: attributes["callback_url"].(string),
IncludeResources: stringSliceValueRef(attributes["include_resources"]),
Reference: stringRef(attributes["reference"]),
ReferenceOrigin: stringRef(attributes["reference_origin"]),
Metadata: keyValueRef(attributes["metadata"]),
},
},
}

address, _, err := c.WebhooksApi.POSTWebhooks(ctx).WebhookCreate(webhookCreate).Execute()
if err != nil {
return diagErr(err)
}

d.SetId(*address.Data.Id)

return nil
}

func resourceWebhookDeleteFunc(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics {
c := i.(*commercelayer.APIClient)
_, err := c.WebhooksApi.DELETEWebhooksWebhookId(ctx, d.Id()).Execute()
return diag.FromErr(err)
}

func resourceWebhookUpdateFunc(ctx context.Context, d *schema.ResourceData, i interface{}) diag.Diagnostics {
c := i.(*commercelayer.APIClient)

attributes := d.Get("attributes").([]interface{})[0].(map[string]interface{})

var webhookUpdate = commercelayer.WebhookUpdate{
Data: commercelayer.WebhookUpdateData{
Type: webhookType,
Id: d.Id(),
Attributes: commercelayer.PATCHWebhooksWebhookId200ResponseDataAttributes{
Name: stringRef(attributes["name"]),
Topic: stringRef(attributes["topic"]),
CallbackUrl: stringRef(attributes["callback_url"]),
IncludeResources: stringSliceValueRef(attributes["include_resources"]),
Reference: stringRef(attributes["reference"]),
ReferenceOrigin: stringRef(attributes["reference_origin"]),
Metadata: keyValueRef(attributes["metadata"]),
},
},
}

_, _, err := c.WebhooksApi.PATCHWebhooksWebhookId(ctx, d.Id()).WebhookUpdate(webhookUpdate).Execute()

return diag.FromErr(err)

}
1 change: 1 addition & 0 deletions commercelayer/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ const (
merchantType = "merchants"
customerGroupType = "customer_groups"
priceListType = "price_lists"
webhookType = "webhooks"
)
14 changes: 14 additions & 0 deletions commercelayer/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,3 +54,17 @@ func float64ToFloat32Ref(val interface{}) *float32 {

return &ref
}

func stringSliceValueRef(val interface{}) []string {
if val == nil {
return []string{}
}

var s []string

for _, v := range val.([]interface{}) {
s = append(s, v.(string))
}

return s
}
18 changes: 18 additions & 0 deletions commercelayer/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,21 @@ func TestFloat64ToFloat32RefZeroVal(t *testing.T) {
func TestFloat64ToFloat32RefFloat64Val(t *testing.T) {
assert.Equal(t, float32(1), *float64ToFloat32Ref(float64(1)))
}

func TestStringSliceValueRefNilVal(t *testing.T) {
assert.Equal(t, []string{}, stringSliceValueRef(nil))
}

func TestStringSliceValueRefEmptySliceVal(t *testing.T) {
assert.Equal(t, []string(nil), stringSliceValueRef([]interface{}{}))
}

func TestStringSliceValueRefFilledSliceVal(t *testing.T) {
assert.Equal(t, []string{"foobar"}, stringSliceValueRef([]interface{}{"foobar"}))
}

func TestStringSliceValueRefFilledIntSliceVal(t *testing.T) {
assert.Panics(t, func() {
stringSliceValueRef([]interface{}{1})
})
}
4 changes: 2 additions & 2 deletions docs/resources/address.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
page_title: "commercelayer_address Resource - terraform-provider-commercelayer"
subcategory: ""
description: |-
Get notified when specific events occur on a Commercelayer store. For more information, see Addresss Overview.
Addresses can be associated with orders as their shipping or billing addresses. Add a Google or Bing geocoder to a market if you want its addresses to be automatically geocoded. Customers can save their most-used addresses in their address books (as customer addresses).
---

# commercelayer_address (Resource)

Get notified when specific events occur on a Commercelayer store. For more information, see Addresss Overview.
Addresses can be associated with orders as their shipping or billing addresses. Add a Google or Bing geocoder to a market if you want its addresses to be automatically geocoded. Customers can save their most-used addresses in their address books (as customer addresses).



Expand Down
42 changes: 42 additions & 0 deletions docs/resources/webhook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "commercelayer_webhook Resource - terraform-provider-commercelayer"
subcategory: ""
description: |-
A webhook object is returned as part of the response body of each successful list, retrieve, create or update API call to the /api/webhooks endpoint.
---

# commercelayer_webhook (Resource)

A webhook object is returned as part of the response body of each successful list, retrieve, create or update API call to the /api/webhooks endpoint.



<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `attributes` (Block List, Min: 1, Max: 1) Resource attributes (see [below for nested schema](#nestedblock--attributes))

### Read-Only

- `id` (String) The webhook unique identifier

<a id="nestedblock--attributes"></a>
### Nested Schema for `attributes`

Required:

- `callback_url` (String) URI where the webhook subscription should send the POST request when the event occurs.
- `topic` (String) The identifier of the resource/event that will trigger the webhook.

Optional:

- `include_resources` (List of String) List of related resources that should be included in the webhook body.
- `metadata` (Map of String) Set of key-value pairs that you can attach to the resource. This can be useful for storing additional information about the resource in a structured format
- `name` (String) Unique name for the webhook.
- `reference` (String) A string that you can use to add any external identifier to the resource. This can be useful for integrating the resource to an external system, like an ERP, a marketing tool, a CRM, or whatever.
- `reference_origin` (String) Any identifier of the third party system that defines the reference code


14 changes: 14 additions & 0 deletions examples/full/webhooks.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
resource "commercelayer_webhook" "orders_create_webhook" {
attributes {
name = "order-fulfillment"
topic = "orders.create"
callback_url = "http://example.url"
include_resources = [
"customer",
"line_items"
]
metadata = {
foo : "bar"
}
}
}

0 comments on commit 442dcd9

Please sign in to comment.