diff --git a/connectors.go b/connectors.go index 0506c77..fd98701 100644 --- a/connectors.go +++ b/connectors.go @@ -37,6 +37,7 @@ import ( "github.com/wakflo/extensions/internal/connectors/googlemail" "github.com/wakflo/extensions/internal/connectors/goscript" "github.com/wakflo/extensions/internal/connectors/harvest" + "github.com/wakflo/extensions/internal/connectors/hubspot" "github.com/wakflo/extensions/internal/connectors/javascript" "github.com/wakflo/extensions/internal/connectors/jiracloud" "github.com/wakflo/extensions/internal/connectors/jsonconverter" @@ -112,6 +113,7 @@ func RegisterConnectors() []*sdk.ConnectorPlugin { monday.NewConnector, // Monday.com zoom.NewConnector, // Zoom flexport.NewConnector, // Flexport + hubspot.NewConnector, // Hubspot jiracloud.NewConnector, // Jira Cloud prisync.NewConnector, // Prisync github.NewConnector, // Github diff --git a/internal/connectors/hubspot/lib.go b/internal/connectors/hubspot/lib.go new file mode 100644 index 0000000..2b7c24e --- /dev/null +++ b/internal/connectors/hubspot/lib.go @@ -0,0 +1,46 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + sdk "github.com/wakflo/go-sdk/connector" +) + +func NewConnector() (*sdk.ConnectorPlugin, error) { + return sdk.CreateConnector(&sdk.CreateConnectorArgs{ + Name: "Hubspot", + Description: "Powerful CRM that offers tools for sales, customer service, and marketing automation.", + Logo: "logos:hubspot", + Version: "0.0.1", + Group: sdk.ConnectorGroupApps, + Authors: []string{"Wakflo "}, + Triggers: []sdk.ITrigger{ + NewTicketCreated(), + NewContactCreated(), + NewCompanyCreated(), + NewDealCreated(), + NewTaskCreated(), + }, + Operations: []sdk.IOperation{ + NewCreateContactOperation(), + NewListContactsOperation(), + NewRetrieveContactOperation(), + NewCreateTicketOperation(), + NewListTicketsOperation(), + NewSearchOwnerByEmailOperation(), + NewSearchOwnerByEmailOperation(), + }, + }) +} diff --git a/internal/connectors/hubspot/model.go b/internal/connectors/hubspot/model.go new file mode 100644 index 0000000..81ab134 --- /dev/null +++ b/internal/connectors/hubspot/model.go @@ -0,0 +1,66 @@ +package hubspot + +import "time" + +type contactRequest struct { + Properties map[string]interface{} `json:"properties"` +} + +type ListResponse struct { + Lists []List `json:"lists"` +} + +type List struct { + ProcessingType string `json:"processingType"` + ObjectTypeID string `json:"objectTypeId"` + UpdatedByID string `json:"updatedById"` + FiltersUpdatedAt time.Time `json:"filtersUpdatedAt"` + ListID string `json:"listId"` + CreatedAt time.Time `json:"createdAt"` + ProcessingStatus string `json:"processingStatus"` + DeletedAt time.Time `json:"deletedAt"` + ListVersion int `json:"listVersion"` + Size int `json:"size"` + Name string `json:"name"` + CreatedByID string `json:"createdById"` + FilterBranch FilterBranch `json:"filterBranch"` + UpdatedAt time.Time `json:"updatedAt"` +} + +type FilterBranch struct { + FilterBranchType string `json:"filterBranchType"` + FilterBranches []FilterBranch `json:"filterBranches"` + FilterBranchOperator string `json:"filterBranchOperator"` + Filters []interface{} `json:"filters"` +} + +type DealPipelineResponse struct { + Results []PipelineResult `json:"results"` +} + +type PipelineResult struct { + CreatedAt time.Time `json:"createdAt"` + ArchivedAt time.Time `json:"archivedAt"` + Archived bool `json:"archived"` + DisplayOrder int `json:"displayOrder"` + Stages []Stage `json:"stages"` + Label string `json:"label"` + ID string `json:"id"` + UpdatedAt time.Time `json:"updatedAt"` +} + +type Stage struct { + CreatedAt time.Time `json:"createdAt"` + ArchivedAt time.Time `json:"archivedAt"` + Archived bool `json:"archived"` + Metadata StageMetadata `json:"metadata"` + DisplayOrder int `json:"displayOrder"` + WritePermissions string `json:"writePermissions"` + Label string `json:"label"` + ID string `json:"id"` + UpdatedAt time.Time `json:"updatedAt"` +} + +type StageMetadata struct { + TicketState string `json:"ticketState"` +} diff --git a/internal/connectors/hubspot/operation_create_contact.go b/internal/connectors/hubspot/operation_create_contact.go new file mode 100644 index 0000000..2d74b43 --- /dev/null +++ b/internal/connectors/hubspot/operation_create_contact.go @@ -0,0 +1,103 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "encoding/json" + "net/http" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type createNewContactProps struct { + FirstName string `json:"firstname"` + LastName string `json:"lastname"` + Email string `json:"email"` + Zip string `json:"zip"` +} + +type CreateContactOperation struct { + options *sdk.OperationInfo +} + +func NewCreateContactOperation() *CreateContactOperation { + return &CreateContactOperation{ + options: &sdk.OperationInfo{ + Name: "Create new Contact", + Description: "Create new contact", + Auth: sharedAuth, + Input: map[string]*sdkcore.AutoFormSchema{ + "firstname": autoform.NewShortTextField(). + SetDisplayName("First Name"). + SetDescription("First Name"). + SetRequired(true).Build(), + "lastname": autoform.NewShortTextField(). + SetDisplayName("Last Name"). + SetDescription("Last name"). + SetRequired(true).Build(), + "email": autoform.NewShortTextField(). + SetDisplayName("Email"). + SetDescription("Email"). + SetRequired(false).Build(), + "zip": autoform.NewShortTextField(). + SetDisplayName("Zip"). + SetDescription("Zip Code"). + SetRequired(false).Build(), + }, + SampleOutput: map[string]interface{}{}, + ErrorSettings: sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + RequireAuth: true, + }, + } +} + +func (c *CreateContactOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + input := sdk.InputToType[createNewContactProps](ctx) + + contact := contactRequest{ + Properties: map[string]interface{}{ + "firstname": input.FirstName, + "lastname": input.LastName, + "email": input.Email, + "zip": input.Zip, + }, + } + + newContact, err := json.Marshal(contact) + if err != nil { + return nil, err + } + + reqURL := "/crm/v3/objects/contacts" + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodPost, newContact) + if err != nil { + return nil, err + } + return resp, nil +} + +func (c *CreateContactOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return c.Run(ctx) +} + +func (c *CreateContactOperation) GetInfo() *sdk.OperationInfo { + return c.options +} diff --git a/internal/connectors/hubspot/operation_create_ticket.go b/internal/connectors/hubspot/operation_create_ticket.go new file mode 100644 index 0000000..cabf33a --- /dev/null +++ b/internal/connectors/hubspot/operation_create_ticket.go @@ -0,0 +1,101 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "encoding/json" + "net/http" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type createNewTicketProps struct { + Subject string `json:"subject"` + Content string `json:"content"` + Priority string `json:"hs_ticket_priority"` +} + +type CreateTicketOperation struct { + options *sdk.OperationInfo +} + +func NewCreateTicketOperation() *CreateTicketOperation { + return &CreateTicketOperation{ + options: &sdk.OperationInfo{ + Name: "Create new Ticket", + Description: "Create new contact", + Auth: sharedAuth, + Input: map[string]*sdkcore.AutoFormSchema{ + "subject": autoform.NewShortTextField(). + SetDisplayName("Ticket Subject"). + SetDescription("subject of the ticket to create"). + SetRequired(true).Build(), + "content": autoform.NewShortTextField(). + SetDisplayName("Ticket Description"). + SetDescription("ticket description"). + SetRequired(false).Build(), + "hs_ticket_priority": autoform.NewSelectField(). + SetDisplayName("Format"). + SetDescription("The format of the email to read"). + SetOptions(hubspotPriority). + SetRequired(false). + Build(), + }, + SampleOutput: map[string]interface{}{}, + ErrorSettings: sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + RequireAuth: true, + }, + } +} + +func (c *CreateTicketOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + input := sdk.InputToType[createNewTicketProps](ctx) + + ticket := contactRequest{ + Properties: map[string]interface{}{ + "subject": input.Subject, + "content": input.Content, + "hs_ticket_priority": input.Priority, + "hs_pipeline": "0", + "hs_pipeline_stage": "1", + }, + } + + newTicket, err := json.Marshal(ticket) + if err != nil { + return nil, err + } + + reqURL := "/crm/v3/objects/tickets" + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodPost, newTicket) + if err != nil { + return nil, err + } + return resp, nil +} + +func (c *CreateTicketOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return c.Run(ctx) +} + +func (c *CreateTicketOperation) GetInfo() *sdk.OperationInfo { + return c.options +} diff --git a/internal/connectors/hubspot/operation_list_contacts.go b/internal/connectors/hubspot/operation_list_contacts.go new file mode 100644 index 0000000..5280062 --- /dev/null +++ b/internal/connectors/hubspot/operation_list_contacts.go @@ -0,0 +1,73 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "net/http" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type listContactsProps struct { + Limit string `json:"limit"` +} + +type ListContactsOperation struct { + options *sdk.OperationInfo +} + +func NewListContactsOperation() *ListContactsOperation { + return &ListContactsOperation{ + options: &sdk.OperationInfo{ + Name: "List Contacts", + Description: "list contacts", + Auth: sharedAuth, + Input: map[string]*sdkcore.AutoFormSchema{ + "limit": autoform.NewShortTextField(). + SetDisplayName("limit"). + SetDescription(""). + SetRequired(false).Build(), + }, + SampleOutput: map[string]interface{}{}, + ErrorSettings: sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + RequireAuth: true, + }, + } +} + +func (c *ListContactsOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + _ = sdk.InputToType[listContactsProps](ctx) + + reqURL := "/crm/v3/objects/contacts" + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodGet, nil) + if err != nil { + return nil, err + } + return resp, nil +} + +func (c *ListContactsOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return c.Run(ctx) +} + +func (c *ListContactsOperation) GetInfo() *sdk.OperationInfo { + return c.options +} diff --git a/internal/connectors/hubspot/operation_list_tickets.go b/internal/connectors/hubspot/operation_list_tickets.go new file mode 100644 index 0000000..fc51057 --- /dev/null +++ b/internal/connectors/hubspot/operation_list_tickets.go @@ -0,0 +1,73 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "net/http" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type listTicketsOperationProps struct { + Subject string `json:"subject"` +} + +type ListTicketsOperation struct { + options *sdk.OperationInfo +} + +func NewListTicketsOperation() *ListTicketsOperation { + return &ListTicketsOperation{ + options: &sdk.OperationInfo{ + Name: "List Tickets", + Description: "List tickets", + Auth: sharedAuth, + Input: map[string]*sdkcore.AutoFormSchema{ + "subject": autoform.NewShortTextField(). + SetDisplayName(""). + SetDescription(""). + SetRequired(false).Build(), + }, + SampleOutput: map[string]interface{}{}, + ErrorSettings: sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + RequireAuth: true, + }, + } +} + +func (c *ListTicketsOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + _ = sdk.InputToType[listTicketsOperationProps](ctx) + + reqURL := "/crm/v3/objects/tickets" + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodGet, nil) + if err != nil { + return nil, err + } + return resp, nil +} + +func (c *ListTicketsOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return c.Run(ctx) +} + +func (c *ListTicketsOperation) GetInfo() *sdk.OperationInfo { + return c.options +} diff --git a/internal/connectors/hubspot/operation_retrieve_contact.go b/internal/connectors/hubspot/operation_retrieve_contact.go new file mode 100644 index 0000000..c13f094 --- /dev/null +++ b/internal/connectors/hubspot/operation_retrieve_contact.go @@ -0,0 +1,74 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "fmt" + "net/http" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type retrieveContactProps struct { + Email string `json:"email"` +} + +type RetrieveContactOperation struct { + options *sdk.OperationInfo +} + +func NewRetrieveContactOperation() *RetrieveContactOperation { + return &RetrieveContactOperation{ + options: &sdk.OperationInfo{ + Name: "Retrieve a Contact by email", + Description: "retrieve a contact", + Auth: sharedAuth, + Input: map[string]*sdkcore.AutoFormSchema{ + "email": autoform.NewShortTextField(). + SetDisplayName("Contact's email"). + SetDescription("contact's email"). + SetRequired(true).Build(), + }, + SampleOutput: map[string]interface{}{}, + ErrorSettings: sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + RequireAuth: true, + }, + } +} + +func (c *RetrieveContactOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + input := sdk.InputToType[retrieveContactProps](ctx) + + reqURL := fmt.Sprintf("/v3/objects/contacts/%s?idProperty=email", input.Email) + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodGet, nil) + if err != nil { + return nil, err + } + return resp, nil +} + +func (c *RetrieveContactOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return c.Run(ctx) +} + +func (c *RetrieveContactOperation) GetInfo() *sdk.OperationInfo { + return c.options +} diff --git a/internal/connectors/hubspot/operation_search_owner_by_email.go b/internal/connectors/hubspot/operation_search_owner_by_email.go new file mode 100644 index 0000000..9dca8f1 --- /dev/null +++ b/internal/connectors/hubspot/operation_search_owner_by_email.go @@ -0,0 +1,74 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "fmt" + "net/http" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type searchOwnerByEmailProps struct { + Email string `json:"email"` +} + +type SearchOwnerByEmailOperation struct { + options *sdk.OperationInfo +} + +func NewSearchOwnerByEmailOperation() *SearchOwnerByEmailOperation { + return &SearchOwnerByEmailOperation{ + options: &sdk.OperationInfo{ + Name: "Get owner by email", + Description: "Retrieves an existing owner by email.", + Auth: sharedAuth, + Input: map[string]*sdkcore.AutoFormSchema{ + "email": autoform.NewShortTextField(). + SetDisplayName("Owner Email"). + SetDescription("owner's email"). + SetRequired(true).Build(), + }, + SampleOutput: map[string]interface{}{}, + ErrorSettings: sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + RequireAuth: true, + }, + } +} + +func (c *SearchOwnerByEmailOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + input := sdk.InputToType[searchOwnerByEmailProps](ctx) + + reqURL := fmt.Sprintf("/crm/v3/owners/?email=%s&limit=100&archived=false", input.Email) + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodGet, nil) + if err != nil { + return nil, err + } + return resp, nil +} + +func (c *SearchOwnerByEmailOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return c.Run(ctx) +} + +func (c *SearchOwnerByEmailOperation) GetInfo() *sdk.OperationInfo { + return c.options +} diff --git a/internal/connectors/hubspot/shared.go b/internal/connectors/hubspot/shared.go new file mode 100644 index 0000000..a76a1b7 --- /dev/null +++ b/internal/connectors/hubspot/shared.go @@ -0,0 +1,176 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "bytes" + "encoding/json" + "io" + "net/http" + + sdkcore "github.com/wakflo/go-sdk/core" + + "github.com/wakflo/go-sdk/autoform" +) + +var ( + // #nosec + tokenURL = "https://api.hubapi.com/oauth/v1/token" + sharedAuth = autoform.NewOAuthField("https://app.hubspot.com/oauth/authorize", &tokenURL, []string{ + "oauth" + + " crm.lists.read " + + "crm.lists.write " + + "crm.objects.contacts.read" + + " crm.objects.contacts.write " + + "crm.objects.owners.read " + + "crm.objects.companies.read " + + "crm.objects.companies.write " + + "crm.objects.deals.read" + + " crm.objects.deals.write " + + "crm.objects.line_items.read " + + "crm.schemas.line_items.read " + + "crm.schemas.companies.read " + + "crm.schemas.contacts.read " + + "crm.schemas.deals.read tickets", + }).SetRequired(true).Build() +) + +var baseAPI = "https://api.hubapi.com" + +func hubspotClient(reqURL, accessToken, method string, request []byte) (interface{}, error) { + fullURL := baseAPI + reqURL + req, err := http.NewRequest(method, fullURL, bytes.NewBuffer(request)) + if err != nil { + return nil, err + } + + req.Header.Add("Content-Type", "application/json") + req.Header.Add("Accept", "application/json") + req.Header.Add("Authorization", "Bearer "+accessToken) + client := &http.Client{} + res, err := client.Do(req) + if err != nil { + return nil, err + } + defer res.Body.Close() + + body, err := io.ReadAll(res.Body) + if err != nil { + return nil, err + } + var hubspotResponse interface{} + err = json.Unmarshal(body, &hubspotResponse) + if err != nil { + return nil, err + } + + return hubspotResponse, nil +} + +// func getListsInput() *sdkcore.AutoFormSchema { +// getLists := func(ctx *sdkcore.DynamicFieldContext) (interface{}, error) { +// client := fastshot.NewClient(baseAPI). +// Auth().BearerToken(ctx.Auth.AccessToken). +// Header(). +// AddAccept("application/json"). +// Build() +// +// rsp, err := client.GET("/crm/v3/lists/").Send() +// if err != nil { +// return nil, err +// } +// +// if rsp.Status().IsError() { +// return nil, errors.New(rsp.Status().Text()) +// } +// +// bytes, err := io.ReadAll(rsp.Raw().Body) //nolint:bodyclose +// if err != nil { +// return nil, err +// } +// +// var hubspotLists ListResponse +// err = json.Unmarshal(bytes, &hubspotLists) +// if err != nil { +// return nil, err +// } +// +// list := hubspotLists.Lists +// return arrutil.Map[List, map[string]any](list, func(input List) (target map[string]any, find bool) { +// return map[string]any{ +// "id": input.ListID, +// "name": input.Name, +// }, true +// }), nil +// } +// +// return autoform.NewDynamicField(sdkcore.String). +// SetDisplayName("List"). +// SetDescription("Select list"). +// SetDependsOn([]string{"connection"}). +// SetDynamicOptions(&getLists). +// SetRequired(true).Build() +// } +// +// func getPipelineInput() *sdkcore.AutoFormSchema { +// getPipelines := func(ctx *sdkcore.DynamicFieldContext) (interface{}, error) { +// client := fastshot.NewClient(baseAPI). +// Auth().BearerToken(ctx.Auth.AccessToken). +// Header(). +// AddAccept("application/json"). +// Build() +// +// rsp, err := client.GET("/crm/v3/pipelines/deals").Send() +// if err != nil { +// return nil, err +// } +// +// if rsp.Status().IsError() { +// return nil, errors.New(rsp.Status().Text()) +// } +// +// bytes, err := io.ReadAll(rsp.Raw().Body) //nolint:bodyclose +// if err != nil { +// return nil, err +// } +// +// var hubspotPipelines DealPipelineResponse +// err = json.Unmarshal(bytes, &hubspotPipelines) +// if err != nil { +// return nil, err +// } +// +// pipeline := hubspotPipelines.Results +// return arrutil.Map[PipelineResult, map[string]any](pipeline, func(input PipelineResult) (target map[string]any, find bool) { +// return map[string]any{ +// "id": input.ID, +// "name": input.Label, +// }, true +// }), nil +// } +// +// return autoform.NewDynamicField(sdkcore.String). +// SetDisplayName("Deal Pipeline"). +// SetDescription("Deal Pipeline"). +// SetDependsOn([]string{"connection"}). +// SetDynamicOptions(&getPipelines). +// SetRequired(true).Build() +// } + +var hubspotPriority = []*sdkcore.AutoFormSchema{ + {Const: "HIGH", Title: "High"}, + {Const: "MEDIUM", Title: "Medium"}, + {Const: "LOW", Title: "Low"}, +} diff --git a/internal/connectors/hubspot/trigger_new_company.go b/internal/connectors/hubspot/trigger_new_company.go new file mode 100644 index 0000000..47f883d --- /dev/null +++ b/internal/connectors/hubspot/trigger_new_company.go @@ -0,0 +1,82 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "net/http" + "time" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type CompanyCreated struct { + options *sdk.TriggerInfo +} + +func NewCompanyCreated() *TicketCreated { + return &TicketCreated{ + options: &sdk.TriggerInfo{ + Name: "New Company Added", + Description: "triggers workflow when a new company is added", + RequireAuth: true, + Auth: sharedAuth, + Type: sdkcore.TriggerTypeCron, + Input: map[string]*sdkcore.AutoFormSchema{ + "id": autoform.NewShortTextField(). + SetDisplayName(""). + SetDescription(""). + Build(), + }, + Settings: &sdkcore.TriggerSettings{}, + ErrorSettings: &sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + }, + } +} + +func (t *CompanyCreated) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + reqURL := "/crm/v3/objects/company?limit=50&archived=false&properties=createdAt,updatedAt" + + if ctx.Metadata.LastRun != nil { + createdAfter := ctx.Metadata.LastRun.UTC().Format(time.RFC3339) + reqURL += "&createdAfter=" + createdAfter + } + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodGet, nil) + if err != nil { + return nil, err + } + return resp, nil +} + +func (t *CompanyCreated) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return t.Run(ctx) +} + +func (t *CompanyCreated) OnEnabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *CompanyCreated) OnDisabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *CompanyCreated) GetInfo() *sdk.TriggerInfo { + return t.options +} diff --git a/internal/connectors/hubspot/trigger_new_contact.go b/internal/connectors/hubspot/trigger_new_contact.go new file mode 100644 index 0000000..d280d8f --- /dev/null +++ b/internal/connectors/hubspot/trigger_new_contact.go @@ -0,0 +1,82 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "net/http" + "time" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type ContactCreated struct { + options *sdk.TriggerInfo +} + +func NewContactCreated() *TicketCreated { + return &TicketCreated{ + options: &sdk.TriggerInfo{ + Name: "New Contact Added", + Description: "triggers workflow when a new contact has been created", + RequireAuth: true, + Auth: sharedAuth, + Type: sdkcore.TriggerTypeCron, + Input: map[string]*sdkcore.AutoFormSchema{ + "id": autoform.NewShortTextField(). + SetDisplayName(""). + SetDescription(""). + Build(), + }, + Settings: &sdkcore.TriggerSettings{}, + ErrorSettings: &sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + }, + } +} + +func (t *ContactCreated) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + reqURL := "/crm/v3/objects/contacts?limit=50&archived=false&properties=createdAt,updatedAt" + + if ctx.Metadata.LastRun != nil { + createdAfter := ctx.Metadata.LastRun.UTC().Format(time.RFC3339) + reqURL += "&createdAfter=" + createdAfter + } + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodGet, nil) + if err != nil { + return nil, err + } + return resp, nil +} + +func (t *ContactCreated) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return t.Run(ctx) +} + +func (t *ContactCreated) OnEnabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *ContactCreated) OnDisabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *ContactCreated) GetInfo() *sdk.TriggerInfo { + return t.options +} diff --git a/internal/connectors/hubspot/trigger_new_deal.go b/internal/connectors/hubspot/trigger_new_deal.go new file mode 100644 index 0000000..b7d2717 --- /dev/null +++ b/internal/connectors/hubspot/trigger_new_deal.go @@ -0,0 +1,82 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "net/http" + "time" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type DealCreated struct { + options *sdk.TriggerInfo +} + +func NewDealCreated() *TicketCreated { + return &TicketCreated{ + options: &sdk.TriggerInfo{ + Name: "New Deal Added", + Description: "triggers workflow when a new deal is added", + RequireAuth: true, + Auth: sharedAuth, + Type: sdkcore.TriggerTypeCron, + Input: map[string]*sdkcore.AutoFormSchema{ + "id": autoform.NewShortTextField(). + SetDisplayName(""). + SetDescription(""). + Build(), + }, + Settings: &sdkcore.TriggerSettings{}, + ErrorSettings: &sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + }, + } +} + +func (t *DealCreated) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + reqURL := "/crm/v3/objects/deals?limit=50&archived=false&properties=createdAt,updatedAt" + + if ctx.Metadata.LastRun != nil { + createdAfter := ctx.Metadata.LastRun.UTC().Format(time.RFC3339) + reqURL += "&createdAfter=" + createdAfter + } + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodGet, nil) + if err != nil { + return nil, err + } + return resp, nil +} + +func (t *DealCreated) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return t.Run(ctx) +} + +func (t *DealCreated) OnEnabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *DealCreated) OnDisabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *DealCreated) GetInfo() *sdk.TriggerInfo { + return t.options +} diff --git a/internal/connectors/hubspot/trigger_new_task.go b/internal/connectors/hubspot/trigger_new_task.go new file mode 100644 index 0000000..897fe1f --- /dev/null +++ b/internal/connectors/hubspot/trigger_new_task.go @@ -0,0 +1,82 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "net/http" + "time" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type TaskCreated struct { + options *sdk.TriggerInfo +} + +func NewTaskCreated() *TicketCreated { + return &TicketCreated{ + options: &sdk.TriggerInfo{ + Name: "New Task Added", + Description: "triggers workflow when a new task has been added", + RequireAuth: true, + Auth: sharedAuth, + Type: sdkcore.TriggerTypeCron, + Input: map[string]*sdkcore.AutoFormSchema{ + "id": autoform.NewShortTextField(). + SetDisplayName(""). + SetDescription(""). + Build(), + }, + Settings: &sdkcore.TriggerSettings{}, + ErrorSettings: &sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + }, + } +} + +func (t *TaskCreated) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + reqURL := "/crm/v3/objects/tasks?limit=50&archived=false&properties=createdAt,updatedAt" + + if ctx.Metadata.LastRun != nil { + createdAfter := ctx.Metadata.LastRun.UTC().Format(time.RFC3339) + reqURL += "&createdAfter=" + createdAfter + } + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodGet, nil) + if err != nil { + return nil, err + } + return resp, nil +} + +func (t *TaskCreated) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return t.Run(ctx) +} + +func (t *TaskCreated) OnEnabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *TaskCreated) OnDisabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *TaskCreated) GetInfo() *sdk.TriggerInfo { + return t.options +} diff --git a/internal/connectors/hubspot/trigger_new_ticket.go b/internal/connectors/hubspot/trigger_new_ticket.go new file mode 100644 index 0000000..9320940 --- /dev/null +++ b/internal/connectors/hubspot/trigger_new_ticket.go @@ -0,0 +1,82 @@ +// Copyright 2022-present Wakflo +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package hubspot + +import ( + "net/http" + "time" + + "github.com/wakflo/go-sdk/autoform" + sdk "github.com/wakflo/go-sdk/connector" + sdkcore "github.com/wakflo/go-sdk/core" +) + +type TicketCreated struct { + options *sdk.TriggerInfo +} + +func NewTicketCreated() *TicketCreated { + return &TicketCreated{ + options: &sdk.TriggerInfo{ + Name: "New Ticket Added", + Description: "triggers workflow when a new ticket has been created", + RequireAuth: true, + Auth: sharedAuth, + Type: sdkcore.TriggerTypeCron, + Input: map[string]*sdkcore.AutoFormSchema{ + "id": autoform.NewShortTextField(). + SetDisplayName(""). + SetDescription(""). + Build(), + }, + Settings: &sdkcore.TriggerSettings{}, + ErrorSettings: &sdkcore.StepErrorSettings{ + ContinueOnError: false, + RetryOnError: false, + }, + }, + } +} + +func (t *TicketCreated) Run(ctx *sdk.RunContext) (sdk.JSON, error) { + reqURL := "/crm/v3/objects/tickets?limit=50&archived=false&properties=createdAt,updatedAt" + + if ctx.Metadata.LastRun != nil { + createdAfter := ctx.Metadata.LastRun.UTC().Format(time.RFC3339) + reqURL += "&createdAfter=" + createdAfter + } + + resp, err := hubspotClient(reqURL, ctx.Auth.AccessToken, http.MethodGet, nil) + if err != nil { + return nil, err + } + return resp, nil +} + +func (t *TicketCreated) Test(ctx *sdk.RunContext) (sdk.JSON, error) { + return t.Run(ctx) +} + +func (t *TicketCreated) OnEnabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *TicketCreated) OnDisabled(ctx *sdk.RunContext) error { + return nil +} + +func (t *TicketCreated) GetInfo() *sdk.TriggerInfo { + return t.options +}