Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRM Schemas/Properties CRUD support #17

Merged
merged 1 commit into from
Apr 27, 2023
Merged
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
2 changes: 1 addition & 1 deletion contact.go
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,7 @@ func (s *ContactServiceOp) Update(contactID string, contact interface{}) (*Respo

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

// AssociateAnotherObj associates Contact with another HubSpot objects.
Expand Down
16 changes: 13 additions & 3 deletions crm.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ const (
)

type CRM struct {
Contact ContactService
Deal DealService
Imports CrmImportsService
Contact ContactService
Deal DealService
Imports CrmImportsService
Schemas CrmSchemasService
Properties CrmPropertiesService
}

func newCRM(c *Client) *CRM {
Expand All @@ -29,5 +31,13 @@ func newCRM(c *Client) *CRM {
crmImportsPath: fmt.Sprintf("%s/%s", crmPath, crmImportsBasePath),
client: c,
},
Schemas: &CrmSchemasServiceOp{
crmSchemasPath: fmt.Sprintf("%s/%s", crmPath, crmSchemasPath),
client: c,
},
Properties: &CrmPropertiesServiceOp{
crmPropertiesPath: fmt.Sprintf("%s/%s", crmPath, crmPropertiesPath),
client: c,
},
}
}
7 changes: 4 additions & 3 deletions crm_imports_start.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import (
)

type CrmImportConfig struct {
Name string `json:"name"`
ImportOperations map[string]string `json:"importOperations"`
Files []CrmImportFileConfig `json:"files"`
Name string `json:"name"`
MarketableContactImport bool `json:"marketableContactImport"`
ImportOperations map[string]string `json:"importOperations"`
Files []CrmImportFileConfig `json:"files"`
}

