Skip to content

Commit

Permalink
Merge pull request #21 from sblackstone/CrmTickets
Browse files Browse the repository at this point in the history
Add support for CRM/Tickets API endpoints
  • Loading branch information
kk-no authored Jul 12, 2023
2 parents e7c15ab + f7e8b0e commit ef44a72
Show file tree
Hide file tree
Showing 3 changed files with 251 additions and 0 deletions.
5 changes: 5 additions & 0 deletions crm.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type CRM struct {
Imports CrmImportsService
Schemas CrmSchemasService
Properties CrmPropertiesService
Tickets CrmTicketsServivce
}

func newCRM(c *Client) *CRM {
Expand All @@ -39,5 +40,9 @@ func newCRM(c *Client) *CRM {
crmPropertiesPath: fmt.Sprintf("%s/%s", crmPath, crmPropertiesPath),
client: c,
},
Tickets: &CrmTicketsServivceOp{
crmTicketsPath: fmt.Sprintf("%s/%s/%s", crmPath, objectsBasePath, crmTicketsBasePath),
client: c,
},
}
}
141 changes: 141 additions & 0 deletions crm_tickets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package hubspot

import "fmt"

const (
crmTicketsBasePath = "tickets"
)

// CrmTicketsServivce is an interface of CRM tickets endpoints of the HubSpot API.
// Reference: https://developers.hubspot.com/docs/api/crm/tickets
type CrmTicketsServivce interface {
List(option *RequestQueryOption) (*CrmTicketsList, error)
Get(ticketId string, option *RequestQueryOption) (*CrmTicket, error)
Create(reqData *CrmTicketCreateRequest) (*CrmTicket, error)
Archive(ticketId string) error
Update(ticketId string, reqData *CrmTicketUpdateRequest) (*CrmTicket, error)
Search(reqData *CrmTicketSearchRequest) (*CrmTicketsList, error)
}

// CrmTicketsServivceOp handles communication with the CRM tickets endpoints of the HubSpot API.
type CrmTicketsServivceOp struct {
client *Client
crmTicketsPath string
}

var _ CrmTicketsServivce = (*CrmTicketsServivceOp)(nil)

type CrmTicket struct {
Id *HsStr `json:"id,omitempty"`
Properties map[string]interface{} `json:"properties,omitempty"`
PropertiesWithHistory map[string]interface{} `json:"propertiesWithHistory,omitempty"`
CreatedAt *HsTime `json:"createdAt,omitempty"`
UpdatedAt *HsTime `json:"updatedAt,omitempty"`
Archived *HsBool `json:"archived,omitempty"`
ArchivedAt *HsTime `json:"archivedAt,omitempty"`
}

type CrmTicketsPagingData struct {
After *HsStr `json:"after,omitempty"`
Link *HsStr `json:"link,omitempty"`
}

type CrmTicketsPaging struct {
Next *CrmTicketsPagingData `json:"next,omitempty"`
}

type CrmTicketsList struct {
Total *HsInt `json:"total,omitempty"`
Results []*CrmTicket `json:"results"`
Paging *CrmTicketsPaging `json:"paging,omitempty"`
}

func (s *CrmTicketsServivceOp) List(option *RequestQueryOption) (*CrmTicketsList, error) {
var resource CrmTicketsList
if err := s.client.Get(s.crmTicketsPath, &resource, option); err != nil {
return nil, err
}
return &resource, nil
}

func (s *CrmTicketsServivceOp) Get(ticketId string, option *RequestQueryOption) (*CrmTicket, error) {
var resource CrmTicket
path := fmt.Sprintf("%s/%s", s.crmTicketsPath, ticketId)
if err := s.client.Get(path, &resource, option); err != nil {
return nil, err
}
return &resource, nil
}

type CrmTicketAssociationTarget struct {
Id *HsStr `json:"id,omitempty"`
}

type CrmTicketAssociationType struct {
AssociationCategory *HsStr `json:"associationCategory,omitempty"`
AssociationTypeId *HsInt `json:"associationTypeId,omitempty"`
}

type CrmTicketAssociation struct {
To CrmTicketAssociationTarget `json:"to,omitempty"`
Types []CrmTicketAssociationType `json:"types,omitempty"`
}

type CrmTicketCreateRequest struct {
Properties map[string]interface{} `json:"properties,omitempty"`
Associations []*CrmTicketAssociation `json:"associations,omitempty"`
}

type CrmTicketUpdateRequest = CrmTicketCreateRequest

func (s *CrmTicketsServivceOp) Create(reqData *CrmTicketCreateRequest) (*CrmTicket, error) {
var resource CrmTicket
if err := s.client.Post(s.crmTicketsPath, reqData, &resource); err != nil {
return nil, err
}
return &resource, nil
}

