Skip to content

Commit 9ab8beb

Browse files
committed
Add support for CRM Schemas and CRM Properties API
1 parent bf87cc8 commit 9ab8beb

11 files changed

+526
-9
lines changed

contact.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ func (s *ContactServiceOp) Update(contactID string, contact interface{}) (*Respo
355355

356356
// Delete deletes a contact.
357357
func (s *ContactServiceOp) Delete(contactID string) error {
358-
return s.client.Delete(s.contactPath + "/" + contactID)
358+
return s.client.Delete(s.contactPath+"/"+contactID, nil)
359359
}
360360

361361
// AssociateAnotherObj associates Contact with another HubSpot objects.

crm.go

+13-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,11 @@ const (
99
)
1010

1111
type CRM struct {
12-
Contact ContactService
13-
Deal DealService
14-
Imports CrmImportsService
12+
Contact ContactService
13+
Deal DealService
14+
Imports CrmImportsService
15+
Schemas CrmSchemasService
16+
Properties CrmPropertiesService
1517
}
1618

1719
func newCRM(c *Client) *CRM {
@@ -29,5 +31,13 @@ func newCRM(c *Client) *CRM {
2931
crmImportsPath: fmt.Sprintf("%s/%s", crmPath, crmImportsBasePath),
3032
client: c,
3133
},
34+
Schemas: &CrmSchemasServiceOp{
35+
crmSchemasPath: fmt.Sprintf("%s/%s", crmPath, crmSchemasPath),
36+
client: c,
37+
},
38+
Properties: &CrmPropertiesServiceOp{
39+
crmPropertiesPath: fmt.Sprintf("%s/%s", crmPath, crmPropertiesPath),
40+
client: c,
41+
},
3242
}
3343
}

crm_imports_start.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,10 @@ import (
1010
)
1111

1212
type CrmImportConfig struct {
13-
Name string `json:"name"`
14-
ImportOperations map[string]string `json:"importOperations"`
15-
Files []CrmImportFileConfig `json:"files"`
13+
Name string `json:"name"`
14+
MarketableContactImport bool `json:"marketableContactImport"`
15+
ImportOperations map[string]string `json:"importOperations"`
16+
Files []CrmImportFileConfig `json:"files"`
1617
}
1718