type CrmImportFilePageConfig struct {
Expand Down
114 changes: 114 additions & 0 deletions crm_properties.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package hubspot

import (
"fmt"
)

const (
crmPropertiesPath = "properties"
)

type CrmPropertiesList struct {
Results []*CrmProperty `json:"results,omitempty"`
}

type CrmProperty struct {
sblackstone marked this conversation as resolved.
Show resolved Hide resolved
UpdatedAt *HsTime `json:"updatedAt,omitempty"`
CreatedAt *HsTime `json:"createdAt,omitempty"`
ArchivedAt *HsTime `json:"archivedAt,omitempty"`
Name *HsStr `json:"name,omitempty"`
Label *HsStr `json:"label,omitempty"`
Type *HsStr `json:"type,omitempty"`
FieldType *HsStr `json:"fieldType,omitempty"`
Description *HsStr `json:"description,omitempty"`
GroupName *HsStr `json:"groupName,omitempty"`
Options []*CrmPropertyOptions `json:"options,omitempty"`
CreatedUserId *HsStr `json:"createdUserId,omitempty"`
UpdatedUserId *HsStr `json:"updatedUserId,omitempty"`
ReferencedObjectType *HsStr `json:"referencedObjectType,omitempty"`
DisplayOrder *HsInt `json:"displayOrder,omitempty"`
Calculated *HsBool `json:"calculated,omitempty"`
ExternalOptions *HsBool `json:"externalOptions,omitempty"`
Archived *HsBool `json:"archived,omitempty"`
HasUniqueValue *HsBool `json:"hasUniqueValue,omitempty"`
Hidden *HsBool `json:"hidden,omitempty"`
HubspotDefined *HsBool `json:"hubspotDefined,omitempty"`
ShowCurrencySymbol *HsBool `json:"showCurrencySymbol,omitempty"`
ModificationMetaData *CrmPropertyModificationMeta `json:"modificationMetadata,omitempty"`
FormField *HsBool `json:"formField,omitempty"`
CalculationFormula *HsStr `json:"calculationFormula,omitempty"`
}

type CrmPropertyModificationMeta struct {
sblackstone marked this conversation as resolved.
Show resolved Hide resolved
Archivable *HsBool `json:"archivable,omitempty"`
ReadOnlyDefition *HsBool `json:"readOnlyDefinition,omitempty"`
ReadOnlyValue *HsBool `json:"readOnlyValue,omitempty"`
ReadOnlyOptions *HsBool `json:"readOnlyOptions,omitempty"`
}

type CrmPropertyOptions struct {
sblackstone marked this conversation as resolved.
Show resolved Hide resolved
Label *HsStr `json:"label,omitempty"`
Value *HsStr `json:"value,omitempty"`
Description *HsStr `json:"description,omitempty"`
DisplayOrder *HsInt `json:"displayOrder,omitempty"`
Hidden *HsBool `json:"hidden,omitempty"`
}

// CrmPropertiesService is an interface of CRM properties endpoints of the HubSpot API.
// Reference: https://developers.hubspot.com/docs/api/crm/properties
type CrmPropertiesService interface {
List(objectType string) (*CrmPropertiesList, error)
Create(objectType string, reqData interface{}) (*CrmProperty, error)
Get(objectType string, propertyName string) (*CrmProperty, error)
Delete(objectType string, propertyName string) error
Update(objectType string, propertyName string, reqData interface{}) (*CrmProperty, error)
}

// CrmPropertiesServiceOp handles communication with the CRM properties endpoint.
type CrmPropertiesServiceOp struct {
client *Client
crmPropertiesPath string
}

var _ CrmPropertiesService = (*CrmPropertiesServiceOp)(nil)

func (s *CrmPropertiesServiceOp) List(objectType string) (*CrmPropertiesList, error) {
var resource CrmPropertiesList
path := fmt.Sprintf("%s/%s", s.crmPropertiesPath, objectType)
if err := s.client.Get(path, &resource, nil); err != nil {
return nil, err
}
return &resource, nil
}

func (s *CrmPropertiesServiceOp) Get(objectType, propertyName string) (*CrmProperty, error) {
var resource CrmProperty
path := fmt.Sprintf("%s/%s/%s", s.crmPropertiesPath, objectType, propertyName)
if err := s.client.Get(path, &resource, nil); err != nil {
return nil, err
}
return &resource, nil
}

func (s *CrmPropertiesServiceOp) Create(objectType string, reqData interface{}) (*CrmProperty, error) {
var resource CrmProperty
path := fmt.Sprintf("%s/%s", s.crmPropertiesPath, objectType)
if err := s.client.Post(path, reqData, &resource); err != nil {
return nil, err
}
return &resource, nil
}

func (s *CrmPropertiesServiceOp) Delete(objectType string, propertyName string) error {
path := fmt.Sprintf("%s/%s/%s", s.crmPropertiesPath, objectType, propertyName)
return s.client.Delete(path, nil)
}

func (s *CrmPropertiesServiceOp) Update(objectType string, propertyName string, reqData interface{}) (*CrmProperty, error) {
var resource CrmProperty
path := fmt.Sprintf("%s/%s/%s", s.crmPropertiesPath, objectType, propertyName)
if err := s.client.Patch(path, reqData, &resource); err != nil {
return nil, err
}
return &resource, nil
}
81 changes: 81 additions & 0 deletions crm_properties_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package hubspot

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

func TestListCrmProperties(t *testing.T) {
t.SkipNow()
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
// Use crm_schemas:TestCreate() to generate this...
res, err := cli.CRM.Properties.List("cars")
if err != nil {
t.Error(err)
}

if len(res.Results) < 1 {
t.Error("expected len(res.Results) to be > 1")
}
}

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

cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
// Use crm_schemas:TestCreate() to generate this...
res, err := cli.CRM.Properties.Get("cars", "model")
if err != nil {
t.Error(err)
}
if *res.Name != "model" {
t.Errorf("expected res.Name to be model, got %s", res.Name)
}
}

func TestCreateProperty(t *testing.T) {
t.SkipNow()
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
newProp := &CrmProperty{
Name: NewString("mileage"),
Label: NewString("Mileage Label"),
Type: NewString("number"),
FieldType: NewString("number"),
GroupName: NewString("cars_information"),
}

_, err := cli.CRM.Properties.Create("cars", newProp)
if err != nil {
t.Error(err)
return
}
}

func TestUpdateProperty(t *testing.T) {
t.SkipNow()
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))

updateProp := make(map[string]interface{})
updateProp["label"] = fmt.Sprintf("Updated Label %s", time.Now().String())

res, err := cli.CRM.Properties.Update("cars", "mileage", &updateProp)
if err != nil {
t.Error(err)
return
}

if res.Label != updateProp["label"] {
t.Errorf("expected res.Label to be %s, got %s", updateProp["label"], res.Label)
}
}

