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

feat: implement smartsheet connector #70

Merged
merged 1 commit into from
Nov 15, 2024
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: 2 additions & 0 deletions connectors.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ import (
"github.com/wakflo/extensions/internal/connectors/shippo"
"github.com/wakflo/extensions/internal/connectors/shopify"
"github.com/wakflo/extensions/internal/connectors/slack"
"github.com/wakflo/extensions/internal/connectors/smartsheet"
"github.com/wakflo/extensions/internal/connectors/square"
"github.com/wakflo/extensions/internal/connectors/stripe"
"github.com/wakflo/extensions/internal/connectors/todoist"
Expand Down Expand Up @@ -121,6 +122,7 @@ func RegisterConnectors() []*sdk.ConnectorPlugin {
github.NewConnector, // Github
trello.NewConnector, // Trello
notion.NewConnector, // Notion
smartsheet.NewConnector, // Smartsheet
}

// 🛑Do-Not-Edit
Expand Down
34 changes: 34 additions & 0 deletions internal/connectors/smartsheet/lib.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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 smartsheet

import (
sdk "github.com/wakflo/go-sdk/connector"
)

func NewConnector() (*sdk.ConnectorPlugin, error) {
return sdk.CreateConnector(&sdk.CreateConnectorArgs{
Name: "Smartsheet",
Description: "Work management that adapts to your needs.",
Logo: "ph:check-square-duotone",
Version: "0.0.1",
Group: sdk.ConnectorGroupApps,
Authors: []string{"Wakflo <integrations@wakflo.com>"},
Triggers: []sdk.ITrigger{},
Operations: []sdk.IOperation{
NewListSheetsOperation(),
},
})
}
71 changes: 71 additions & 0 deletions internal/connectors/smartsheet/operation_list_sheets.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// 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 smartsheet

import (
"github.com/wakflo/go-sdk/autoform"
sdk "github.com/wakflo/go-sdk/connector"
sdkcore "github.com/wakflo/go-sdk/core"
)

type listInvoicesOperationProps struct {
Name string `json:"name"`
}

type ListSheetsOperation struct {
options *sdk.OperationInfo
}

func NewListSheetsOperation() *ListSheetsOperation {
return &ListSheetsOperation{
options: &sdk.OperationInfo{
Name: "List Sheets",
Description: "list all sheets",
Auth: sharedAuth,
Input: map[string]*sdkcore.AutoFormSchema{
"name": autoform.NewShortTextField().
SetDisplayName("").
SetDescription("").
SetRequired(false).Build(),
},
SampleOutput: map[string]interface{}{},
ErrorSettings: sdkcore.StepErrorSettings{
ContinueOnError: false,
RetryOnError: false,
},
RequireAuth: true,
},
}
}

func (c *ListSheetsOperation) Run(ctx *sdk.RunContext) (sdk.JSON, error) {
_ = sdk.InputToType[listInvoicesOperationProps](ctx)

url := "/2.0/sheets"

sheets, err := getSmartsheetClient(ctx.Auth.AccessToken, url)
if err != nil {
return nil, err
}
return sheets, nil
}

func (c *ListSheetsOperation) Test(ctx *sdk.RunContext) (sdk.JSON, error) {
return c.Run(ctx)
}

func (c *ListSheetsOperation) GetInfo() *sdk.OperationInfo {
return c.options
}
72 changes: 72 additions & 0 deletions internal/connectors/smartsheet/shared.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// 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 smartsheet

import (
"encoding/json"
"errors"
"fmt"
"io"
"net/http"

"github.com/wakflo/go-sdk/autoform"
)

var (
// #nosec
tokenURL = "https://api.smartsheet.com/2.0/token"
sharedAuth = autoform.NewOAuthField("https://app.smartsheet.com/b/authorize", &tokenURL, []string{
"ADMIN_SHEETS ADMIN_USERS ADMIN_WEBHOOKS SHARE_SHEETS WRITE_SHEETS ADMIN_WORKSPACES CREATE_SHEETS READ_CONTACTS DELETE_SHEETS READ_SHEETS READ_USERS",
}).Build()
)

const baseURL = "https://api.smartsheet.com"

func getSmartsheetClient(accessToken, url string) (map[string]interface{}, error) {
fullURL := baseURL + url
req, err := http.NewRequest(http.MethodGet, fullURL, nil)
if err != nil {
return nil, fmt.Errorf("error creating request: %v", err)
}

req.Header.Set("Authorization", "Bearer "+accessToken)
req.Header.Set("Content-Type", "application/json")

client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("error sending request: %v", err)
}
defer resp.Body.Close()

body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("error reading response body: %v", err)
}

fmt.Println("Response Body:", string(body))

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("API request failed with status code %d: %s", resp.StatusCode, string(body))
}

var result map[string]interface{}
err = json.Unmarshal(body, &result)
if err != nil {
return nil, errors.New("error unmarshalling response")
}

return result, nil
}
Loading