Skip to content

Commit 7242028

Browse files
authored
feat: add excel tools (#63)
Signed-off-by: Grant Linville <[email protected]>
1 parent 95991b4 commit 7242028

20 files changed

+733
-0
lines changed

apis/excel/code/.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.idea/
2+
.vscode/
3+
bin/

apis/excel/code/Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.PHONY: build
2+
build:
3+
go build -o bin/gptscript-go-tool .

apis/excel/code/go.mod

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module github.com/gptscript-ai/tools/apis/excel/code
2+
3+
go 1.23.1
4+
5+
require (
6+
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0
7+
github.com/microsoftgraph/msgraph-sdk-go v1.48.0
8+
)
9+
10+
require (
11+
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 // indirect
12+
github.com/cjlapao/common-go v0.0.39 // indirect
13+
github.com/davecgh/go-spew v1.1.1 // indirect
14+
github.com/go-logr/logr v1.4.1 // indirect
15+
github.com/go-logr/stdr v1.2.2 // indirect
16+
github.com/google/uuid v1.6.0 // indirect
17+
github.com/microsoft/kiota-abstractions-go v1.7.0 // indirect
18+
github.com/microsoft/kiota-authentication-azure-go v1.1.0 // indirect
19+
github.com/microsoft/kiota-http-go v1.4.4 // indirect
20+
github.com/microsoft/kiota-serialization-form-go v1.0.0 // indirect
21+
github.com/microsoft/kiota-serialization-json-go v1.0.8 // indirect
22+
github.com/microsoft/kiota-serialization-multipart-go v1.0.0 // indirect
23+
github.com/microsoft/kiota-serialization-text-go v1.0.0 // indirect
24+
github.com/microsoftgraph/msgraph-sdk-go-core v1.2.1 // indirect
25+
github.com/pmezard/go-difflib v1.0.0 // indirect
26+
github.com/std-uritemplate/std-uritemplate/go v0.0.57 // indirect
27+
github.com/stretchr/testify v1.9.0 // indirect
28+
go.opentelemetry.io/otel v1.24.0 // indirect
29+
go.opentelemetry.io/otel/metric v1.24.0 // indirect
30+
go.opentelemetry.io/otel/trace v1.24.0 // indirect
31+
golang.org/x/net v0.27.0 // indirect
32+
golang.org/x/text v0.16.0 // indirect
33+
gopkg.in/yaml.v3 v3.0.1 // indirect
34+
)

apis/excel/code/go.sum

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8=
2+
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0=
3+
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY=
4+
github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY=
5+
github.com/cjlapao/common-go v0.0.39 h1:bAAUrj2B9v0kMzbAOhzjSmiyDy+rd56r2sy7oEiQLlA=
6+
github.com/cjlapao/common-go v0.0.39/go.mod h1:M3dzazLjTjEtZJbbxoA5ZDiGCiHmpwqW9l4UWaddwOA=
7+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
8+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
9+
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
10+
github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ=
11+
github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
12+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
13+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
14+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
15+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
16+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
17+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
18+
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
19+
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
20+
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
21+
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
22+
github.com/microsoft/kiota-abstractions-go v1.7.0 h1:/0OKSSEe94Z1qgpcGE7ZFI9P+4iAnsDQo9v9UOk+R8E=
23+
github.com/microsoft/kiota-abstractions-go v1.7.0/go.mod h1:FI1I2OHg0E7bK5t8DPnw+9C/CHVyLP6XeqDBT+95pTE=
24+
github.com/microsoft/kiota-authentication-azure-go v1.1.0 h1:HudH57Enel9zFQ4TEaJw6lMiyZ5RbBdrRHwdU0NP2RY=
25+
github.com/microsoft/kiota-authentication-azure-go v1.1.0/go.mod h1:zfPFOiLdEqM77Hua5B/2vpcXrVaGqSWjHSRzlvAWEgc=
26+
github.com/microsoft/kiota-http-go v1.4.4 h1:HM0KT/Q7o+JsGatFkkbTIqJL24Jzo5eMI5NNe9N4TQ4=
27+
github.com/microsoft/kiota-http-go v1.4.4/go.mod h1:Kup5nMDD3a9sjdgRKHCqZWqtrv3FbprjcPaGjLR6FzM=
28+
github.com/microsoft/kiota-serialization-form-go v1.0.0 h1:UNdrkMnLFqUCccQZerKjblsyVgifS11b3WCx+eFEsAI=
29+
github.com/microsoft/kiota-serialization-form-go v1.0.0/go.mod h1:h4mQOO6KVTNciMF6azi1J9QB19ujSw3ULKcSNyXXOMA=
30+
github.com/microsoft/kiota-serialization-json-go v1.0.8 h1:+aViv9k6wqaw1Fx6P49fl5GIB1hN3b6CG0McNTcUYBc=
31+
github.com/microsoft/kiota-serialization-json-go v1.0.8/go.mod h1:O8+v11U0EUwHlCz7hrW38KxDmdhKAHfv4Q89uvsBalY=
32+
github.com/microsoft/kiota-serialization-multipart-go v1.0.0 h1:3O5sb5Zj+moLBiJympbXNaeV07K0d46IfuEd5v9+pBs=
33+
github.com/microsoft/kiota-serialization-multipart-go v1.0.0/go.mod h1:yauLeBTpANk4L03XD985akNysG24SnRJGaveZf+p4so=
34+
github.com/microsoft/kiota-serialization-text-go v1.0.0 h1:XOaRhAXy+g8ZVpcq7x7a0jlETWnWrEum0RhmbYrTFnA=
35+
github.com/microsoft/kiota-serialization-text-go v1.0.0/go.mod h1:sM1/C6ecnQ7IquQOGUrUldaO5wj+9+v7G2W3sQ3fy6M=
36+
github.com/microsoftgraph/msgraph-sdk-go v1.48.0 h1:JYKXW90/rjMzbD9kIzD+PzoBBbiNh4dRW6riKg+Bm94=
37+
github.com/microsoftgraph/msgraph-sdk-go v1.48.0/go.mod h1:ghZjDbiV52URFLjZGFZckbLqMW1IgWvQKW4AqLgOm5E=
38+
github.com/microsoftgraph/msgraph-sdk-go-core v1.2.1 h1:P1wpmn3xxfPMFJHg+PJPcusErfRkl63h6OdAnpDbkS8=
39+
github.com/microsoftgraph/msgraph-sdk-go-core v1.2.1/go.mod h1:vFmWQGWyLlhxCESNLv61vlE4qesBU+eWmEVH7DJSESA=
40+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
41+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
42+
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
43+
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
44+
github.com/std-uritemplate/std-uritemplate/go v0.0.57 h1:GHGjptrsmazP4IVDlUprssiEf9ESVkbjx15xQXXzvq4=
45+
github.com/std-uritemplate/std-uritemplate/go v0.0.57/go.mod h1:rG/bqh/ThY4xE5de7Rap3vaDkYUT76B0GPJ0loYeTTc=
46+
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
47+
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
48+
go.opentelemetry.io/otel v1.24.0 h1:0LAOdjNmQeSTzGBzduGe/rU4tZhMwL5rWgtp9Ku5Jfo=
49+
go.opentelemetry.io/otel v1.24.0/go.mod h1:W7b9Ozg4nkF5tWI5zsXkaKKDjdVjpD4oAt9Qi/MArHo=
50+
go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI=
51+
go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco=
52+
go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI=
53+
go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU=
54+
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
55+
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
56+
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
57+
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
58+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
59+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
60+
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
61+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
62+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

apis/excel/code/main.go

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"os"
7+
8+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/commands"
9+
)
10+
11+
func main() {
12+
if len(os.Args) != 2 {
13+
fmt.Println("Usage: gptscript-go-tool <command>")
14+
os.Exit(1)
15+
}
16+
17+
command := os.Args[1]
18+
19+
var err error
20+
switch command {
21+
case "listWorkbooks":
22+
err = commands.ListWorkbooks(context.Background())
23+
case "listWorksheets":
24+
err = commands.ListWorksheets(context.Background(), os.Getenv("WORKBOOK_ID"))
25+
case "getWorksheetData":
26+
err = commands.GetWorksheetData(context.Background(), os.Getenv("WORKBOOK_ID"), os.Getenv("WORKSHEET_ID"))
27+
case "addWorksheetRow":
28+
err = commands.AddWorksheetRow(context.Background(), os.Getenv("WORKBOOK_ID"), os.Getenv("WORKSHEET_ID"), os.Getenv("CONTENTS"))
29+
case "createWorkbook":
30+
err = commands.CreateWorkbook(context.Background(), os.Getenv("NAME"))
31+
case "createWorksheet":
32+
err = commands.CreateWorksheet(context.Background(), os.Getenv("WORKBOOK_ID"), os.Getenv("NAME"))
33+
default:
34+
fmt.Printf("Unknown command: %s\n", command)
35+
os.Exit(1)
36+
}
37+
38+
if err != nil {
39+
fmt.Println(err)
40+
os.Exit(1)
41+
}
42+
}

