Skip to content

Commit

Permalink
Merge pull request #280 from paoloromolini/custom_objects_v2
Browse files Browse the repository at this point in the history
Custom objects v2
  • Loading branch information
nukosuke authored Sep 16, 2023
2 parents 518a951 + c7149ad commit a4cebf3
Show file tree
Hide file tree
Showing 4 changed files with 286 additions and 0 deletions.
1 change: 1 addition & 0 deletions zendesk/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ type API interface {
UserFieldAPI
ViewAPI
WebhookAPI
CustomObjectAPI
}

var _ API = (*Client)(nil)
172 changes: 172 additions & 0 deletions zendesk/custom_object.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
package zendesk

import (
"context"
"encoding/json"
"fmt"
"time"
)

type CustomObjectRecord struct {
Url string `json:"url,omitempty"`
Name string `json:"name,omitempty"`
ID string `json:"id,omitempty"`
CustomObjectKey string `json:"custom_object_key"`
CustomObjectFields map[string]interface{} `json:"custom_object_fields" binding:"required"`
CreatedByUserID string `json:"created_by_user_id,omitempty"`
UpdatedByUserID string `json:"updated_by_user_id,omitempty"`
CreatedAt time.Time `json:"created_at,omitempty"`
UpdatedAt time.Time `json:"updated_at,omitempty"`
ExternalID string `json:"external_id,omitempty"`
}

// CustomObjectAPI an interface containing all custom object related methods
type CustomObjectAPI interface {
CreateCustomObjectRecord(
ctx context.Context, record CustomObjectRecord, customObjectKey string) (CustomObjectRecord, error)
SearchCustomObjectRecords(
ctx context.Context,
customObjectKey string,
opts *CustomObjectAutocompleteOptions,
) ([]CustomObjectRecord, Page, error)
ListCustomObjectRecords(
ctx context.Context, customObjectKey string, opts *CustomObjectListOptions) ([]CustomObjectRecord, Page, error)
ShowCustomObjectRecord(
ctx context.Context, customObjectKey string, customObjectRecordID string,
) (*CustomObjectRecord, error)
UpdateCustomObjectRecord(
ctx context.Context, customObjectKey string, customObjectRecordID string, record CustomObjectRecord,
) (*CustomObjectRecord, error)
}

// CustomObjectAutocompleteOptions custom object search options
type CustomObjectAutocompleteOptions struct {
PageOptions
Name string `url:"name"`
}

// CreateCustomObjectRecord CreateCustomObject create a custom object record
func (z *Client) CreateCustomObjectRecord(
ctx context.Context, record CustomObjectRecord, customObjectKey string,
) (CustomObjectRecord, error) {

var data, result struct {
CustomObjectRecord CustomObjectRecord `json:"custom_object_record"`
}
data.CustomObjectRecord = record

body, err := z.post(ctx, fmt.Sprintf("/custom_objects/%s/records.json", customObjectKey), data)
if err != nil {
return CustomObjectRecord{}, err
}
err = json.Unmarshal(body, &result)
if err != nil {
return CustomObjectRecord{}, err
}
return result.CustomObjectRecord, nil
}

// CustomObjectListOptions custom object list options
type CustomObjectListOptions struct {
PageOptions
ExternalIds []string `url:"external_ids"`
}

// ListCustomObjectRecords list objects
// https://developer.zendesk.com/api-reference/custom-objects/custom_object_records/#list-custom-object-records
func (z *Client) ListCustomObjectRecords(
ctx context.Context, customObjectKey string, opts *CustomObjectListOptions) ([]CustomObjectRecord, Page, error) {
var result struct {
CustomObjectRecords []CustomObjectRecord `json:"custom_object_records"`
Page
}
tmp := opts
if tmp == nil {
tmp = &CustomObjectListOptions{}
}
url := fmt.Sprintf("/custom_objects/%s/records", customObjectKey)
urlWithOptions, err := addOptions(url, tmp)
body, err := z.get(ctx, urlWithOptions)

if err != nil {
return nil, Page{}, err
}
err = json.Unmarshal(body, &result)
if err != nil {
return nil, Page{}, err
}
return result.CustomObjectRecords, result.Page, nil
}

