From dabcfd41893e3770081b2143bab7cb821662afec Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Tue, 11 Dec 2018 18:06:04 +0100 Subject: [PATCH 01/12] Add Ticket Search support and fix Ticket unmarshaling --- client.go | 15 ++++++---- search.go | 32 ++++++++++++++++++++++ search_struct.go | 8 ++++++ test/zendesk_test.go | 37 ++++++++++++++++++------- ticket.go | 5 ++-- ticket_struct.go | 65 ++++++++++++++++++++++++-------------------- 6 files changed, 115 insertions(+), 47 deletions(-) create mode 100644 search.go create mode 100644 search_struct.go diff --git a/client.go b/client.go index 426bb1c..85f37f1 100644 --- a/client.go +++ b/client.go @@ -1,14 +1,15 @@ package zendesk import ( - "gopkg.in/resty.v0" - "fmt" "encoding/json" + "fmt" + + "gopkg.in/resty.v0" ) type Client struct { - domain string - client *resty.Client + domain string + client *resty.Client apiVersion string } @@ -20,6 +21,10 @@ func (c Client) Ticket() TicketApiHandler { return TicketApiHandler{c} } +func (c Client) Search() SearchApiHandler { + return SearchApiHandler{c} +} + func (c Client) toFullUrl(path string) string { return fmt.Sprintf("https://%v.zendesk.com/api/%s/%s", c.domain, c.apiVersion, path) } @@ -60,4 +65,4 @@ func (c Client) delete(path string) (*resty.Response, error) { func (c Client) parseResponseToInterface(response *resty.Response, v interface{}) { json.Unmarshal(response.Body(), &v) -} \ No newline at end of file +} diff --git a/search.go b/search.go new file mode 100644 index 0000000..a95c9f2 --- /dev/null +++ b/search.go @@ -0,0 +1,32 @@ +package zendesk + +import ( + "fmt" + + resty "gopkg.in/resty.v0" +) + +type SearchApiHandler struct { + client Client +} + +func (s SearchApiHandler) SearchTickets(searchString string) (TicketSearch, error) { + response, err := s.client.get( + fmt.Sprintf("/search.json?query=type:ticket %s", searchString), + nil, + ) + + if err != nil { + + } + + return s.parseResults(response), err +} + +func (s SearchApiHandler) parseResults(response *resty.Response) TicketSearch { + var object TicketSearch + + s.client.parseResponseToInterface(response, &object) + + return object +} diff --git a/search_struct.go b/search_struct.go new file mode 100644 index 0000000..3e9d733 --- /dev/null +++ b/search_struct.go @@ -0,0 +1,8 @@ +package zendesk + +type TicketSearch struct { + Count int `json:"count,omitempty"` + NextPage string `json:"next_page,omitempty"` + PrevPage string `json:"prev_page,omitempty"` + Tickets []Ticket `json:"results,omitempty"` +} diff --git a/test/zendesk_test.go b/test/zendesk_test.go index d3eba4b..36a5e7d 100644 --- a/test/zendesk_test.go +++ b/test/zendesk_test.go @@ -2,12 +2,13 @@ package test import ( "testing" - "github.com/hellofresh/zendesk-go" + + zendesk "github.com/hellofresh/zendesk-go" ) var client = zendesk.FromToken( zendesk.LoadConfiguration("./../config/configuration.yml"), -); +) var id int @@ -38,7 +39,7 @@ func TestUserApiHandler_GetById(t *testing.T) { func TestUserApiHandler_Create(t *testing.T) { user := zendesk.User{ - Name: "Felipe Pieretti Umpierre", + Name: "Felipe Pieretti Umpierre", Email: "fum@hellofresh.com", } @@ -52,7 +53,7 @@ func TestUserApiHandler_Create(t *testing.T) { func TestUserApiHandler_CreateOrUpdate(t *testing.T) { user := zendesk.User{ - Name: "Felipe Pieretti Umpierre = Updated", + Name: "Felipe Pieretti Umpierre = Updated", Email: "fum@hellofresh.com", } @@ -68,12 +69,12 @@ func TestUserApiHandler_CreateOrUpdateMany(t *testing.T) { var many zendesk.ManyUsers many.AppendUsers(zendesk.User{ - Name: "User 1", + Name: "User 1", Email: "user-1@hellofresh.com", }) many.AppendUsers(zendesk.User{ - Name: "User-2", + Name: "User-2", Email: "user-2@hellofresh.com", }) @@ -96,8 +97,8 @@ func TestUserApiHandler_Delete(t *testing.T) { func TestUserApiHandler_Update(t *testing.T) { user := zendesk.User{ - Id: id, - Name: "Felipe Pieretti Umpierre - hallo", + Id: id, + Name: "Felipe Pieretti Umpierre - hallo", Email: "fum@hellofresh.com", } @@ -109,6 +110,22 @@ func TestUserApiHandler_Update(t *testing.T) { } } +// --------- SEARCH -------- + +func TestSearchApiHandler_Search(t *testing.T) { + tickets, err := client.Search().SearchTickets("TEST") + + if err != nil { + t.Errorf("Error: %s", err) + t.Fail() + } + + for _, ticket := range tickets.Tickets { + id = ticket.Id + break + } +} + // --------- TICKET -------- func TestTicketApiHandler_GetAll(t *testing.T) { @@ -171,7 +188,7 @@ func TestTicketApiHandler_Delete(t *testing.T) { func TestTicketApiHandler_Update(t *testing.T) { ticket := zendesk.Ticket{ - Id: id, + Id: id, Description: "Test ticket", } @@ -181,4 +198,4 @@ func TestTicketApiHandler_Update(t *testing.T) { t.Errorf("Error: %s", err) t.Fail() } -} \ No newline at end of file +} diff --git a/ticket.go b/ticket.go index dcf4a5a..b1a1fa8 100644 --- a/ticket.go +++ b/ticket.go @@ -2,7 +2,8 @@ package zendesk import ( "fmt" - "gopkg.in/resty.v0" + + resty "gopkg.in/resty.v0" ) type TicketApiHandler struct { @@ -97,4 +98,4 @@ func (t TicketApiHandler) parseSingleObject(response *resty.Response) Ticket { t.client.parseResponseToInterface(response, &object) return object.Response -} \ No newline at end of file +} diff --git a/ticket_struct.go b/ticket_struct.go index 1d70c13..abb56e4 100644 --- a/ticket_struct.go +++ b/ticket_struct.go @@ -2,35 +2,40 @@ package zendesk type Via struct{} +type CustomFields struct { + Id int `json:"id,omitempty"` + Value string `json:"value,omitempty"` +} + type Ticket struct { - Id int `json:"id,omitempty"` - Url string `json:"url,omitempty"` - ExternalId string `json:"external_id,omitempty"` - Type string `json:"type,omitempty"` - Subject string `json:"subject,omitempty"` - RawSubject string `json:"raw_subject,omitempty"` - Description string `json:"description,omitempty"` - Priority string `json:"priority,omitempty"` - Status string `json:"status,omitempty"` - Recipient string `json:"recipient,omitempty"` - RequesterId int `json:"requester_id,omitempty"` - SubmitterId int `json:"submitter_id,omitempty"` - AssigneeId int `json:"assignee_id,omitempty"` - OrganizationId int `json:"organization_id,omitempty"` - GroupId int `json:"group_id,omitempty"` - CollaboratorsId []int `json:"collaborators_id,omitempty"` - ForumTopicId int `json:"forum_topic_id,omitempty"` - ProblemId int `json:"problem_id,omitempty"` - HasIncidents bool `json:"has_incidents,omitempty"` - DueAt string `json:"due_at,omitempty"` - Tags []string `json:"tags,omitempty"` - Via *Via `json:"via,omitempty"` - CustomFields []string `json:"custom_fields,omitempty"` - SatisfactionRating []string `json:"satisfaction_rating,omitempty"` - SharingAgreementIds []int `json:"sharing_agreement_ids,omitempty"` - FollowupIds []int `json:"followup_ids,omitempty"` - TicketFormId int `json:"ticket_form_id,omitempty"` - BrandId int `json:"brand_id,omitempty"` - CreatedAt string `json:"created_at,omitempty"` - UpdatedAt string `json:"updated_at,omitempty"` + Id int `json:"id,omitempty"` + Url string `json:"url,omitempty"` + ExternalId string `json:"external_id,omitempty"` + Type string `json:"type,omitempty"` + Subject string `json:"subject,omitempty"` + RawSubject string `json:"raw_subject,omitempty"` + Description string `json:"description,omitempty"` + Priority string `json:"priority,omitempty"` + Status string `json:"status,omitempty"` + Recipient string `json:"recipient,omitempty"` + RequesterId int `json:"requester_id,omitempty"` + SubmitterId int `json:"submitter_id,omitempty"` + AssigneeId int `json:"assignee_id,omitempty"` + OrganizationId int `json:"organization_id,omitempty"` + GroupId int `json:"group_id,omitempty"` + CollaboratorsId []int `json:"collaborators_id,omitempty"` + ForumTopicId int `json:"forum_topic_id,omitempty"` + ProblemId int `json:"problem_id,omitempty"` + HasIncidents bool `json:"has_incidents,omitempty"` + DueAt string `json:"due_at,omitempty"` + Tags []string `json:"tags,omitempty"` + Via *Via `json:"via,omitempty"` + CustomFields []CustomFields `json:"custom_fields,omitempty"` + SatisfactionRating map[string]string `json:"satisfaction_rating,omitempty"` + SharingAgreementIds []int `json:"sharing_agreement_ids,omitempty"` + FollowupIds []int `json:"followup_ids,omitempty"` + TicketFormId int `json:"ticket_form_id,omitempty"` + BrandId int `json:"brand_id,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` } From 89b5bd23214200ea2e851da426192e3c3778d5f5 Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Tue, 11 Dec 2018 18:14:11 +0100 Subject: [PATCH 02/12] Add Ticket Search documentation --- README.md | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index db51008..6174d2a 100644 --- a/README.md +++ b/README.md @@ -182,4 +182,13 @@ Delete an existing ticket ``` client.ZendeskApi().DeleteTicket(1) -``` \ No newline at end of file +``` + +## Search function available + +#### TicketSearch +Return a Search result containg only tickets + +``` +client.ZendeskApi().TicketSearch("Test") +``` From 9f93e3de00a919edc443efe04e6cb7cb27d36618 Mon Sep 17 00:00:00 2001 From: zach-dunton-sf Date: Tue, 11 Dec 2018 18:15:29 +0100 Subject: [PATCH 03/12] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6174d2a..aff9df3 100644 --- a/README.md +++ b/README.md @@ -187,7 +187,7 @@ client.ZendeskApi().DeleteTicket(1) ## Search function available #### TicketSearch -Return a Search result containg only tickets +Return a Search result containing only tickets ``` client.ZendeskApi().TicketSearch("Test") From da449a237a0710dd219c5853d3cae1035d7adfdc Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Fri, 14 Dec 2018 16:37:00 +0100 Subject: [PATCH 04/12] Add support for TicketMetrics, SatisfactionRatings --- builder.go | 21 +++++++++--- client.go | 10 +++++- satisfaction_ratings.go | 33 +++++++++++++++++++ satisfaction_ratings_struct.go | 22 +++++++++++++ test/zendesk_test.go | 2 +- ticket_metrics.go | 58 ++++++++++++++++++++++++++++++++++ ticket_metrics_struct.go | 41 ++++++++++++++++++++++++ 7 files changed, 181 insertions(+), 6 deletions(-) create mode 100644 satisfaction_ratings.go create mode 100644 satisfaction_ratings_struct.go create mode 100644 ticket_metrics.go create mode 100644 ticket_metrics_struct.go diff --git a/builder.go b/builder.go index 99ad46a..2065379 100644 --- a/builder.go +++ b/builder.go @@ -3,9 +3,10 @@ package zendesk import ( "fmt" "io/ioutil" + "os" - "gopkg.in/yaml.v2" - "gopkg.in/resty.v0" + resty "gopkg.in/resty.v0" + yaml "gopkg.in/yaml.v2" ) func FromToken(config ZendeskConfiguration) Client { @@ -16,12 +17,24 @@ func FromToken(config ZendeskConfiguration) Client { restyClient.SetHeader("Content-Type", "application/json") return Client{ - domain: config.Domain, + domain: config.Domain, apiVersion: config.ApiVersion, - client: restyClient, + client: restyClient, } } +func FromEnv() Client { + zendeskConfiguration := ZendeskConfiguration{} + zendeskConfiguration.ApiVersion = os.Getenv("ZENDESK_API_VERSION") + zendeskConfiguration.Domain = os.Getenv("ZENDESK_DOMAIN") + zendeskConfiguration.Email = os.Getenv("ZENDESK_EMAIL") + zendeskConfiguration.Password = os.Getenv("ZENDESK_PASSWORD") + zendeskConfiguration.Token = os.Getenv("ZENDESK_TOKEN") + + fmt.Println(zendeskConfiguration) + return FromToken(zendeskConfiguration) +} + func LoadConfiguration(path string) ZendeskConfiguration { zendeskConfiguration := ZendeskConfiguration{} zendeskConfigurationFile, err := ioutil.ReadFile(path) diff --git a/client.go b/client.go index 85f37f1..ec6c282 100644 --- a/client.go +++ b/client.go @@ -4,7 +4,7 @@ import ( "encoding/json" "fmt" - "gopkg.in/resty.v0" + resty "gopkg.in/resty.v0" ) type Client struct { @@ -25,6 +25,14 @@ func (c Client) Search() SearchApiHandler { return SearchApiHandler{c} } +func (c Client) TicketMetric() TicketMetricApiHandler { + return TicketMetricApiHandler{c} +} + +func (c Client) SatisfactionRating() SatisfactionRatingApiHandler { + return SatisfactionRatingApiHandler{c} +} + func (c Client) toFullUrl(path string) string { return fmt.Sprintf("https://%v.zendesk.com/api/%s/%s", c.domain, c.apiVersion, path) } diff --git a/satisfaction_ratings.go b/satisfaction_ratings.go new file mode 100644 index 0000000..24d3f63 --- /dev/null +++ b/satisfaction_ratings.go @@ -0,0 +1,33 @@ +package zendesk + +import ( + "fmt" + "time" + + resty "gopkg.in/resty.v0" +) + +type SatisfactionRatingApiHandler struct { + client Client +} + +func (s SatisfactionRatingApiHandler) SatisfactionRatings(score string, startDate *time.Time, stopDate *time.Time) (SatisfactionRatings, error) { + response, err := s.client.get( + fmt.Sprintf("/satisfaction_ratings.json?start_time=%d&end_time=%d", startDate.Unix(), stopDate.Unix()), + nil, + ) + + if err != nil { + + } + + return s.parseResults(response), err +} + +func (s SatisfactionRatingApiHandler) parseResults(response *resty.Response) SatisfactionRatings { + var object SatisfactionRatings + + s.client.parseResponseToInterface(response, &object) + + return object +} diff --git a/satisfaction_ratings_struct.go b/satisfaction_ratings_struct.go new file mode 100644 index 0000000..01cb7aa --- /dev/null +++ b/satisfaction_ratings_struct.go @@ -0,0 +1,22 @@ +package zendesk + +import "time" + +type SatisfactionRatings struct { + Count int `json:"count,omitempty"` + NextPage string `json:"next_page,omitempty"` + PrevPage string `json:"prev_page,omitempty"` + SatisfactionRatings []SatisfactionRating `json:"satisfaction_ratings,omitempty"` +} + +type SatisfactionRating struct { + Id int `json:"id,omitempty"` + Url string `json:"url,omitempty"` + AssigneeId int `json:"assignee_id,omitempty"` + GroupId int `json:"group_id,omitempty"` + RequesterId int `json:"requester_id,omitempty"` + TicketId int `json:"ticket_id,omitempty"` + Score string `json:"score,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` +} diff --git a/test/zendesk_test.go b/test/zendesk_test.go index 36a5e7d..147da2e 100644 --- a/test/zendesk_test.go +++ b/test/zendesk_test.go @@ -3,7 +3,7 @@ package test import ( "testing" - zendesk "github.com/hellofresh/zendesk-go" + zendesk "github.com/smartfrog-oss/zendesk-go" ) var client = zendesk.FromToken( diff --git a/ticket_metrics.go b/ticket_metrics.go new file mode 100644 index 0000000..310c5e0 --- /dev/null +++ b/ticket_metrics.go @@ -0,0 +1,58 @@ +package zendesk + +import ( + "fmt" + + resty "gopkg.in/resty.v0" +) + +type TicketMetricApiHandler struct { + client Client +} + +func (s TicketMetricApiHandler) TicketMetrics() (TicketMetrics, error) { + response, err := s.client.get( + fmt.Sprintf("/ticket_metrics.json"), + nil, + ) + + if err != nil { + + } + + return s.parseResults(response), err +} + +func (s TicketMetricApiHandler) TicketMetricsPage(page int) (TicketMetrics, error) { + response, err := s.client.get( + fmt.Sprintf("/ticket_metrics.json?page=%d", page), + nil, + ) + + if err != nil { + + } + + return s.parseResults(response), err +} + +func (s TicketMetricApiHandler) TicketMetricsByName(metricName string) (TicketMetrics, error) { + response, err := s.client.get( + fmt.Sprintf("/ticket_metrics/%s.json", metricName), + nil, + ) + + if err != nil { + + } + + return s.parseResults(response), err +} + +func (s TicketMetricApiHandler) parseResults(response *resty.Response) TicketMetrics { + var object TicketMetrics + + s.client.parseResponseToInterface(response, &object) + + return object +} diff --git a/ticket_metrics_struct.go b/ticket_metrics_struct.go new file mode 100644 index 0000000..d761211 --- /dev/null +++ b/ticket_metrics_struct.go @@ -0,0 +1,41 @@ +package zendesk + +import ( + "time" +) + +type TicketMetrics struct { + Count int `json:"count,omitempty"` + NextPage string `json:"next_page,omitempty"` + PrevPage string `json:"prev_page,omitempty"` + TicketMetrics []TicketMetric `json:"ticket_metrics,omitempty"` +} + +type InMinutes struct { + Calendar int `json:"calendar,omitempty"` + Business int `json:"business,omitempty"` +} + +type TicketMetric struct { + Id int `json:"id,omitempty"` + TicketId int `json:"ticket_id,omitempty"` + Url string `json:"url,omitempty"` + GroupStations int `json:"group_stations,omitempty"` + AssigneeStations int `json:"assignee_stations,omitempty"` + Reopens int `json:"reopens,omitempty"` + Replies int `json:"replies,omitempty"` + AssigneeUpdatedAt *time.Time `json:"assignee_updated_at,omitempty"` + RequesterUpdatedAt *time.Time `json:"requester_updated_at,omitempty"` + StausUpdatedAt *time.Time `json:"status_updated_at,omitempty"` + InitiallyAssignedAt *time.Time `json:"initially_assigned_at,omitempty"` + AssignedAt *time.Time `json:"assigned_at,omitempty"` + SolvedAt *time.Time `json:"solved_at,omitempty"` + LastCommentAddedAt *time.Time `json:"last_comment_added_at,omitempty"` + FirstResolutionTimeInMinutes InMinutes `json:"first_resolution_time_in_minutes,omitempty"` + ReplyTimeInMinutes InMinutes `json:"reply_time_in_minutes,omitempty"` + FullResolutionTimeInMinutes InMinutes `json:"full_resolution_time_in_minutes,omitempty"` + AgentWaitTimeInMinutes InMinutes `json:"agent_wait_time_in_minutes,omitempty"` + RequesterWaitTimeInMinutes InMinutes `json:"requester_wait_time_in_minutes,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` +} From 27a86b919729674860989c9fd1e4e1428c185a1c Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Mon, 17 Dec 2018 16:56:03 +0100 Subject: [PATCH 05/12] Add score to query string when satisfaction ratings are being used --- satisfaction_ratings.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/satisfaction_ratings.go b/satisfaction_ratings.go index 24d3f63..dc51d68 100644 --- a/satisfaction_ratings.go +++ b/satisfaction_ratings.go @@ -12,8 +12,18 @@ type SatisfactionRatingApiHandler struct { } func (s SatisfactionRatingApiHandler) SatisfactionRatings(score string, startDate *time.Time, stopDate *time.Time) (SatisfactionRatings, error) { + var urlString string + + if len(score) > 0) { + formatString = "/satisfaction_ratings.json?start_time=%d&end_time=%d&score=%s" + urlString := fmt.Sprintf(formatString, startDate.Unix(), stopDate.Unix(), score), + } else { + formatString:= "/satisfaction_ratings.json?start_time=%d&end_time=%d" + urlString := fmt.Sprintf(formatString, startDate.Unix(), stopDate.Unix()), + } + response, err := s.client.get( - fmt.Sprintf("/satisfaction_ratings.json?start_time=%d&end_time=%d", startDate.Unix(), stopDate.Unix()), + urlString nil, ) From 650f57213ccd089aca274260a0d7426b7f1ad0ba Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Mon, 17 Dec 2018 16:56:30 +0100 Subject: [PATCH 06/12] Formatting --- adapter.go | 4 +-- glide.lock | 20 +++++++++++++ glide.yaml | 18 ++++++++++++ satisfaction_ratings.go | 14 ++++----- user_struct.go | 65 +++++++++++++++++++++-------------------- 5 files changed, 80 insertions(+), 41 deletions(-) create mode 100644 glide.lock create mode 100644 glide.yaml diff --git a/adapter.go b/adapter.go index 7d1cab1..bdf8be7 100644 --- a/adapter.go +++ b/adapter.go @@ -1,6 +1,6 @@ package zendesk -import "gopkg.in/resty.v0" +import resty "gopkg.in/resty.v0" type ZendeskApi interface { GetById(id int) (interface{}, error) @@ -14,4 +14,4 @@ type ZendeskApi interface { // Parse response parseSingleObject(response *resty.Response) interface{} parseMultiObjects(response *resty.Response) []interface{} -} \ No newline at end of file +} diff --git a/glide.lock b/glide.lock new file mode 100644 index 0000000..f4b2da8 --- /dev/null +++ b/glide.lock @@ -0,0 +1,20 @@ +hash: 27115a2a0af1c783ee899e7a74cf9af7591d1879b16f937a41529aae79d3df79 +updated: 2018-12-17T17:14:56.669947868+01:00 +imports: +- name: github.com/golang/protobuf + version: f0a097ddac24fb00e07d2ac17f8671423f3ea47c + subpackages: + - proto +- name: github.com/ttacon/builder + version: 7f152c3cf4714fd6318739f8f3dbcd14c2a18b39 +- name: github.com/ttacon/libphonenumber + version: 1197dfb91fa03c779576ad248ad5ca0a43fb3a31 +- name: golang.org/x/net + version: 4876518f9e71663000c348837735820161a42df7 + subpackages: + - publicsuffix +- name: gopkg.in/resty.v0 + version: aed15a666de54595af7d8895aa7299ceff5635f8 +- name: gopkg.in/yaml.v2 + version: a83829b6f1293c91addabc89d0571c246397bbf4 +testImports: [] diff --git a/glide.yaml b/glide.yaml new file mode 100644 index 0000000..667a2e5 --- /dev/null +++ b/glide.yaml @@ -0,0 +1,18 @@ +package: github.com/smartfrog-oss/zendesk-go +import: +- package: github.com/golang/protobuf + version: f0a097ddac24fb00e07d2ac17f8671423f3ea47c + subpackages: + - proto +- package: github.com/ttacon/builder + version: 7f152c3cf4714fd6318739f8f3dbcd14c2a18b39 +- package: github.com/ttacon/libphonenumber + version: 1197dfb91fa03c779576ad248ad5ca0a43fb3a31 +- package: golang.org/x/net + version: 4876518f9e71663000c348837735820161a42df7 + subpackages: + - publicsuffix +- package: gopkg.in/resty.v0 + version: ~0.6.0 +- package: gopkg.in/yaml.v2 + version: a83829b6f1293c91addabc89d0571c246397bbf4 diff --git a/satisfaction_ratings.go b/satisfaction_ratings.go index dc51d68..234d01c 100644 --- a/satisfaction_ratings.go +++ b/satisfaction_ratings.go @@ -14,16 +14,16 @@ type SatisfactionRatingApiHandler struct { func (s SatisfactionRatingApiHandler) SatisfactionRatings(score string, startDate *time.Time, stopDate *time.Time) (SatisfactionRatings, error) { var urlString string - if len(score) > 0) { - formatString = "/satisfaction_ratings.json?start_time=%d&end_time=%d&score=%s" - urlString := fmt.Sprintf(formatString, startDate.Unix(), stopDate.Unix(), score), + if len(score) > 0 { + formatString := "/satisfaction_ratings.json?start_time=%d&end_time=%d&score=%s" + urlString = fmt.Sprintf(formatString, startDate.Unix(), stopDate.Unix(), score) } else { - formatString:= "/satisfaction_ratings.json?start_time=%d&end_time=%d" - urlString := fmt.Sprintf(formatString, startDate.Unix(), stopDate.Unix()), + formatString := "/satisfaction_ratings.json?start_time=%d&end_time=%d" + urlString = fmt.Sprintf(formatString, startDate.Unix(), stopDate.Unix()) } - + response, err := s.client.get( - urlString + urlString, nil, ) diff --git a/user_struct.go b/user_struct.go index 27a853c..6a5d3f4 100644 --- a/user_struct.go +++ b/user_struct.go @@ -1,8 +1,9 @@ package zendesk import ( - "github.com/ttacon/libphonenumber" "strings" + + "github.com/ttacon/libphonenumber" ) type ManyUsers struct { @@ -10,36 +11,36 @@ type ManyUsers struct { } type User struct { - Id int`json:"id,omitempty"` - Url string `json:"url,omitempty"` - Name string `json:"name,omitempty"` - ExternalId string `json:"external_id,omitempty"` - Alias string `json:"alias,omitempty"` - CreatedAt string `json:"created_at,omitempty"` - UpdatedAt string `json:"updated_at,omitempty"` - Active bool `json:"active,omitempty"` - Verified bool `json:"verified,omitempty"` - Shared bool `json:"shared,omitempty"` - SharedAgent bool `json:"shared_agent,omitempty"` - Locale string `json:"locale,omitempty"` - LocaleId int `json:"locale_id,omitempty"` - TimeZone string `json:"time_zone,omitempty"` - LastLoginAt string `json:"last_login_at,omitempty"` - Email string `json:"email,omitempty"` - Phone string `json:"phone,omitempty"` - Signature string `json:"signature,omitempty"` - Details string `json:"details,omitempty"` - Notes string `json:"notes,omitempty"` - OrganizationId int `json:"organization_id,omitempty"` - Role string `json:"role,omitempty"` - CustomRoleId string `json:"custom_role_id,omitempty"` - Moderator bool `json:"moderator,omitempty"` - TicketRestriction string `json:"ticket_restriction,omitempty"` - OnlyPrivateComments bool `json:"only_private_comments,omitempty"` - Tags []string `json:"tags,omitempty"` - Suspended bool `json:"suspended,omitempty"` - RestrictedAgent bool `json:"restricted_agent,omitempty"` - Photo *Attachment `json:"photo,omitempty"` + Id int `json:"id,omitempty"` + Url string `json:"url,omitempty"` + Name string `json:"name,omitempty"` + ExternalId string `json:"external_id,omitempty"` + Alias string `json:"alias,omitempty"` + CreatedAt string `json:"created_at,omitempty"` + UpdatedAt string `json:"updated_at,omitempty"` + Active bool `json:"active,omitempty"` + Verified bool `json:"verified,omitempty"` + Shared bool `json:"shared,omitempty"` + SharedAgent bool `json:"shared_agent,omitempty"` + Locale string `json:"locale,omitempty"` + LocaleId int `json:"locale_id,omitempty"` + TimeZone string `json:"time_zone,omitempty"` + LastLoginAt string `json:"last_login_at,omitempty"` + Email string `json:"email,omitempty"` + Phone string `json:"phone,omitempty"` + Signature string `json:"signature,omitempty"` + Details string `json:"details,omitempty"` + Notes string `json:"notes,omitempty"` + OrganizationId int `json:"organization_id,omitempty"` + Role string `json:"role,omitempty"` + CustomRoleId string `json:"custom_role_id,omitempty"` + Moderator bool `json:"moderator,omitempty"` + TicketRestriction string `json:"ticket_restriction,omitempty"` + OnlyPrivateComments bool `json:"only_private_comments,omitempty"` + Tags []string `json:"tags,omitempty"` + Suspended bool `json:"suspended,omitempty"` + RestrictedAgent bool `json:"restricted_agent,omitempty"` + Photo *Attachment `json:"photo,omitempty"` UserFields map[string]interface{} `json:"user_fields,omitempty"` } @@ -56,4 +57,4 @@ func (users *ManyUsers) AppendUsers(user User) []User { users.Users = append(users.Users, user) return users.Users -} \ No newline at end of file +} From 2c88ada6d5a4844f27c83ea53cac58afb811c423 Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Tue, 18 Dec 2018 10:58:23 +0100 Subject: [PATCH 07/12] Add options to search and satisfaction ratings --- satisfaction_ratings.go | 8 ++------ search.go | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/satisfaction_ratings.go b/satisfaction_ratings.go index 234d01c..63629f8 100644 --- a/satisfaction_ratings.go +++ b/satisfaction_ratings.go @@ -12,14 +12,10 @@ type SatisfactionRatingApiHandler struct { } func (s SatisfactionRatingApiHandler) SatisfactionRatings(score string, startDate *time.Time, stopDate *time.Time) (SatisfactionRatings, error) { - var urlString string + urlString := fmt.Sprintf("/satisfaction_ratings.json?start_time=%d&end_time=%d", startDate.Unix(), stopDate.Unix()) if len(score) > 0 { - formatString := "/satisfaction_ratings.json?start_time=%d&end_time=%d&score=%s" - urlString = fmt.Sprintf(formatString, startDate.Unix(), stopDate.Unix(), score) - } else { - formatString := "/satisfaction_ratings.json?start_time=%d&end_time=%d" - urlString = fmt.Sprintf(formatString, startDate.Unix(), stopDate.Unix()) + urlString = fmt.Sprintf(urlString+"&score=%s", score) } response, err := s.client.get( diff --git a/search.go b/search.go index a95c9f2..00b0321 100644 --- a/search.go +++ b/search.go @@ -10,9 +10,19 @@ type SearchApiHandler struct { client Client } -func (s SearchApiHandler) SearchTickets(searchString string) (TicketSearch, error) { +func (s SearchApiHandler) SearchTickets(searchString string, sortBy string, sortOrder string) (TicketSearch, error) { + urlString := fmt.Sprintf("/search.json?query=type:ticket %s", searchString) + + if len(sortBy) > 0 { + urlString = fmt.Sprintf(urlString+"&sort_by=%s", sortBy) + } + + if len(sortBy) > 0 { + urlString = fmt.Sprintf(urlString+"&sort_order=%s", sortOrder) + } + response, err := s.client.get( - fmt.Sprintf("/search.json?query=type:ticket %s", searchString), + urlString, nil, ) From 76b98ba5e6474ba3643a30bbf818149f56a4c201 Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Tue, 18 Dec 2018 11:30:07 +0100 Subject: [PATCH 08/12] Add NextPage and PrevPage functions to search --- search.go | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/search.go b/search.go index 00b0321..10e72ac 100644 --- a/search.go +++ b/search.go @@ -33,6 +33,32 @@ func (s SearchApiHandler) SearchTickets(searchString string, sortBy string, sort return s.parseResults(response), err } +func (s SearchApiHandler) NextPage(t TicketSearch) (TicketSearch, error) { + response, err := s.client.get( + t.NextPage, + nil, + ) + + if err != nil { + + } + + return s.parseResults(response), err +} + +func (s SearchApiHandler) PrevPage(t TicketSearch) (TicketSearch, error) { + response, err := s.client.get( + t.PrevPage, + nil, + ) + + if err != nil { + + } + + return s.parseResults(response), err +} + func (s SearchApiHandler) parseResults(response *resty.Response) TicketSearch { var object TicketSearch From 8b8b508e7a1fd1306b9ed7658ab2f47cb94e2abd Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Tue, 18 Dec 2018 12:23:27 +0100 Subject: [PATCH 09/12] Remove base path from next and previous page urls --- client.go | 6 ++++++ search.go | 7 ++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/client.go b/client.go index ec6c282..5551b4d 100644 --- a/client.go +++ b/client.go @@ -3,6 +3,7 @@ package zendesk import ( "encoding/json" "fmt" + "strings" resty "gopkg.in/resty.v0" ) @@ -37,6 +38,11 @@ func (c Client) toFullUrl(path string) string { return fmt.Sprintf("https://%v.zendesk.com/api/%s/%s", c.domain, c.apiVersion, path) } +func (c Client) toPath(path string) string { + baseURL := fmt.Sprintf("https://%v.zendesk.com/api/%s", c.domain, c.apiVersion) + return strings.Replace(path, baseURL, "", -1) +} + func (c Client) get(path string, params map[string]string) (*resty.Response, error) { resp, err := c.client.R().SetQueryParams(params).Get(c.toFullUrl(path)) diff --git a/search.go b/search.go index 10e72ac..375f205 100644 --- a/search.go +++ b/search.go @@ -2,6 +2,7 @@ package zendesk import ( "fmt" + "log" resty "gopkg.in/resty.v0" ) @@ -35,12 +36,12 @@ func (s SearchApiHandler) SearchTickets(searchString string, sortBy string, sort func (s SearchApiHandler) NextPage(t TicketSearch) (TicketSearch, error) { response, err := s.client.get( - t.NextPage, + s.client.toPath(t.NextPage), nil, ) if err != nil { - + log.Panicln(err) } return s.parseResults(response), err @@ -48,7 +49,7 @@ func (s SearchApiHandler) NextPage(t TicketSearch) (TicketSearch, error) { func (s SearchApiHandler) PrevPage(t TicketSearch) (TicketSearch, error) { response, err := s.client.get( - t.PrevPage, + s.client.toPath(t.PrevPage), nil, ) From 3eb012a68189758394b17de1301c0a37308a90e9 Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Tue, 18 Dec 2018 14:29:43 +0100 Subject: [PATCH 10/12] Handle errors in search --- search.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/search.go b/search.go index 375f205..2696129 100644 --- a/search.go +++ b/search.go @@ -54,7 +54,7 @@ func (s SearchApiHandler) PrevPage(t TicketSearch) (TicketSearch, error) { ) if err != nil { - + return TicketSearch{}, err } return s.parseResults(response), err From 987da6afb071ee176eb24221993b10ceaf44f80c Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Tue, 18 Dec 2018 14:29:58 +0100 Subject: [PATCH 11/12] Set type for createdat and updated at to time --- ticket_struct.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/ticket_struct.go b/ticket_struct.go index abb56e4..9aa34a0 100644 --- a/ticket_struct.go +++ b/ticket_struct.go @@ -1,5 +1,7 @@ package zendesk +import "time" + type Via struct{} type CustomFields struct { @@ -36,6 +38,6 @@ type Ticket struct { FollowupIds []int `json:"followup_ids,omitempty"` TicketFormId int `json:"ticket_form_id,omitempty"` BrandId int `json:"brand_id,omitempty"` - CreatedAt string `json:"created_at,omitempty"` - UpdatedAt string `json:"updated_at,omitempty"` + CreatedAt *time.Time `json:"created_at,omitempty"` + UpdatedAt *time.Time `json:"updated_at,omitempty"` } From bcdd479861b376c71d0439c17b44eee461fd1d6f Mon Sep 17 00:00:00 2001 From: Zach Dunton Date: Tue, 18 Dec 2018 14:34:59 +0100 Subject: [PATCH 12/12] Handle errors in next page --- search.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/search.go b/search.go index 2696129..7e38345 100644 --- a/search.go +++ b/search.go @@ -2,7 +2,6 @@ package zendesk import ( "fmt" - "log" resty "gopkg.in/resty.v0" ) @@ -41,7 +40,7 @@ func (s SearchApiHandler) NextPage(t TicketSearch) (TicketSearch, error) { ) if err != nil { - log.Panicln(err) + return TicketSearch{}, err } return s.parseResults(response), err