1819
type CrmImportFilePageConfig struct {

crm_properties.go

+113
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package hubspot
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
const (
8+
crmPropertiesPath = "properties"
9+
)
10+
11+
type CrmPropertiesList struct {
12+
Results []*CrmProperty `json:"results,omitempty"`
13+
}
14+
15+
type CrmProperty struct {
16+
UpdatedAt *HsTime `json:"updatedAt,omitempty"`
17+
CreatedAt *HsTime `json:"createdAt,omitempty"`
18+
ArchivedAt *HsTime `json:"archivedAt,omitempty"`
19+
Name *HsStr `json:"name,omitempty"`
20+
Label *HsStr `json:"label,omitempty"`
21+
Type *HsStr `json:"type,omitempty"`
22+
FieldType *HsStr `json:"fieldType,omitempty"`
23+
Description *HsStr `json:"description,omitempty"`
24+
GroupName *HsStr `json:"groupName,omitempty"`
25+
Options []*CrmPropertyOptions `json:"options,omitempty"`
26+
CreatedUserId *HsStr `json:"createdUserId,omitempty"`
27+
UpdatedUserId *HsStr `json:"updatedUserId,omitempty"`
28+
ReferencedObjectType *HsStr `json:"referencedObjectType,omitempty"`
29+
DisplayOrder *HsInt `json:"displayOrder,omitempty"`
30+
Calculated *HsBool `json:"calculated,omitempty"`
31+
ExternalOptions *HsBool `json:"externalOptions,omitempty"`
32+
Archived *HsBool `json:"archived,omitempty"`
33+
HasUniqueValue *HsBool `json:"hasUniqueValue,omitempty"`
34+
Hidden *HsBool `json:"hidden,omitempty"`
35+
HubspotDefined *HsBool `json:"hubspotDefined,omitempty"`
36+
ShowCurrencySymbol *HsBool `json:"showCurrencySymbol,omitempty"`
37+
ModificationMetaData *CrmPropertyModificationMeta `json:"modificationMetadata,omitempty"`
38+
FormField *HsBool `json:"formField,omitempty"`
39+
CalculationFormula *HsStr `json:"calculationFormula,omitempty"`
40+
}
41+
42+
type CrmPropertyModificationMeta struct {
43+
Archivable *HsBool `json:"archivable,omitempty"`
44+
ReadOnlyDefition *HsBool `json:"readOnlyDefinition,omitempty"`
45+
ReadOnlyValue *HsBool `json:"readOnlyValue,omitempty"`
46+
ReadOnlyOptions *HsBool `json:"readOnlyOptions,omitempty"`
47+
}
48+
type CrmPropertyOptions struct {
49+
Label *HsStr `json:"label,omitempty"`
50+
Value *HsStr `json:"value,omitempty"`
51+
Description *HsStr `json:"description,omitempty"`
52+
DisplayOrder *HsInt `json:"displayOrder,omitempty"`
53+
Hidden *HsBool `json:"hidden,omitempty"`
54+
}
55+
56+
// CrmPropertiesService is an interface of CRM properties endpoints of the HubSpot API.
57+
// Reference: https://developers.hubspot.com/docs/api/crm/properties
58+
type CrmPropertiesService interface {
59+
List(objectType string) (*CrmPropertiesList, error)
60+
Create(objectType string, reqData interface{}) (*CrmProperty, error)
61+
Get(objectType string, propertyName string) (*CrmProperty, error)
62+
Delete(objectType string, propertyName string) error
63+
Update(objectType string, propertyName string, reqData interface{}) (*CrmProperty, error)
64+
}
65+
66+
// CrmPropertiesServiceOp handles communication with the CRM properties endpoint.
67+
type CrmPropertiesServiceOp struct {
68+
client *Client
69+
crmPropertiesPath string
70+
}
71+
72+
var _ CrmPropertiesService = (*CrmPropertiesServiceOp)(nil)
73+
74+
func (s *CrmPropertiesServiceOp) List(objectType string) (*CrmPropertiesList, error) {
75+
var resource CrmPropertiesList
76+
path := fmt.Sprintf("%s/%s", s.crmPropertiesPath, objectType)
77+
if err := s.client.Get(path, &resource, nil); err != nil {
78+
return nil, err
79+
}
80+
return &resource, nil
81+
}
82+
83+
func (s *CrmPropertiesServiceOp) Get(objectType, propertyName string) (*CrmProperty, error) {
84+
var resource CrmProperty
85+
path := fmt.Sprintf("%s/%s/%s", s.crmPropertiesPath, objectType, propertyName)
86+
if err := s.client.Get(path, &resource, nil); err != nil {
87+
return nil, err
88+
}
89+
return &resource, nil
90+
}
91+
92+
func (s *CrmPropertiesServiceOp) Create(objectType string, reqData interface{}) (*CrmProperty, error) {
93+
var resource CrmProperty
94+
path := fmt.Sprintf("%s/%s", s.crmPropertiesPath, objectType)
95+
if err := s.client.Post(path, reqData, &resource); err != nil {
96+
return nil, err
97+
}
98+
return &resource, nil
99+
}
100+
101+
func (s *CrmPropertiesServiceOp) Delete(objectType string, propertyName string) error {
102+
path := fmt.Sprintf("%s/%s/%s", s.crmPropertiesPath, objectType, propertyName)
103+
return s.client.Delete(path, nil)
104+
}
105+
106+
func (s *CrmPropertiesServiceOp) Update(objectType string, propertyName string, reqData interface{}) (*CrmProperty, error) {
107+
var resource CrmProperty
108+
path := fmt.Sprintf("%s/%s/%s", s.crmPropertiesPath, objectType, propertyName)
109+
if err := s.client.Patch(path, reqData, &resource); err != nil {
110+
return nil, err
111+
}
112+
return &resource, nil
113+
}

crm_properties_test.go

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package hubspot
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"testing"
7+
"time"
8+
)
9+
10+
func TestListCrmProperties(t *testing.T) {
11+
t.SkipNow()
12+
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
13+
// Use crm_schemas:TestCreate() to generate this...
14+
res, err := cli.CRM.Properties.List("cars")
15+
if err != nil {
16+
t.Error(err)
17+
}
18+
19+
if len(res.Results) < 1 {
20+
t.Error("expected len(res.Results) to be > 1")
21+
}
22+
23+
}
24+
25+
func TestGetCrmProperty(t *testing.T) {
26+
t.SkipNow()
27+
28+
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
29+
// Use crm_schemas:TestCreate() to generate this...
30+
res, err := cli.CRM.Properties.Get("cars", "model")
31+
if err != nil {
32+
t.Error(err)
33+
}
34+
if *res.Name != "model" {
35+
t.Errorf("expected res.Name to be model, got %s", res.Name)
36+
}
37+
38+
}
39+
40+
func TestCreateProperty(t *testing.T) {
41+
t.SkipNow()
42+
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
43+
newProp := &CrmProperty{
44+
Name: NewString("mileage"),
45+
Label: NewString("Mileage Label"),
46+
Type: NewString("number"),
47+
FieldType: NewString("number"),
48+
GroupName: NewString("cars_information"),
49+
}
50+
51+
_, err := cli.CRM.Properties.Create("cars", newProp)
52+
if err != nil {
53+
t.Error(err)
54+
return
55+
}
56+
}
57+
58+
func TestUpdateProperty(t *testing.T) {
59+
t.SkipNow()
60+
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
61+
62+
updateProp := make(map[string]interface{})
63+
updateProp["label"] = fmt.Sprintf("Updated Label %s", time.Now().String())
64+
65+
res, err := cli.CRM.Properties.Update("cars", "mileage", &updateProp)
66+
if err != nil {
67+
t.Error(err)
68+
return
69+
}
70+
71+
if res.Label != updateProp["label"] {
72+
t.Errorf("expected res.Label to be %s, got %s", updateProp["label"], res.Label)
73+
}
74+
}
75+
76+
func TestDeleteProperty(t *testing.T) {
77+
t.SkipNow()
78+
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
79+
err := cli.CRM.Properties.Delete("cars", "mileage")
80+
if err != nil {
81+
t.Error(err)
82+
}
83+
}

