-
Notifications
You must be signed in to change notification settings - Fork 24
feat(admin): add Triggers API for webhook notification management #130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
NitriKx
wants to merge
1
commit into
cloudinary:main
Choose a base branch
from
NitriKx:bsa/add-triggers-webhook-api
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+228
−0
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| package admin | ||
|
|
||
| // Enables you to manage webhook notification triggers for your Cloudinary product environment. | ||
| // | ||
| // https://cloudinary.com/documentation/notifications | ||
|
|
||
| import ( | ||
| "context" | ||
|
|
||
| "github.com/cloudinary/cloudinary-go/v2/api" | ||
| ) | ||
|
|
||
| const ( | ||
| triggersEndpoint api.EndPoint = "triggers" | ||
| ) | ||
|
|
||
| // Trigger represents a single webhook notification trigger. | ||
| type Trigger struct { | ||
| ID string `json:"id,omitempty"` | ||
| URI string `json:"uri,omitempty"` | ||
| EventType string `json:"event_type,omitempty"` | ||
| Additive bool `json:"additive"` | ||
| Filter map[string]any `json:"filter,omitempty"` | ||
| FilterLanguage string `json:"filter_language,omitempty"` | ||
| PayloadTemplate map[string]any `json:"payload_template,omitempty"` | ||
| AuthScheme string `json:"auth_scheme,omitempty"` | ||
| ProductEnvironmentID string `json:"product_environment_id,omitempty"` | ||
| URIType string `json:"uri_type,omitempty"` | ||
| CreatedAt string `json:"created_at,omitempty"` | ||
| UpdatedAt string `json:"updated_at,omitempty"` | ||
| } | ||
|
|
||
| // ListTriggersParams are the parameters for ListTriggers. | ||
| type ListTriggersParams struct{} | ||
|
|
||
| // ListTriggersResult is the result of ListTriggers. | ||
| type ListTriggersResult struct { | ||
| Triggers []Trigger `json:"triggers"` | ||
| Error api.ErrorResp `json:"error,omitempty"` | ||
| } | ||
|
|
||
| // ListTriggers lists all webhook notification triggers for the product environment. | ||
| func (a *API) ListTriggers(ctx context.Context, params ListTriggersParams) (*ListTriggersResult, error) { | ||
| res := &ListTriggersResult{} | ||
| _, err := a.get(ctx, triggersEndpoint, params, res) | ||
| return res, err | ||
| } | ||
|
|
||
| // GetTriggerParams are the parameters for GetTrigger. | ||
| type GetTriggerParams struct { | ||
| TriggerID string `json:"-"` | ||
| } | ||
|
|
||
| // GetTriggerResult is the result of GetTrigger. | ||
| type GetTriggerResult struct { | ||
| Trigger | ||
| Error api.ErrorResp `json:"error,omitempty"` | ||
| } | ||
|
|
||
| // GetTrigger retrieves a single webhook notification trigger by its ID. | ||
| // Cloudinary does not expose a single-resource GET endpoint, so this is | ||
| // implemented as ListTriggers filtered to the matching ID. | ||
| func (a *API) GetTrigger(ctx context.Context, params GetTriggerParams) (*GetTriggerResult, error) { | ||
| list, err := a.ListTriggers(ctx, ListTriggersParams{}) | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| if list.Error.Message != "" { | ||
| return &GetTriggerResult{Error: list.Error}, nil | ||
| } | ||
| for _, t := range list.Triggers { | ||
| if t.ID == params.TriggerID { | ||
| return &GetTriggerResult{Trigger: t}, nil | ||
| } | ||
| } | ||
| // Not found — return empty result with no error; caller checks ID == "". | ||
| return &GetTriggerResult{}, nil | ||
| } | ||
|
|
||
| // CreateTriggerParams are the parameters for CreateTrigger. | ||
| type CreateTriggerParams struct { | ||
| URI string `json:"uri"` | ||
| EventType string `json:"event_type"` | ||
| Additive bool `json:"additive,omitempty"` | ||
| Filter map[string]any `json:"filter,omitempty"` | ||
| FilterLanguage string `json:"filter_language,omitempty"` | ||
| PayloadTemplate map[string]any `json:"payload_template,omitempty"` | ||
| AuthScheme string `json:"auth_scheme,omitempty"` | ||
| } | ||
|
|
||
| // CreateTriggerResult is the result of CreateTrigger. | ||
| type CreateTriggerResult struct { | ||
| Trigger | ||
| Error api.ErrorResp `json:"error,omitempty"` | ||
| } | ||
|
|
||
| // CreateTrigger creates a new webhook notification trigger. | ||
| func (a *API) CreateTrigger(ctx context.Context, params CreateTriggerParams) (*CreateTriggerResult, error) { | ||
| res := &CreateTriggerResult{} | ||
| _, err := a.post(ctx, triggersEndpoint, params, res) | ||
| return res, err | ||
| } | ||
|
|
||
| // UpdateTriggerParams are the parameters for UpdateTrigger. | ||
| type UpdateTriggerParams struct { | ||
| TriggerID string `json:"-"` | ||
| URI string `json:"uri,omitempty"` | ||
| EventType string `json:"event_type,omitempty"` | ||
| Additive *bool `json:"additive,omitempty"` | ||
| Filter map[string]any `json:"filter,omitempty"` | ||
| FilterLanguage string `json:"filter_language,omitempty"` | ||
| PayloadTemplate map[string]any `json:"payload_template,omitempty"` | ||
| AuthScheme string `json:"auth_scheme,omitempty"` | ||
| } | ||
|
|
||
| // UpdateTriggerResult is the result of UpdateTrigger. | ||
| type UpdateTriggerResult struct { | ||
| Trigger | ||
| Error api.ErrorResp `json:"error,omitempty"` | ||
| } | ||
|
|
||
| // UpdateTrigger updates an existing webhook notification trigger. | ||
| func (a *API) UpdateTrigger(ctx context.Context, params UpdateTriggerParams) (*UpdateTriggerResult, error) { | ||
| res := &UpdateTriggerResult{} | ||
| _, err := a.put(ctx, api.BuildPath(triggersEndpoint, params.TriggerID), params, res) | ||
| return res, err | ||
| } | ||
|
|
||
| // DeleteTriggerParams are the parameters for DeleteTrigger. | ||
| type DeleteTriggerParams struct { | ||
| TriggerID string `json:"-"` | ||
| } | ||
|
|
||
| // DeleteTriggerResult is the result of DeleteTrigger. | ||
| type DeleteTriggerResult struct { | ||
| Message string `json:"message,omitempty"` | ||
| Error api.ErrorResp `json:"error,omitempty"` | ||
| } | ||
|
|
||
| // DeleteTrigger deletes a webhook notification trigger by its ID. | ||
| func (a *API) DeleteTrigger(ctx context.Context, params DeleteTriggerParams) (*DeleteTriggerResult, error) { | ||
| res := &DeleteTriggerResult{} | ||
| _, err := a.delete(ctx, api.BuildPath(triggersEndpoint, params.TriggerID), params, res) | ||
| return res, err | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| package admin_test | ||
|
|
||
| import ( | ||
| "testing" | ||
|
|
||
| "github.com/cloudinary/cloudinary-go/v2/api/admin" | ||
| "github.com/stretchr/testify/assert" | ||
| ) | ||
|
|
||
| const testTriggerURI = "https://example.com/000-go-trigger-test" | ||
|
|
||
| var testTriggerID string | ||
|
|
||
| func TestTriggers_CreateTrigger(t *testing.T) { | ||
| resp, err := adminAPI.CreateTrigger(ctx, admin.CreateTriggerParams{ | ||
| URI: testTriggerURI, | ||
| EventType: "upload", | ||
| }) | ||
|
|
||
| if err != nil || resp.Error.Message != "" { | ||
| t.Error(resp, err) | ||
| return | ||
| } | ||
|
|
||
| testTriggerID = resp.ID | ||
| assert.NotEmpty(t, testTriggerID) | ||
| } | ||
|
|
||
| func TestTriggers_ListTriggers(t *testing.T) { | ||
| resp, err := adminAPI.ListTriggers(ctx, admin.ListTriggersParams{}) | ||
|
|
||
| if err != nil || resp.Error.Message != "" { | ||
| t.Error(resp, err) | ||
| } | ||
| } | ||
|
|
||
| func TestTriggers_GetTrigger(t *testing.T) { | ||
| if testTriggerID == "" { | ||
| t.Skip("create trigger test did not run or failed") | ||
| } | ||
|
|
||
| resp, err := adminAPI.GetTrigger(ctx, admin.GetTriggerParams{ | ||
| TriggerID: testTriggerID, | ||
| }) | ||
|
|
||
| if err != nil || resp.Error.Message != "" { | ||
| t.Error(resp, err) | ||
| return | ||
| } | ||
|
|
||
| assert.Equal(t, testTriggerID, resp.ID) | ||
| } | ||
|
|
||
| func TestTriggers_UpdateTrigger(t *testing.T) { | ||
| if testTriggerID == "" { | ||
| t.Skip("create trigger test did not run or failed") | ||
| } | ||
|
|
||
| resp, err := adminAPI.UpdateTrigger(ctx, admin.UpdateTriggerParams{ | ||
| TriggerID: testTriggerID, | ||
| URI: testTriggerURI, | ||
| EventType: "upload", | ||
| AuthScheme: "default", | ||
| }) | ||
|
|
||
| if err != nil || resp.Error.Message != "" { | ||
| t.Error(resp, err) | ||
| } | ||
| } | ||
|
|
||
| func TestTriggers_DeleteTrigger(t *testing.T) { | ||
| if testTriggerID == "" { | ||
| t.Skip("create trigger test did not run or failed") | ||
| } | ||
|
|
||
| resp, err := adminAPI.DeleteTrigger(ctx, admin.DeleteTriggerParams{ | ||
| TriggerID: testTriggerID, | ||
| }) | ||
|
|
||
| if err != nil || resp.Error.Message != "" { | ||
| t.Error(resp, err) | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's drop this one. The API itself doesn't support it.
Current implementation is trivial, anyone can implement it in their code.
The real reason for dropping it, is if/when it will be implemented in the API side, it might have different structure and it will introduce a breaking change, which we would like to avoid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All right 👀
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for you comment it's fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NitriKx I see no change, was it pushed?