func TestDeleteProperty(t *testing.T) {
t.SkipNow()
cli, _ := NewClient(SetPrivateAppToken(os.Getenv("PRIVATE_APP_TOKEN")))
err := cli.CRM.Properties.Delete("cars", "mileage")
if err != nil {
t.Error(err)
}
}
106 changes: 106 additions & 0 deletions crm_schemas.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package hubspot

import (
"fmt"
)

const (
crmSchemasPath = "schemas"
)

type CrmSchemaAssociation struct {
FromObjectTypeId *HsStr `json:"fromObjectTypeId"`
ToObjectTypeId *HsStr `json:"toObjectTypeId"`
Name *HsStr `json:"name"`
ID *HsStr `json:"id"`
CreatedAt *HsTime `json:"createdAt"`
UpdatedAt *HsTime `json:"updatedAt"`
Cardinality *HsStr `json:"cardinality"`
InverseCardinality *HsStr `json:"inverseCardinality"`
}

type CrmSchemaLabels struct {
Singular *HsStr `json:"singular"`
Plural *HsStr `json:"plural"`
}

type CrmSchemasList struct {
Results []*CrmSchema
sblackstone marked this conversation as resolved.
Show resolved Hide resolved
}

type CrmSchema struct {
Labels *CrmSchemaLabels `json:"labels,omitempty"`
PrimaryDisplayProperty *HsStr `json:"primaryDisplayProperty,omitempty"`
Archived *HsBool `json:"archived,omitempty"`
ID *HsStr `json:"id,omitempty"`
FullyQualifiedName *HsStr `json:"fullyQualifiedName,omitempty"`
CreatedAt *HsTime `json:"createdAt,omitempty"`
UpdatedAt *HsTime `json:"updatedAt,omitempty"`
ObjectTypeId *HsStr `json:"objectTypeId,omitempty"`
Properties []*CrmProperty `json:"properties,omitempty"`
Associations []*CrmSchemaAssociation `json:"associations,omitempty"`
Name *HsStr `json:"name,omitempty"`
MetaType *HsStr `json:"metaType,omitempty"`
RequiredProperties []*HsStr `json:"requiredProperties,omitempty"`
Restorable *HsBool `json:"restorable,omitempty"`
SearchableProperties []*HsStr `json:"searchableProperties,omitempty"`
SecondaryDisplayProperties []*HsStr `json:"secondaryDisplayProperties,omitempty"`
PortalId *HsInt `json:"portalId"`
}

// CrmSchemasService is an interface of CRM schemas endpoints of the HubSpot API.
// Reference: https://developers.hubspot.com/docs/api/crm/crm-custom-objects
type CrmSchemasService interface {
List() (*CrmSchemasList, error)
Create(reqData interface{}) (*CrmSchema, error)
Get(objectType string) (*CrmSchema, error)
Delete(objectType string, option *RequestQueryOption) error
Update(objectType string, reqData interface{}) (*CrmSchema, error)
}

// CrmSchemasServiceOp handles communication with the CRM schemas endpoint.
type CrmSchemasServiceOp struct {
client *Client
crmSchemasPath string
}

var _ CrmSchemasService = (*CrmSchemasServiceOp)(nil)

func (s *CrmSchemasServiceOp) List() (*CrmSchemasList, error) {
var resource CrmSchemasList
if err := s.client.Get(s.crmSchemasPath, &resource, nil); err != nil {
return nil, err
}
return &resource, nil
}

func (s *CrmSchemasServiceOp) Create(reqData interface{}) (*CrmSchema, error) {
var resource CrmSchema
if err := s.client.Post(s.crmSchemasPath, reqData, &resource); err != nil {
return nil, err
}
return &resource, nil
}

func (s *CrmSchemasServiceOp) Get(objectType string) (*CrmSchema, error) {
var resource CrmSchema
path := fmt.Sprintf("%s/%s", s.crmSchemasPath, objectType)
if err := s.client.Get(path, &resource, nil); err != nil {
return nil, err
}
return &resource, nil
}

func (s *CrmSchemasServiceOp) Delete(objectType string, option *RequestQueryOption) error {
path := fmt.Sprintf("%s/%s", s.crmSchemasPath, objectType)
return s.client.Delete(path, option)
}

func (s *CrmSchemasServiceOp) Update(objectType string, reqData interface{}) (*CrmSchema, error) {
var resource CrmSchema
path := fmt.Sprintf("%s/%s", s.crmSchemasPath, objectType)
if err := s.client.Patch(path, reqData, &resource); err != nil {
return nil, err
}
return &resource, nil
}
Loading