Skip to content

Commit

Permalink
Add support for Account Webhooks (#167)
Browse files Browse the repository at this point in the history
  • Loading branch information
dglsparsons authored Apr 17, 2024
1 parent 05a5921 commit 135c3b7
Show file tree
Hide file tree
Showing 6 changed files with 535 additions and 0 deletions.
74 changes: 74 additions & 0 deletions client/webhook.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package client

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-log/tflog"
)

type CreateWebhookRequest struct {
TeamID string `json:"-"`
Events []string `json:"events"`
Endpoint string `json:"url"`
ProjectIDs []string `json:"projectIds,omitempty"`
}

type Webhook struct {
Events []string `json:"events"`
ID string `json:"id"`
Endpoint string `json:"url"`
TeamID string `json:"ownerId"`
ProjectIDs []string `json:"projectIds"`
Secret string `json:"secret"`
}

func (c *Client) CreateWebhook(ctx context.Context, request CreateWebhookRequest) (w Webhook, err error) {
url := fmt.Sprintf("%s/v1/webhooks", c.baseURL)
if c.teamID(request.TeamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID))
}
payload := string(mustMarshal(request))
tflog.Info(ctx, "creating webhook", map[string]interface{}{
"url": url,
"payload": payload,
})
err = c.doRequest(clientRequest{
ctx: ctx,
method: "POST",
url: url,
body: payload,
}, &w)
return w, err
}

func (c *Client) DeleteWebhook(ctx context.Context, id, teamID string) error {
url := fmt.Sprintf("%s/v1/webhooks/%s", c.baseURL, id)
if c.teamID(teamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID))
}
tflog.Info(ctx, "deleting webhook", map[string]interface{}{
"url": url,
})
return c.doRequest(clientRequest{
ctx: ctx,
method: "DELETE",
url: url,
}, nil)
}

func (c *Client) GetWebhook(ctx context.Context, id, teamID string) (w Webhook, err error) {
url := fmt.Sprintf("%s/v1/webhooks/%s", c.baseURL, id)
if c.teamID(teamID) != "" {
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID))
}
tflog.Info(ctx, "getting webhook", map[string]interface{}{
"url": url,
})
err = c.doRequest(clientRequest{
ctx: ctx,
method: "GET",
url: url,
}, &w)
return w, err
}
58 changes: 58 additions & 0 deletions docs/resources/webhook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "vercel_webhook Resource - terraform-provider-vercel"
subcategory: ""
description: |-
A webhook is a trigger-based HTTP endpoint configured to receive HTTP POST requests through events.
When an event happens, a webhook is sent to a third-party app, which can then take appropriate action.
~> Only Pro and Enterprise teams are able to configure these webhooks at the account level.
---

# vercel_webhook (Resource)

A webhook is a trigger-based HTTP endpoint configured to receive HTTP POST requests through events.

When an event happens, a webhook is sent to a third-party app, which can then take appropriate action.

~> Only Pro and Enterprise teams are able to configure these webhooks at the account level.

## Example Usage

```terraform
resource "vercel_project" "example" {
name = "example-project"
}
resource "vercel_project" "example2" {
name = "another-example-project"
}
resource "vercel_webhook" "with_project_ids" {
events = ["deployment.created", "deployment.succeeded"]
endpoint = "https://example.com/endpoint"
project_ids = [vercel_project.example.id, vercel_project.example2.id]
}
resource "vercel_webhook" "without_project_ids" {
events = ["deployment.created", "deployment.succeeded"]
endpoint = "https://example.com/endpoint"
}
```

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

### Required

- `endpoint` (String) Webhooks events will be sent as POST request to this URL.
- `events` (Set of String) A list of the events the webhook will listen to. At least one must be present.

### Optional

- `project_ids` (Set of String) A list of project IDs that the webhook should be associated with. These projects should send events to the specified endpoint.
- `team_id` (String) The ID of the team the Webhook should exist under. Required when configuring a team resource if a default team has not been set in the provider.

### Read-Only

- `id` (String) The ID of the Webhook.
- `secret` (String) A secret value which will be provided in the `x-vercel-signature` header and can be used to verify the authenticity of the webhook. See https://vercel.com/docs/observability/webhooks-overview/webhooks-api#securing-webhooks for further details.
18 changes: 18 additions & 0 deletions examples/resources/vercel_webhook/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
resource "vercel_project" "example" {
name = "example-project"
}

resource "vercel_project" "example2" {
name = "another-example-project"
}

resource "vercel_webhook" "with_project_ids" {
events = ["deployment.created", "deployment.succeeded"]
endpoint = "https://example.com/endpoint"
project_ids = [vercel_project.example.id, vercel_project.example2.id]
}

resource "vercel_webhook" "without_project_ids" {
events = ["deployment.created", "deployment.succeeded"]
endpoint = "https://example.com/endpoint"
}
1 change: 1 addition & 0 deletions vercel/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ func (p *vercelProvider) Resources(_ context.Context) []func() resource.Resource
newEdgeConfigResource,
newEdgeConfigTokenResource,
newEdgeConfigSchemaResource,
newWebhookResource,
}
}

Expand Down
Loading

0 comments on commit 135c3b7

Please sign in to comment.