Skip to content

Commit

Permalink
add webhook server
Browse files Browse the repository at this point in the history
  • Loading branch information
jeffy-mathew committed Jun 13, 2024
1 parent 6c3fb6a commit 238ff00
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 7 deletions.
14 changes: 11 additions & 3 deletions auto/deps_pro-ha.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ services:
container_name: openldap
image: osixia/openldap:1.5.0
ports:
- '389:389'
- '636:636'
- "389:389"
- "636:636"
environment:
- LDAP_READONLY_USER=true
- LDAP_READONLY_USER_USERNAME=read-only-admin
Expand All @@ -50,8 +50,16 @@ services:
profiles: ["all", "master-datacenter"]
container_name: restcountries
image: bigpapoo/restcountries:1.0

trevorblades:
profiles: ["all", "master-datacenter"]
container_name: trevorblades
image: mangomm/trevorblades-countries

webhook:
profiles: ["all", "master-datacenter"]
container_name: webhook-server
build:
context: ./webhook-server
ports:
- "9003:8080"
15 changes: 11 additions & 4 deletions auto/deps_pro.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
version: "3.9"
services:

bundle-server:
profiles: ["all", "master-datacenter"]
container_name: bundle-server
Expand All @@ -24,8 +23,8 @@ services:
container_name: openldap
image: osixia/openldap:1.5.0
ports:
- '389:389'
- '636:636'
- "389:389"
- "636:636"
environment:
- LDAP_READONLY_USER=true
- LDAP_READONLY_USER_USERNAME=read-only-admin
Expand All @@ -51,8 +50,16 @@ services:
profiles: ["all", "master-datacenter"]
container_name: restcountries
image: bigpapoo/restcountries:1.0

trevorblades:
profiles: ["all", "master-datacenter"]
container_name: trevorblades
image: mangomm/trevorblades-countries

webhook:
profiles: ["all", "master-datacenter"]
container_name: webhook-server
build:
context: ./webhook-server
ports:
- "9003:8080"
17 changes: 17 additions & 0 deletions auto/webhook-server/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Use the official Golang image as the build stage
FROM golang:alpine as builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy the source code into the container
COPY . .

# Build the Go app
RUN go build -o webhook .

# Expose port 8080 to the outside world
EXPOSE 8080

# Command to run the executable
CMD ["./webhook"]
60 changes: 60 additions & 0 deletions auto/webhook-server/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Webhook Server

A simple Go application to receive and store webhook events, and retrieve them based on an ID.

## Features

- Receives webhook events at `/webhook/{id}`
- Stores requests associated with each `{id}`
- Retrieves stored requests at `/requests/{id}`


## Usage

### Start webhook server
`go run main.go` runs the webhook server listening on port `8080`.

### Sending a Webhook Event

Send a POST request to `/webhook/{id}` with your webhook payload:

```
curl -X POST http://localhost:8080/webhook/1 \
-H "Content-Type: application/json" \
-d '{"event": "test"}'
```

### Retrieving Stored Requests
Send a GET request to `/requests/{id}` to retrieve the requests stored for a particular ID
```
curl http://localhost:8080/requests/1
```

This will return a JSON array of all received webhook requests for the given ID.

### Example
1. Send a webhook event to ID `1`:

```
curl -X POST http://localhost:8080/webhook/1 \
-H "Content-Type: application/json" \
-d '{"event": "test event for ID 1"}'
```

2. Retrieve stored requests for ID `1`:
```
curl http://localhost:8080/requests/1
```

Response
```
[
{
"headers": {
"Content-Type": ["application/json"],
...
},
"body": {"event": "test event for ID 1"}
}
]
```
3 changes: 3 additions & 0 deletions auto/webhook-server/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module webhook

go 1.22.0
82 changes: 82 additions & 0 deletions auto/webhook-server/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package main

import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"regexp"
"sync"
)

const root = "root"

type WebhookRequest struct {
Headers map[string][]string `json:"headers"`
Body json.RawMessage `json:"body"`
}

var (
receivedRequests = make(map[string][]WebhookRequest)
mutex sync.Mutex
idPattern = regexp.MustCompile(`^/webhook/(\d+)$`)
requestPattern = regexp.MustCompile(`^/requests/(\d+)$`)
)

func webhookHandler(w http.ResponseWriter, r *http.Request) {
body, err := io.ReadAll(r.Body)
if err != nil {
http.Error(w, "couldn't read body", http.StatusBadRequest)
return
}

matches := idPattern.FindStringSubmatch(r.URL.Path)
id := root
if len(matches) >= 2 {
id = matches[1]
}

request := WebhookRequest{
Headers: r.Header,
Body: body,
}

mutex.Lock()
receivedRequests[id] = append(receivedRequests[id], request)
mutex.Unlock()

w.WriteHeader(http.StatusOK)
}

func requestsHandler(w http.ResponseWriter, r *http.Request) {
matches := requestPattern.FindStringSubmatch(r.URL.Path)
id := root
if len(matches) >= 2 {
id = matches[1]
}

log.Println("id =", id)

mutex.Lock()
defer mutex.Unlock()

requests, exists := receivedRequests[id]
if !exists {
http.Error(w, "No requests found for the given ID", http.StatusNotFound)
return
}

w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(requests)
}

func main() {
http.HandleFunc("/webhook/", webhookHandler)
http.HandleFunc("/requests/", requestsHandler)

fmt.Println("Starting server on :8080")
if err := http.ListenAndServe(":8080", nil); err != nil {
log.Fatalf("Could not start server: %s\n", err)
}
}

0 comments on commit 238ff00

Please sign in to comment.