// SearchCustomObjectRecords search for a custom object record by the name field
// https://developer.zendesk.com/api-reference/custom-objects/custom_object_records/#search-custom-object-records
func (z *Client) SearchCustomObjectRecords(
ctx context.Context, customObjectKey string, opts *CustomObjectAutocompleteOptions) ([]CustomObjectRecord, Page, error) {
var result struct {
CustomObjectRecords []CustomObjectRecord `json:"custom_object_records"`
Page
}
tmp := opts
if tmp == nil {
tmp = &CustomObjectAutocompleteOptions{}
}
url := fmt.Sprintf("/custom_objects/%s/records/autocomplete", customObjectKey)
urlWithOptions, err := addOptions(url, tmp)
body, err := z.get(ctx, urlWithOptions)

if err != nil {
return nil, Page{}, err
}
err = json.Unmarshal(body, &result)
if err != nil {
return nil, Page{}, err
}
return result.CustomObjectRecords, result.Page, nil
}

// ShowCustomObjectRecord returns a custom record for a specific object using a provided id.
// https://developer.zendesk.com/api-reference/custom-objects/custom_object_records/#show-custom-object-record
func (z *Client) ShowCustomObjectRecord(
ctx context.Context, customObjectKey string, customObjectRecordID string,
) (*CustomObjectRecord, error) {
var result struct {
CustomObjectRecord CustomObjectRecord `json:"custom_object_record"`
}

url := fmt.Sprintf("/custom_objects/%s/records/%s", customObjectKey, customObjectRecordID)
body, err := z.get(ctx, url)

if err != nil {
return nil, err
}
err = json.Unmarshal(body, &result)

if err != nil {
return nil, err
}
return &result.CustomObjectRecord, nil
}

// UpdateCustomObjectRecord Updates an individual custom object record
// https://developer.zendesk.com/api-reference/custom-objects/custom_object_records/#update-custom-object-record
func (z *Client) UpdateCustomObjectRecord(
ctx context.Context, customObjectKey string, customObjectRecordID string, record CustomObjectRecord,
) (*CustomObjectRecord, error) {
var data, result struct {
CustomObjectRecord CustomObjectRecord `json:"custom_object_record"`
}
data.CustomObjectRecord = record

url := fmt.Sprintf("/custom_objects/%s/records/%s", customObjectKey, customObjectRecordID)
body, err := z.patch(ctx, url, data)

if err != nil {
return nil, err
}
err = json.Unmarshal(body, &result)

if err != nil {
return nil, err
}
return &result.CustomObjectRecord, nil
}
77 changes: 77 additions & 0 deletions zendesk/mock/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions zendesk/zendesk.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,42 @@ func (z *Client) put(ctx context.Context, path string, data interface{}) ([]byte
return body, nil
}

// patch sends data to API and returns response body as []bytes
func (z *Client) patch(ctx context.Context, path string, data interface{}) ([]byte, error) {
bytes, err := json.Marshal(data)
if err != nil {
return nil, err
}

req, err := http.NewRequest(http.MethodPatch, z.baseURL.String()+path, strings.NewReader(string(bytes)))
if err != nil {
return nil, err
}

req = z.prepareRequest(ctx, req)

resp, err := z.httpClient.Do(req)
if err != nil {
return nil, err
}

defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}

// NOTE: some webhook mutation APIs return status No Content.
if !(resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNoContent) {
return nil, Error{
body: body,
resp: resp,
}
}

return body, nil
}

// delete sends data to API and returns an error if unsuccessful
func (z *Client) delete(ctx context.Context, path string) error {
req, err := http.NewRequest(http.MethodDelete, z.baseURL.String()+path, nil)
Expand Down

0 comments on commit a4cebf3

Please sign in to comment.