Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions fixture/GET/custom_ticket_status.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"custom_status": {
"active": true,
"agent_label": "Responding quickly",
"created_at": "2021-07-20T22:55:29Z",
"default": false,
"description": "Customer needs a response quickly",
"end_user_description": "Your ticket is being responded to",
"end_user_label": "Urgent processing",
"id": 35436,
"raw_agent_label": "Responding quickly",
"raw_description": "Customer needs a response quickly",
"raw_end_user_description": "Your ticket is being responded to",
"raw_end_user_label": "Urgent processing",
"status_category": "open",
"updated_at": "2021-07-20T22:55:29Z"
}
}
36 changes: 36 additions & 0 deletions fixture/GET/custom_ticket_statuses.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"custom_statuses": [
{
"active": true,
"agent_label": "Responding quickly",
"created_at": "2021-07-20T22:55:29Z",
"default": false,
"description": "Customer needs a response quickly",
"end_user_description": "Your ticket is being responded to",
"end_user_label": "Urgent processing",
"id": 35436,
"raw_agent_label": "Responding quickly",
"raw_description": "Customer needs a response quickly",
"raw_end_user_description": "Your ticket is being responded to",
"raw_end_user_label": "Urgent processing",
"status_category": "open",
"updated_at": "2021-07-20T22:55:29Z"
},
{
"active": true,
"agent_label": "Responding quickly",
"created_at": "2021-07-20T22:55:29Z",
"default": false,
"description": "Need team action",
"end_user_description": "Your ticket is being responded to",
"end_user_label": "Low Priority",
"id": 32451,
"raw_agent_label": "Responding quickly",
"raw_description": "Need team action",
"raw_end_user_description": "Your ticket is being responded to",
"raw_end_user_label": "test processing",
"status_category": "open",
"updated_at": "2021-07-20T22:55:29Z"
}
]
}
18 changes: 18 additions & 0 deletions fixture/POST/custom_ticket_status.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"custom_status": {
"active": true,
"agent_label": "Responding quickly",
"created_at": "2021-07-20T22:55:29Z",
"default": false,
"description": "Customer needs a response quickly",
"end_user_description": "Your ticket is being responded to",
"end_user_label": "Urgent processing",
"id": 35436,
"raw_agent_label": "Responding quickly",
"raw_description": "Customer needs a response quickly",
"raw_end_user_description": "Your ticket is being responded to",
"raw_end_user_label": "Urgent processing",
"status_category": "open",
"updated_at": "2021-07-20T22:55:29Z"
}
}
18 changes: 18 additions & 0 deletions fixture/PUT/custom_ticket_status.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"custom_status": {
"active": true,
"agent_label": "Responding quickly",
"created_at": "2021-07-20T22:55:29Z",
"default": false,
"description": "Customer needs a response quickly",
"end_user_description": "Your ticket is being responded to",
"end_user_label": "Urgent processing",
"id": 35436,
"raw_agent_label": "Responding quickly",
"raw_description": "Customer needs a response quickly",
"raw_end_user_description": "Your ticket is being responded to",
"raw_end_user_label": "Urgent processing",
"status_category": "open",
"updated_at": "2021-07-20T22:55:29Z"
}
}
4 changes: 4 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ require (

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/mod v0.11.0 // indirect
golang.org/x/sys v0.1.0 // indirect
golang.org/x/tools v0.2.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
31 changes: 31 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
Expand All @@ -9,9 +11,38 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU=
go.uber.org/mock v0.4.0/go.mod h1:a6FSlNadKUHUa9IP5Vyt1zh4fC7uAwxMutEAscFbkZc=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE=
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
Expand Down
1 change: 1 addition & 0 deletions zendesk/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ type API interface {
BaseAPI
BrandAPI
CustomRoleAPI
CustomTicketStatusAPI
DynamicContentAPI
GroupAPI
GroupMembershipAPI
Expand Down
196 changes: 196 additions & 0 deletions zendesk/custom_ticket_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
package zendesk

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

type CustomTicketStatus struct {
Active bool `json:"active,omitempty"`
AgentLabel string `json:"agent_label,omitempty"`
CreatedAt *time.Time `json:"created_at,omitempty"`
Default bool `json:"default,omitempty"`
Description string `json:"description,omitempty"`
EndUserDescription string `json:"end_user_description,omitempty"`
EndUserLabel string `json:"end_user_label,omitempty"`
ID int64 `json:"id,omitempty"`
RawAgentLabel string `json:"raw_agent_label,omitempty"`
RawDescription string `json:"raw_description,omitempty"`
RawEndUserDescription string `json:"raw_end_user_description,omitempty"`
RawEndUserLabel string `json:"raw_end_user_label,omitempty"`
StatusCategory string `json:"status_category,omitempty"`
UpdatedAt *time.Time `json:"updated_at,omitempty"`
}

type CustomTicketStatusCreateOption struct {
// If true, show only active custom ticket statuses. If false, show only inactive custom ticket statuses. If the filter is not used, show all custom ticket statuses
Active bool `json:"active,omitempty"`

// The dynamic content placeholder or the label displayed to agents. Maximum length for displayed label is 48 characters
AgentLabel string `json:"agent_label,omitempty"`

// The description of when the user should select this custom ticket status
Description string `json:"description,omitempty"`

// The description displayed to end users
EndUserDescription string `json:"end_user_description,omitempty"`

// The dynamic content placeholder or the label displayed to end users. Maximum length for displayed label is 48 characters
EndUserLabel string `json:"end_user_label,omitempty"`

// The status category the custom status belongs to. Allowed values are "new", "open", "pending", "hold", or "solved"
StatusCategory string `json:"status_category,omitempty"`
}

type CustomTicketStatusUpdateOption struct {
// If true, show only active custom ticket statuses. If false, show only inactive custom ticket statuses. If the filter is not used, show all custom ticket statuses
Active bool `json:"active,omitempty"`

// The dynamic content placeholder or the label displayed to agents. Maximum length for displayed label is 48 characters
AgentLabel string `json:"agent_label,omitempty"`

// The description of when the user should select this custom ticket status
Description string `json:"description,omitempty"`

// The description displayed to end users
EndUserDescription string `json:"end_user_description,omitempty"`

// The dynamic content placeholder or the label displayed to end users. Maximum length for displayed label is 48 characters
EndUserLabel string `json:"end_user_label,omitempty"`
}

type CustomTicketStatusListOptions struct {
// If true, show only active custom ticket statuses. If false, show only inactive custom ticket statuses. If the filter is not used, show all custom ticket statuses
Active bool

// If true, show only default custom ticket statuses. If false, show only non-default custom ticket statuses. If the filter is not used, show all custom ticket statuses
Default bool

// Filter the list of custom ticket statuses by a comma-separated list of status categories
StatusCategories string
}

type CustomTicketStatusListResult struct {
CustomTicketStatuses []CustomTicketStatus `json:"custom_statuses"`
}

// CustomTicketStatusAPI an interface containing all custom ticket status related methods
type CustomTicketStatusAPI interface {
GetCustomTicketStatuses(ctx context.Context, opts *CustomTicketStatusListOptions) ([]CustomTicketStatus, error)
GetCustomTicketStatus(ctx context.Context, customTicketStatusID int64) (CustomTicketStatus, error)
CreateCustomTicketStatus(ctx context.Context, customTicketStatusCreateOptions CustomTicketStatusCreateOption) (CustomTicketStatus, error)
UpdateCustomTicketStatus(ctx context.Context, customTicketStatusID int64, customTicketStatus CustomTicketStatusUpdateOption) (CustomTicketStatus, error)
}

// GetCustomTicketStatuses: Lists all undeleted custom ticket statuses for the account. No pagination is provided.
//
// ref: https://developer.zendesk.com/api-reference/ticketing/tickets/custom_ticket_statuses/#list-custom-ticket-statuses
func (z *Client) GetCustomTicketStatuses(ctx context.Context, opts *CustomTicketStatusListOptions) ([]CustomTicketStatus, error) {
var data struct {
CustomTicketStatuses []CustomTicketStatus `json:"custom_statuses"`
}

tmp := opts
if tmp == nil {
tmp = &CustomTicketStatusListOptions{}
}

u, err := addOptions("/custom_statuses.json", tmp)
if err != nil {
return nil, err
}

body, err := z.get(ctx, u)
if err != nil {
return nil, err
}

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

// GetCustomTicketStatus: Returns the custom ticket status object.
//
// ref:https://developer.zendesk.com/api-reference/ticketing/tickets/custom_ticket_statuses/#show-custom-ticket-status
func (z *Client) GetCustomTicketStatus(ctx context.Context, customTicketStatusID int64) (CustomTicketStatus, error) {
var result struct {
CustomTicketStatus CustomTicketStatus `json:"custom_status"`
}

body, err := z.get(ctx, fmt.Sprintf("/custom_statuses/%d.json", customTicketStatusID))
if err != nil {
return CustomTicketStatus{}, err
}

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

return result.CustomTicketStatus, err
}

// CreateCustomTicketStatus: Takes a CustomTicketStatusCreateOption object that specifies the custom ticket status properties to create.
//
// ref:https://developer.zendesk.com/api-reference/ticketing/tickets/custom_ticket_statuses/#create-custom-ticket-status
func (z *Client) CreateCustomTicketStatus(ctx context.Context, customTicketStatus CustomTicketStatusCreateOption) (CustomTicketStatus, error) {
var data struct {
CustomTicketStatus CustomTicketStatusCreateOption `json:"custom_status"`
}

var result struct {
CustomTicketStatus CustomTicketStatus `json:"custom_status"`
}

data.CustomTicketStatus = customTicketStatus

body, err := z.Post(ctx, "/custom_statuses.json", data)
if err != nil {
return CustomTicketStatus{}, err
}

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

return result.CustomTicketStatus, err
}

// UpdateCustomTicketStatus: Takes a CustomTicketStatusUpdateOption object that specifies the custom ticket status properties to update.
//
// ref:https://developer.zendesk.com/api-reference/ticketing/tickets/custom_ticket_statuses/#update-custom-ticket-status
func (z *Client) UpdateCustomTicketStatus(ctx context.Context, customTicketStatusID int64, customTicketStatus CustomTicketStatusUpdateOption) (CustomTicketStatus, error) {
var data struct {
CustomTicketStatus CustomTicketStatusUpdateOption `json:"custom_status"`
}
var result struct {
CustomTicketStatus CustomTicketStatus `json:"custom_status"`
}

data.CustomTicketStatus = customTicketStatus

path := fmt.Sprintf("/custom_statuses/%d.json", customTicketStatusID)

body, err := z.put(ctx, path, data)
if err != nil {
return CustomTicketStatus{}, err
}

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

return result.CustomTicketStatus, err
}

// Custom statuses can't be deleted at this time.
// If you deactivate a custom status, it won't be available in the status picker and agents won't be able to use it.
// You can also edit a custom status and change its name, description, etc.
// ref: https://support.zendesk.com/hc/en-us/articles/4412575941402-Managing-ticket-statuses
Loading