241 lines
5.7 KiB
Go
241 lines
5.7 KiB
Go
package monday
|
|
|
|
import (
|
|
"bytes"
|
|
_ "embed"
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
)
|
|
|
|
//go:embed query.graphql
|
|
var requestQuery string
|
|
|
|
const (
|
|
// resource types
|
|
TypeBoard = "Board"
|
|
TypeBoardGroup = "Board Group"
|
|
TypeBoardColumn = "Board Column"
|
|
TypeDoc = "Document"
|
|
TypeFolder = "Folder"
|
|
TypeTag = "Tag"
|
|
TypeTeam = "Team"
|
|
TypeWorkspace = "Workspace"
|
|
)
|
|
|
|
type Request struct {
|
|
Query string `json:"query"`
|
|
}
|
|
|
|
// Response is the Monday Graphql API response in case of success
|
|
type Response struct {
|
|
Data Data `json:"data"`
|
|
}
|
|
|
|
type Data struct {
|
|
Me Me `json:"me"`
|
|
Account Account `json:"account"`
|
|
Users []User `json:"users"`
|
|
Boards []Board `json:"boards"`
|
|
Docs []Doc `json:"docs"`
|
|
Folders []EntityRef `json:"folders"`
|
|
Tags []EntityRef `json:"tags"`
|
|
Teams []EntityRef `json:"teams"`
|
|
Workspaces []Workspace `json:"workspaces"`
|
|
}
|
|
|
|
type EntityRef struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
type Me struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Email string `json:"email"`
|
|
Title string `json:"title"`
|
|
IsAdmin bool `json:"is_admin"`
|
|
IsGuest bool `json:"is_guest"`
|
|
IsViewOnly bool `json:"is_view_only"`
|
|
IsPending bool `json:"is_pending"`
|
|
IsVerified bool `json:"is_verified"`
|
|
Teams []EntityRef `json:"teams"`
|
|
}
|
|
|
|
type Account struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Slug string `json:"slug"`
|
|
Tier string `json:"tier"`
|
|
}
|
|
|
|
type User struct {
|
|
Email string `json:"email"`
|
|
Account Account `json:"account"`
|
|
}
|
|
|
|
type Board struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
State string `json:"state"`
|
|
Permissions string `json:"permissions"`
|
|
Groups []Group `json:"groups"`
|
|
Columns []Column `json:"column"`
|
|
Owners []EntityRef `json:"owner"`
|
|
}
|
|
|
|
type Group struct {
|
|
Title string `json:"title"`
|
|
ID string `json:"id"`
|
|
}
|
|
|
|
type Column struct {
|
|
ID string `json:"id"`
|
|
Title string `json:"title"`
|
|
Type string `json:"type"`
|
|
}
|
|
|
|
type Doc struct {
|
|
ID string `json:"id"`
|
|
ObjectID string `json:"object_id"`
|
|
Name string `json:"name"`
|
|
CreatedBy EntityRef `json:"created_by"`
|
|
}
|
|
|
|
type Workspace struct {
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Kind string `json:"kind"`
|
|
}
|
|
|
|
// captureMondayData send a request to Monday graphql API to get all data and capture it in secret info
|
|
func captureMondayData(client *http.Client, key string, secretInfo *SecretInfo) error {
|
|
jsonData, err := json.Marshal(Request{Query: requestQuery})
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
req, err := http.NewRequest(http.MethodPost, "https://api.monday.com/v2", bytes.NewBuffer(jsonData))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
req.Header.Add("Content-Type", "application/json")
|
|
req.Header.Add("Authorization", key)
|
|
resp, err := client.Do(req)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer func() {
|
|
_, _ = io.Copy(io.Discard, resp.Body)
|
|
_ = resp.Body.Close()
|
|
}()
|
|
|
|
switch resp.StatusCode {
|
|
case http.StatusOK:
|
|
var apiResponse Response
|
|
|
|
if err := json.NewDecoder(resp.Body).Decode(&apiResponse); err != nil {
|
|
return err
|
|
}
|
|
|
|
// capture details in secret info
|
|
responseToSecretInfo(apiResponse, secretInfo)
|
|
|
|
return nil
|
|
case http.StatusUnauthorized:
|
|
return fmt.Errorf("expired/invalid access token")
|
|
default:
|
|
return fmt.Errorf("unexpected status code: %d", resp.StatusCode)
|
|
}
|
|
}
|
|
|
|
// responseToSecretInfo translate api response to secret info
|
|
func responseToSecretInfo(apiResponse Response, secretInfo *SecretInfo) {
|
|
secretInfo.User = apiResponse.Data.Me
|
|
secretInfo.Account = apiResponse.Data.Account
|
|
|
|
processBoards(apiResponse.Data.Boards, secretInfo)
|
|
processDocs(apiResponse.Data.Docs, secretInfo)
|
|
processSimpleEntities(apiResponse.Data.Folders, TypeFolder, secretInfo)
|
|
processSimpleEntities(apiResponse.Data.Tags, TypeTag, secretInfo)
|
|
processSimpleEntities(apiResponse.Data.Teams, TypeTeam, secretInfo)
|
|
processWorkspaces(apiResponse.Data.Workspaces, secretInfo)
|
|
}
|
|
|
|
func processBoards(boards []Board, secretInfo *SecretInfo) {
|
|
for _, board := range boards {
|
|
boardResource := MondayResource{
|
|
ID: board.ID,
|
|
Name: board.Name,
|
|
Type: TypeBoard,
|
|
MetaData: map[string]string{
|
|
"state": board.State,
|
|
"permissions": board.Permissions,
|
|
},
|
|
}
|
|
|
|
secretInfo.appendResource(boardResource)
|
|
|
|
// sub resources of board
|
|
for _, group := range board.Groups {
|
|
secretInfo.appendResource(MondayResource{
|
|
ID: group.ID,
|
|
Name: group.Title,
|
|
Type: TypeBoardGroup,
|
|
Parent: &boardResource,
|
|
})
|
|
}
|
|
|
|
for _, column := range board.Columns {
|
|
secretInfo.appendResource(MondayResource{
|
|
ID: column.ID,
|
|
Name: column.Title,
|
|
Type: TypeBoardColumn,
|
|
MetaData: map[string]string{
|
|
"Column Type": column.Type,
|
|
},
|
|
Parent: &boardResource,
|
|
})
|
|
}
|
|
}
|
|
}
|
|
|
|
func processDocs(docs []Doc, secretInfo *SecretInfo) {
|
|
for _, doc := range docs {
|
|
secretInfo.appendResource(MondayResource{
|
|
ID: doc.ID,
|
|
Name: doc.Name,
|
|
Type: TypeDoc,
|
|
MetaData: map[string]string{
|
|
"created_by": doc.CreatedBy.Name,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
func processSimpleEntities(entities []EntityRef, entityType string, secretInfo *SecretInfo) {
|
|
for _, entity := range entities {
|
|
secretInfo.appendResource(MondayResource{
|
|
ID: entity.ID,
|
|
Name: entity.Name,
|
|
Type: entityType,
|
|
})
|
|
}
|
|
}
|
|
|
|
func processWorkspaces(workspaces []Workspace, secretInfo *SecretInfo) {
|
|
for _, workspace := range workspaces {
|
|
secretInfo.appendResource(MondayResource{
|
|
ID: workspace.ID,
|
|
Name: workspace.Name,
|
|
Type: TypeWorkspace,
|
|
MetaData: map[string]string{
|
|
"workspace_kind": workspace.Kind,
|
|
},
|
|
})
|
|
}
|
|
}
|