Skip to content

Commit 135c3b7

Browse files
authored
Add support for Account Webhooks (#167)
1 parent 05a5921 commit 135c3b7

File tree

6 files changed

+535
-0
lines changed

6 files changed

+535
-0
lines changed

client/webhook.go

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-log/tflog"
8+
)
9+
10+
type CreateWebhookRequest struct {
11+
TeamID string `json:"-"`
12+
Events []string `json:"events"`
13+
Endpoint string `json:"url"`
14+
ProjectIDs []string `json:"projectIds,omitempty"`
15+
}
16+
17+
type Webhook struct {
18+
Events []string `json:"events"`
19+
ID string `json:"id"`
20+
Endpoint string `json:"url"`
21+
TeamID string `json:"ownerId"`
22+
ProjectIDs []string `json:"projectIds"`
23+
Secret string `json:"secret"`
24+
}
25+
26+
func (c *Client) CreateWebhook(ctx context.Context, request CreateWebhookRequest) (w Webhook, err error) {
27+
url := fmt.Sprintf("%s/v1/webhooks", c.baseURL)
28+
if c.teamID(request.TeamID) != "" {
29+
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(request.TeamID))
30+
}
31+
payload := string(mustMarshal(request))
32+
tflog.Info(ctx, "creating webhook", map[string]interface{}{
33+
"url": url,
34+
"payload": payload,
35+
})
36+
err = c.doRequest(clientRequest{
37+
ctx: ctx,
38+
method: "POST",
39+
url: url,
40+
body: payload,
41+
}, &w)
42+
return w, err
43+
}
44+
45+
func (c *Client) DeleteWebhook(ctx context.Context, id, teamID string) error {
46+
url := fmt.Sprintf("%s/v1/webhooks/%s", c.baseURL, id)
47+
if c.teamID(teamID) != "" {
48+
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID))
49+
}
50+
tflog.Info(ctx, "deleting webhook", map[string]interface{}{
51+
"url": url,
52+
})
53+
return c.doRequest(clientRequest{
54+
ctx: ctx,
55+
method: "DELETE",
56+
url: url,
57+
}, nil)
58+
}
59+
60+
func (c *Client) GetWebhook(ctx context.Context, id, teamID string) (w Webhook, err error) {
61+
url := fmt.Sprintf("%s/v1/webhooks/%s", c.baseURL, id)
62+
if c.teamID(teamID) != "" {
63+
url = fmt.Sprintf("%s?teamId=%s", url, c.teamID(teamID))
64+
}
65+
tflog.Info(ctx, "getting webhook", map[string]interface{}{
66+
"url": url,
67+
})
68+
err = c.doRequest(clientRequest{
69+
ctx: ctx,
70+
method: "GET",
71+
url: url,
72+
}, &w)
73+
return w, err
74+
}

docs/resources/webhook.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "vercel_webhook Resource - terraform-provider-vercel"
4+
subcategory: ""
5+
description: |-
6+
A webhook is a trigger-based HTTP endpoint configured to receive HTTP POST requests through events.
7+
When an event happens, a webhook is sent to a third-party app, which can then take appropriate action.
8+
~> Only Pro and Enterprise teams are able to configure these webhooks at the account level.
9+
---
10+
11+
# vercel_webhook (Resource)
12+
13+
A webhook is a trigger-based HTTP endpoint configured to receive HTTP POST requests through events.
14+
15+
When an event happens, a webhook is sent to a third-party app, which can then take appropriate action.
16+
17+
~> Only Pro and Enterprise teams are able to configure these webhooks at the account level.
18+
19+
## Example Usage
20+
21+
```terraform
22+
resource "vercel_project" "example" {
23+
name = "example-project"
24+
}
25+
26+
resource "vercel_project" "example2" {
27+
name = "another-example-project"
28+
}
29+
30+
resource "vercel_webhook" "with_project_ids" {
31+
events = ["deployment.created", "deployment.succeeded"]
32+
endpoint = "https://example.com/endpoint"
33+
project_ids = [vercel_project.example.id, vercel_project.example2.id]
34+
}
35+
36+
resource "vercel_webhook" "without_project_ids" {
37+
events = ["deployment.created", "deployment.succeeded"]
38+
endpoint = "https://example.com/endpoint"
39+
}
40+
```
41+
42+
<!-- schema generated by tfplugindocs -->
43+
## Schema
44+
45+
### Required
46+
47+
- `endpoint` (String) Webhooks events will be sent as POST request to this URL.
48+
- `events` (Set of String) A list of the events the webhook will listen to. At least one must be present.
49+
50+
### Optional
51+
52+
- `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.
53+
- `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.
54+
55+
### Read-Only
56+
57+
- `id` (String) The ID of the Webhook.
58+
- `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.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
resource "vercel_project" "example" {
2+
name = "example-project"
3+
}
4+
5+
resource "vercel_project" "example2" {
6+
name = "another-example-project"
7+
}
8+
9+
resource "vercel_webhook" "with_project_ids" {
10+
events = ["deployment.created", "deployment.succeeded"]
11+
endpoint = "https://example.com/endpoint"
12+
project_ids = [vercel_project.example.id, vercel_project.example2.id]
13+
}
14+
15+
resource "vercel_webhook" "without_project_ids" {
16+
events = ["deployment.created", "deployment.succeeded"]
17+
endpoint = "https://example.com/endpoint"
18+
}

vercel/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ func (p *vercelProvider) Resources(_ context.Context) []func() resource.Resource
6060
newEdgeConfigResource,
6161
newEdgeConfigTokenResource,
6262
newEdgeConfigSchemaResource,
63+
newWebhookResource,
6364
}
6465
}
6566

0 commit comments

Comments
 (0)