diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6328938..8a868b5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -14,14 +14,14 @@ on: default: false type: boolean version-increment-type: - description: 'Which part of the version to increment:' - required: true - type: choice - options: - - major - - minor - - patch - default: 'patch' + description: "Which part of the version to increment:" + required: true + type: choice + options: + - major + - minor + - patch + default: "patch" permissions: contents: write @@ -66,7 +66,11 @@ jobs: - uses: actions/setup-go@v5 with: - go-version: '1.20' + go-version: "1.20" + + - name: Update version.go file + run: | + sed -i 's/const Version = ".*"/const Version = "${{ steps.prepare-release.outputs.next-release-tag }}"/' version.go - name: Build and push Docker image uses: docker/build-push-action@v4.0.0 diff --git a/cmd/main.go b/cmd/main.go index 082c2f2..4744364 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -14,7 +14,7 @@ import ( ) const ( - Version = "0.1.0" + Version = sdkproxy.Version EnvConfigFormat = ` This application can also be configured via the environment. The following environment variables can be used: diff --git a/http_endpoints.go b/http_endpoints.go index 465f2e6..b556302 100644 --- a/http_endpoints.go +++ b/http_endpoints.go @@ -1,6 +1,7 @@ package local_bucketing_proxy import ( + "bytes" "encoding/json" "fmt" "io" @@ -75,6 +76,10 @@ func Track() gin.HandlerFunc { event := getEventFromBody(c) for _, e := range event.Events { + if e.MetaData == nil { + e.MetaData = make(map[string]interface{}) + } + e.MetaData["sdkProxy"] = Version _, err := client.Track(event.User.User, e) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{}) @@ -87,23 +92,82 @@ func BatchEvents() gin.HandlerFunc { return func(c *gin.Context) { client := c.Value("devcycle").(*devcycle.Client) + body, err := io.ReadAll(c.Request.Body) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Error reading request body: " + err.Error()}) + return + } + + var batchEvents map[string]interface{} + err = json.Unmarshal(body, &batchEvents) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Error unmarshaling request body: " + err.Error()}) + return + } + + batchArray, exists := batchEvents["batch"].([]interface{}) + if !exists { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Missing 'batch' key in request body"}) + return + } + + for _, batchItem := range batchArray { + batchMap, ok := batchItem.(map[string]interface{}) + if !ok { + continue + } + + events, ok := batchMap["events"].([]interface{}) + if !ok { + continue + } + + for i, eventInterface := range events { + event, ok := eventInterface.(map[string]interface{}) + if !ok { + continue + } + + if _, exists := event["metaData"]; !exists { + event["metaData"] = make(map[string]interface{}) + } + + metadata, ok := event["metaData"].(map[string]interface{}) + if !ok { + event["metaData"] = make(map[string]interface{}) + metadata = event["metaData"].(map[string]interface{}) + } + + metadata["sdkProxy"] = Version + events[i] = event + } + + batchMap["events"] = events + } + + modifiedBody, err := json.Marshal(batchEvents) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"message": "Error marshaling modified request body: " + err.Error()}) + return + } + // Passthrough proxy to the configured events api endpoint. httpC := http.DefaultClient - req, err := http.NewRequest("POST", client.DevCycleOptions.EventsAPIURI+"/v1/events/batch", c.Request.Body) + req, err := http.NewRequest("POST", client.DevCycleOptions.EventsAPIURI+"/v1/events/batch", bytes.NewBuffer(modifiedBody)) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"message": "Error creating request, " + err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"message": "Error creating request: " + err.Error()}) return } req.Header.Set("Content-Type", "application/json") req.Header.Set("Authorization", c.Request.Header.Get("Authorization")) resp, err := httpC.Do(req) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"message": "Error sending request, " + err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"message": "Error sending request: " + err.Error()}) return } respBody, err := io.ReadAll(resp.Body) if err != nil { - c.JSON(http.StatusInternalServerError, gin.H{"message": "Error reading response, " + err.Error()}) + c.JSON(http.StatusInternalServerError, gin.H{"message": "Error reading response: " + err.Error()}) return } defer resp.Body.Close() diff --git a/version.go b/version.go new file mode 100644 index 0000000..cafb00d --- /dev/null +++ b/version.go @@ -0,0 +1,3 @@ +package local_bucketing_proxy + +const Version = "2.2.0" \ No newline at end of file