apis/excel/code/pkg/client/client.go

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package client
2+
3+
import (
4+
"context"
5+
"os"
6+
7+
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
8+
"github.com/Azure/azure-sdk-for-go/sdk/azcore/policy"
9+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/global"
10+
msgraphsdkgo "github.com/microsoftgraph/msgraph-sdk-go"
11+
)
12+
13+
// StaticTokenCredential is taken from https://github.com/gptscript-ai/mail-assistant/blob/10944805801bbb6f71eccefd1bea5f114fded164/pkg/mstoken/auth.go
14+
type StaticTokenCredential struct {
15+
token string
16+
}
17+
18+
func (s StaticTokenCredential) GetToken(_ context.Context, options policy.TokenRequestOptions) (azcore.AccessToken, error) {
19+
return azcore.AccessToken{Token: s.token}, nil
20+
}
21+
22+
func NewClient(scopes []string) (*msgraphsdkgo.GraphServiceClient, error) {
23+
return msgraphsdkgo.NewGraphServiceClientWithCredentials(StaticTokenCredential{
24+
token: os.Getenv(global.CredentialEnv),
25+
}, scopes)
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package commands
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"strings"
7+
8+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/client"
9+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/global"
10+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/graph"
11+
)
12+
13+
func AddWorksheetRow(ctx context.Context, workbookID, worksheetID, contents string) error {
14+
c, err := client.NewClient(global.AllScopes)
15+
if err != nil {
16+
return err
17+
}
18+
19+
if err := graph.AddWorksheetRow(ctx, c, workbookID, worksheetID, strings.Split(contents, ",")); err != nil {
20+
return err
21+
}
22+
fmt.Println("Row added successfully")
23+
return nil
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package commands
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/graph"
8+
)
9+
10+
func CreateWorkbook(ctx context.Context, name string) error {
11+
if name == "" {
12+
return fmt.Errorf("name cannot be empty")
13+
}
14+
15+
id, err := graph.CreateWorkbook(ctx, name)
16+
if err != nil {
17+
return err
18+
}
19+
20+
fmt.Printf("Workbook created with ID: %s\n", id)
21+
return nil
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package commands
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/client"
8+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/global"
9+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/graph"
10+
)
11+
12+
func CreateWorksheet(ctx context.Context, workbookID, name string) error {
13+
c, err := client.NewClient(global.AllScopes)
14+
if err != nil {
15+
return err
16+
}
17+
18+
id, err := graph.CreateWorksheet(ctx, c, workbookID, name)
19+
if err != nil {
20+
return err
21+
}
22+
23+
fmt.Printf("Worksheet created with ID: %s\n", id)
24+
return nil
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package commands
2+
3+
import (
4+
"context"
5+
"encoding/json"
6+
"fmt"
7+
8+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/client"
9+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/global"
10+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/graph"
11+
)
12+
13+
func GetWorksheetData(ctx context.Context, workbookID, worksheetID string) error {
14+
c, err := client.NewClient(global.ReadOnlyScopes)
15+
if err != nil {
16+
return err
17+
}
18+
19+
data, _, err := graph.GetWorksheetData(ctx, c, workbookID, worksheetID)
20+
dataBytes, err := json.Marshal(data)
21+
if err != nil {
22+
return err
23+
}
24+
25+
fmt.Println(string(dataBytes))
26+
return nil
27+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package commands
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/client"
8+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/global"
9+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/graph"
10+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/printers"
11+
)
12+
13+
func ListWorkbooks(ctx context.Context) error {
14+
c, err := client.NewClient(global.ReadOnlyScopes)
15+
if err != nil {
16+
return err
17+
}
18+
19+
workbookInfos, err := graph.ListWorkbooks(ctx, c)
20+
if err != nil {
21+
return fmt.Errorf("failed to list spreadsheets: %w", err)
22+
}
23+
24+
printers.PrintWorkbookInfos(workbookInfos)
25+
return nil
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package commands
2+
3+
import (
4+
"context"
5+
6+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/client"
7+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/global"
8+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/graph"
9+
"github.com/gptscript-ai/tools/apis/excel/code/pkg/printers"
10+
)
11+
12+
func ListWorksheets(ctx context.Context, workbookID string) error {
13+
c, err := client.NewClient(global.ReadOnlyScopes)
14+
if err != nil {
15+
return err
16+
}
17+
18+
infos, err := graph.ListWorksheetsInWorkbook(ctx, c, workbookID)
19+
if err != nil {
20+
return err
21+
}
22+
23+
printers.PrintWorksheetInfos(infos)
24+
return nil
25+
}

apis/excel/code/pkg/global/global.go

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package global
2+
3+
const CredentialEnv = "GPTSCRIPT_MICROSOFT_EXCEL_TOKEN"
4+
5+
var (
6+
ReadOnlyScopes = []string{"Files.Read", "User.Read"}
7+
AllScopes = []string{"Files.Read", "Files.ReadWrite", "User.Read"}
8+
)

0 commit comments

Comments
 (0)