func (s *CrmTicketsServivceOp) Archive(ticketId string) error {
path := fmt.Sprintf("%s/%s", s.crmTicketsPath, ticketId)
return s.client.Delete(path, nil)
}

func (s *CrmTicketsServivceOp) Update(ticketId string, reqData *CrmTicketUpdateRequest) (*CrmTicket, error) {
var resource CrmTicket
path := fmt.Sprintf("%s/%s", s.crmTicketsPath, ticketId)
if err := s.client.Patch(path, reqData, &resource); err != nil {
return nil, err
}
return &resource, nil
}

type CrmTicketSearchFilter struct {
Value *HsStr `json:"value,omitempty"`
HighValue *HsStr `json:"highValue,omitempty"`
Values []*HsStr `json:"values,omitempty"`
PropertyName *HsStr `json:"propertyName,omitempty"`
Operator *HsStr `json:"operator,omitempty"`
}

type CrmTicketSearchFilterGroup struct {
Filters []*CrmTicketSearchFilter `json:"filters,omitempty"`
Sorts []*HsStr `json:"sorts,omitempty"`
Query *HsStr `json:"query"`
Properties []*HsStr `json:"properties,omitempty"`
Limit *HsInt `json:"limit,omitempty"`
After *HsInt `json:"after,omitempty"`
}

type CrmTicketSearchRequest struct {
FilterGroups []*CrmTicketSearchFilterGroup `json:"filterGroups,omitempty"`
}

func (s *CrmTicketsServivceOp) Search(reqData *CrmTicketSearchRequest) (*CrmTicketsList, error) {
var resource CrmTicketsList
path := fmt.Sprintf("%s/search", s.crmTicketsPath)
if err := s.client.Post(path, reqData, &resource); err != nil {
return nil, err
}
return &resource, nil
}
105 changes: 105 additions & 0 deletions crm_tickets_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package hubspot

import (
"fmt"
"os"
"testing"
)

func TestListTickets(t *testing.T) {
t.SkipNow()
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
opt := &RequestQueryOption{}
opt.Properties = []string{"Content"}
res, err := cli.CRM.Tickets.List(opt)
if err != nil {
t.Error(err)
}
fmt.Printf("%+v\n", res)
fmt.Printf("%+v\n", res.Results[0])
}

func TestGetCrmTicket(t *testing.T) {
t.SkipNow()
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
opt := &RequestQueryOption{}
opt.Properties = []string{"Content", "associated_contact_lifecycle_stage", "hubspot_owner_id"}
res, err := cli.CRM.Tickets.Get("1594949554", opt)
if err != nil {
t.Error(err)
}
fmt.Printf("%+v\n", res)
}

func TestCreateCrmTicket(t *testing.T) {
t.SkipNow()
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
props := make(map[string]interface{})
props["hs_pipeline"] = "30440034"
props["hs_pipeline_stage"] = "69304142"
props["hubspot_owner_id"] = "301296186"
props["hs_ticket_priority"] = "LOW"
props["content"] = "this would be some content"
props["subject"] = "testing, please ignore"
req := &CrmTicketCreateRequest{
Properties: props,
}
res, err := cli.CRM.Tickets.Create(req)
if err != nil {
t.Error(err)
}
fmt.Printf("%+v\n", res)
}

func TestDeleteCrmTicket(t *testing.T) {
t.SkipNow()
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
err := cli.CRM.Tickets.Archive("1594967688")
if err != nil {
t.Error(err)
}
}

func TestUpdateCrmTicket(t *testing.T) {
t.SkipNow()
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
props := make(map[string]interface{})
props["hs_ticket_priority"] = "HIGH"
req := &CrmTicketCreateRequest{
Properties: props,
}
res, err := cli.CRM.Tickets.Update("1594957134", req)
if err != nil {
t.Error(err)
}
fmt.Printf("%+v\n", res)
}

func TestSearchCrmTicket(t *testing.T) {
t.SkipNow()

cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))

req := &CrmTicketSearchRequest{
FilterGroups: []*CrmTicketSearchFilterGroup{
{
Filters: []*CrmTicketSearchFilter{
{
Value: NewString("LOW"),
PropertyName: NewString("hs_ticket_priority"),
Operator: NewString("EQ"),
},
},
},
},
}

res, err := cli.CRM.Tickets.Search(req)
if err != nil {
t.Error(err)
}

for _, ticket := range res.Results {
fmt.Printf("%+v\n", ticket)
}
}

0 comments on commit ef44a72

Please sign in to comment.