crm_schemas.go

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
package hubspot
2+
3+
import (
4+
"fmt"
5+
)
6+
7+
const (
8+
crmSchemasPath = "schemas"
9+
)
10+
11+
type CrmSchemaAssociation struct {
12+
FromObjectTypeId *HsStr `json:"fromObjectTypeId"`
13+
ToObjectTypeId *HsStr `json:"toObjectTypeId"`
14+
Name *HsStr `json:"name"`
15+
ID *HsStr `json:"id"`
16+
CreatedAt *HsTime `json:"createdAt"`
17+
UpdatedAt *HsTime `json:"updatedAt"`
18+
Cardinality *HsStr `json:"cardinality"`
19+
InverseCardinality *HsStr `json:"inverseCardinality"`
20+
}
21+
22+
type CrmSchemaLabels struct {
23+
Singular *HsStr `json:"singular"`
24+
Plural *HsStr `json:"plural"`
25+
}
26+
27+
type CrmSchemasList struct {
28+
Results []*CrmSchema
29+
}
30+
31+
type CrmSchema struct {
32+
Labels *CrmSchemaLabels `json:"labels,omitempty"`
33+
PrimaryDisplayProperty *HsStr `json:"primaryDisplayProperty,omitempty"`
34+
Archived *HsBool `json:"archived,omitempty"`
35+
ID *HsStr `json:"id,omitempty"`
36+
FullyQualifiedName *HsStr `json:"fullyQualifiedName,omitempty"`
37+
CreatedAt *HsTime `json:"createdAt,omitempty"`
38+
UpdatedAt *HsTime `json:"updatedAt,omitempty"`
39+
ObjectTypeId *HsStr `json:"objectTypeId,omitempty"`
40+
Properties []*CrmProperty `json:"properties,omitempty"`
41+
Associations []*CrmSchemaAssociation `json:"associations,omitempty"`
42+
Name *HsStr `json:"name,omitempty"`
43+
MetaType *HsStr `json:"metaType,omitempty"`
44+
RequiredProperties []*HsStr `json:"requiredProperties,omitempty"`
45+
Restorable *HsBool `json:"restorable,omitempty"`
46+
SearchableProperties []*HsStr `json:"searchableProperties,omitempty"`
47+
SecondaryDisplayProperties []*HsStr `json:"secondaryDisplayProperties,omitempty"`
48+
PortalId *HsInt `json:"portalId"`
49+
}
50+
51+
// CrmSchemasService is an interface of CRM schemas endpoints of the HubSpot API.
52+
// Reference: https://developers.hubspot.com/docs/api/crm/crm-custom-objects
53+
type CrmSchemasService interface {
54+
List() (*CrmSchemasList, error)
55+
Create(reqData interface{}) (*CrmSchema, error)
56+
Get(objectType string) (*CrmSchema, error)
57+
Delete(objectType string, option *RequestQueryOption) error
58+
Update(objectType string, reqData interface{}) (*CrmSchema, error)
59+
}
60+
61+
// CrmSchemasServiceOp handles communication with the CRM schemas endpoint.
62+
type CrmSchemasServiceOp struct {
63+
client *Client
64+
crmSchemasPath string
65+
}
66+
67+
var _ CrmSchemasService = (*CrmSchemasServiceOp)(nil)
68+
69+
func (s *CrmSchemasServiceOp) List() (*CrmSchemasList, error) {
70+
var resource CrmSchemasList
71+
if err := s.client.Get(s.crmSchemasPath, &resource, nil); err != nil {
72+
return nil, err
73+
}
74+
return &resource, nil
75+
}
76+
77+
func (s *CrmSchemasServiceOp) Create(reqData interface{}) (*CrmSchema, error) {
78+
var resource CrmSchema
79+
if err := s.client.Post(s.crmSchemasPath, reqData, &resource); err != nil {
80+
return nil, err
81+
}
82+
return &resource, nil
83+
}
84+
85+
func (s *CrmSchemasServiceOp) Get(objectType string) (*CrmSchema, error) {
86+
var resource CrmSchema
87+
path := fmt.Sprintf("%s/%s", s.crmSchemasPath, objectType)
88+
if err := s.client.Get(path, &resource, nil); err != nil {
89+
return nil, err
90+
}
91+
return &resource, nil
92+
}
93+
94+
func (s *CrmSchemasServiceOp) Delete(objectType string, option *RequestQueryOption) error {
95+
path := fmt.Sprintf("%s/%s", s.crmSchemasPath, objectType)
96+
return s.client.Delete(path, option)
97+
}
98+
99+
func (s *CrmSchemasServiceOp) Update(objectType string, reqData interface{}) (*CrmSchema, error) {
100+
var resource CrmSchema
101+
path := fmt.Sprintf("%s/%s", s.crmSchemasPath, objectType)
102+
if err := s.client.Patch(path, reqData, &resource); err != nil {
103+
return nil, err
104+
}
105+
return &resource, nil
106+
}

0 commit comments

Comments
 (0)