projects

package
v0.0.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 10, 2025 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type LegacyDate

type LegacyDate time.Time

LegacyDate is a type alias for time.Time, used to represent legacy date values in the API.

func (LegacyDate) MarshalJSON

func (d LegacyDate) MarshalJSON() ([]byte, error)

MarshalJSON encodes the LegacyDate as a string in the format "20060102".

func (*LegacyDate) UnmarshalJSON

func (d *LegacyDate) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a JSON string into a LegacyDate type.

type LegacyNumber

type LegacyNumber int64

LegacyNumber is a type alias for int64, used to represent numeric values in the API.

func (LegacyNumber) MarshalJSON

func (n LegacyNumber) MarshalJSON() ([]byte, error)

MarshalJSON encodes the LegacyNumber as a string.

func (*LegacyNumber) UnmarshalJSON

func (n *LegacyNumber) UnmarshalJSON(data []byte) error

UnmarshalJSON decodes a JSON string into a LegacyNumber type.

type Project added in v0.0.3

type Project struct {
	// ID is the unique identifier of the project.
	ID int64 `json:"id"`

	// Description is an optional description of the project.
	Description *string `json:"description"`

	// Name is the name of the project.
	Name string `json:"name"`

	// StartAt is the start date of the project.
	StartAt *time.Time `json:"startAt"`

	// EndAt is the end date of the project.
	EndAt *time.Time `json:"endAt"`

	// Company is the company associated with the project.
	Company twapi.Relationship `json:"company"`

	// Owner is the user who owns the project.
	Owner *twapi.Relationship `json:"projectOwner"`

	// Tags is a list of tags associated with the project.
	Tags []twapi.Relationship `json:"tags"`

	// CreatedAt is the date and time when the project was created.
	CreatedAt *time.Time `json:"createdAt"`

	// CreatedBy is the ID of the user who created the project.
	CreatedBy *int64 `json:"createdBy"`

	// UpdatedAt is the date and time when the project was last updated.
	UpdatedAt *time.Time `json:"updatedAt"`

	// UpdatedBy is the ID of the user who last updated the project.
	UpdatedBy *int64 `json:"updatedBy"`

	// CompletedAt is the date and time when the project was completed.
	CompletedAt *time.Time `json:"completedAt"`

	// CompletedBy is the ID of the user who completed the project.
	CompletedBy *int64 `json:"completedBy"`

	// Status is the status of the project. It can be "active", "inactive"
	// (archived) or "deleted".
	Status string `json:"status"`

	// Type is the type of the project. It can be "normal", "tasklists-template",
	// "projects-template", "personal", "holder-project", "tentative" or
	// "global-messages".
	Type string `json:"type"`
}

Project represents a project in Teamwork.

type ProjectCreateRequest

type ProjectCreateRequest struct {
	// Name is the name of the project.
	Name string `json:"name"`

	// Description is an optional description of the project.
	Description *string `json:"description,omitempty"`

	// StartAt is an optional start date for the project. By default it doesn't
	// have a start date.
	StartAt *LegacyDate `json:"start-date,omitempty"`

	// EndAt is an optional end date for the project. By default it doesn't have
	// an end date.
	EndAt *LegacyDate `json:"end-date,omitempty"`

	// CompanyID is an optional ID of the company/client associated with the
	// project. By default it is the ID of the company of the logged user
	// creating the project.
	CompanyID int64 `json:"companyId"`

	// OwnerID is an optional ID of the user who owns the project. By default it
	// is the ID of the logged user creating the project.
	OwnerID *int64 `json:"projectOwnerId,omitempty"`

	// TagIDs is an optional list of tag IDs associated with the project.
	TagIDs []int64 `json:"tagIds,omitempty"`
}

ProjectCreateRequest represents the request body for creating a new project.

https://apidocs.teamwork.com/docs/teamwork/v1/projects/post-projects-json

func NewProjectCreateRequest added in v0.0.6

func NewProjectCreateRequest(name string) ProjectCreateRequest

NewProjectCreateRequest creates a new ProjectCreateRequest with the provided name. The name is required to create a new project.

func (ProjectCreateRequest) HTTPRequest

func (c ProjectCreateRequest) HTTPRequest(ctx context.Context, server string) (*http.Request, error)

HTTPRequest creates an HTTP request for the ProjectCreateRequest.

type ProjectCreateResponse

type ProjectCreateResponse struct {
	// ID is the unique identifier of the created project.
	ID LegacyNumber `json:"id"`
}

ProjectCreateResponse represents the response body for creating a new project.

https://apidocs.teamwork.com/docs/teamwork/v1/projects/post-projects-json

func ProjectCreate

func ProjectCreate(
	ctx context.Context,
	engine *twapi.Engine,
	req ProjectCreateRequest,
) (*ProjectCreateResponse, error)

ProjectCreate creates a new project using the provided request and returns the response.

Example
package main

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"strings"
	"time"

	twapi "github.com/teamwork/twapi-go-sdk"
	"github.com/teamwork/twapi-go-sdk/projects"
	"github.com/teamwork/twapi-go-sdk/session"
)

func main() {
	address, stop, err := startProjectServer() // mock server for demonstration purposes
	if err != nil {
		fmt.Printf("failed to start server: %s", err)
		return
	}
	defer stop()

	ctx := context.Background()
	engine := twapi.NewEngine(session.NewBearerToken("your_token", fmt.Sprintf("http://%s", address)))

	project, err := projects.ProjectCreate(ctx, engine, projects.ProjectCreateRequest{
		Name:        "New Project",
		Description: twapi.Ptr("This is a new project created via the API."),
		StartAt:     twapi.Ptr(projects.LegacyDate(time.Now().AddDate(0, 0, 1))),  // Start tomorrow
		EndAt:       twapi.Ptr(projects.LegacyDate(time.Now().AddDate(0, 0, 30))), // End in 30 days
		CompanyID:   12345,                                                        // Replace with your company ID
		OwnerID:     twapi.Ptr(int64(67890)),                                      // Replace with the owner user ID
		TagIDs:      []int64{11111, 22222},                                        // Replace with your tag IDs
	})
	if err != nil {
		fmt.Printf("failed to create project: %s", err)
	} else {
		fmt.Printf("created project with identifier %d\n", project.ID)
	}

}

func startProjectServer() (string, func(), error) {
	ln, err := net.Listen("tcp", "localhost:0")
	if err != nil {
		return "", nil, fmt.Errorf("failed to start server: %w", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("POST /projects", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusCreated)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK","id":"12345"}`)
	})
	mux.HandleFunc("PUT /projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("DELETE /projects/{id}", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.PathValue("id") != "12345" {
			http.Error(w, "Not Found", http.StatusNotFound)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"project":{"id":12345}}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"projects":[{"id":12345},{"id":12346}]}`)
	})

	server := &http.Server{
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			if r.Header.Get("Authorization") != "Bearer your_token" {
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}
			r.URL.Path = strings.TrimSuffix(r.URL.Path, ".json")
			mux.ServeHTTP(w, r)
		}),
	}

	stop := make(chan struct{})
	go func() {
		_ = server.Serve(ln)
	}()
	go func() {
		<-stop
		_ = server.Shutdown(context.Background())
	}()

	return ln.Addr().String(), func() {
		close(stop)
	}, nil
}
Output:

created project with identifier 12345

func (*ProjectCreateResponse) HandleHTTPResponse

func (c *ProjectCreateResponse) HandleHTTPResponse(resp *http.Response) error

HandleHTTPResponse handles the HTTP response for the ProjectCreateResponse. If some unexpected HTTP status code is returned by the API, a twapi.HTTPError is returned.

type ProjectDeleteRequest added in v0.0.3

type ProjectDeleteRequest struct {
	// Path contains the path parameters for the request.
	Path ProjectDeleteRequestPath
}

ProjectDeleteRequest represents the request body for deleting a project.

https://apidocs.teamwork.com/docs/teamwork/v1/projects/delete-projects-id-json

func NewProjectDeleteRequest added in v0.0.6

func NewProjectDeleteRequest(projectID int64) ProjectDeleteRequest

NewProjectDeleteRequest creates a new ProjectDeleteRequest with the provided project ID.

func (ProjectDeleteRequest) HTTPRequest added in v0.0.3

func (c ProjectDeleteRequest) HTTPRequest(ctx context.Context, server string) (*http.Request, error)

HTTPRequest creates an HTTP request for the ProjectDeleteRequest.

type ProjectDeleteRequestPath added in v0.0.6

type ProjectDeleteRequestPath struct {
	// ID is the unique identifier of the project to be deleted.
	ID int64
}

ProjectDeleteRequestPath contains the path parameters for deleting a project.

type ProjectDeleteResponse added in v0.0.3

type ProjectDeleteResponse struct{}

ProjectDeleteResponse represents the response body for deleting a project.

https://apidocs.teamwork.com/docs/teamwork/v1/projects/delete-projects-id-json

func ProjectDelete added in v0.0.3

func ProjectDelete(
	ctx context.Context,
	engine *twapi.Engine,
	req ProjectDeleteRequest,
) (*ProjectDeleteResponse, error)

ProjectDelete creates a new project using the provided request and returns the response.

Example
package main

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"strings"

	twapi "github.com/teamwork/twapi-go-sdk"
	"github.com/teamwork/twapi-go-sdk/projects"
	"github.com/teamwork/twapi-go-sdk/session"
)

func main() {
	address, stop, err := startProjectServer() // mock server for demonstration purposes
	if err != nil {
		fmt.Printf("failed to start server: %s", err)
		return
	}
	defer stop()

	ctx := context.Background()
	engine := twapi.NewEngine(session.NewBearerToken("your_token", fmt.Sprintf("http://%s", address)))

	_, err = projects.ProjectDelete(ctx, engine, projects.ProjectDeleteRequest{
		Path: projects.ProjectDeleteRequestPath{
			ID: 12345,
		},
	})
	if err != nil {
		fmt.Printf("failed to delete project: %s", err)
	} else {
		fmt.Println("project deleted!")
	}

}

func startProjectServer() (string, func(), error) {
	ln, err := net.Listen("tcp", "localhost:0")
	if err != nil {
		return "", nil, fmt.Errorf("failed to start server: %w", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("POST /projects", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusCreated)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK","id":"12345"}`)
	})
	mux.HandleFunc("PUT /projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("DELETE /projects/{id}", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.PathValue("id") != "12345" {
			http.Error(w, "Not Found", http.StatusNotFound)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"project":{"id":12345}}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"projects":[{"id":12345},{"id":12346}]}`)
	})

	server := &http.Server{
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			if r.Header.Get("Authorization") != "Bearer your_token" {
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}
			r.URL.Path = strings.TrimSuffix(r.URL.Path, ".json")
			mux.ServeHTTP(w, r)
		}),
	}

	stop := make(chan struct{})
	go func() {
		_ = server.Serve(ln)
	}()
	go func() {
		<-stop
		_ = server.Shutdown(context.Background())
	}()

	return ln.Addr().String(), func() {
		close(stop)
	}, nil
}
Output:

project deleted!

func (*ProjectDeleteResponse) HandleHTTPResponse added in v0.0.3

func (c *ProjectDeleteResponse) HandleHTTPResponse(resp *http.Response) error

HandleHTTPResponse handles the HTTP response for the ProjectDeleteResponse. If some unexpected HTTP status code is returned by the API, a twapi.HTTPError is returned.

type ProjectGetRequest added in v0.0.6

type ProjectGetRequest struct {
	// Path contains the path parameters for the request.
	Path ProjectGetRequestPath
}

ProjectGetRequest represents the request body for loading a single project.

https://apidocs.teamwork.com/docs/teamwork/v3/projects/get-projects-api-v3-projects-project-id-json

func NewProjectGetRequest added in v0.0.6

func NewProjectGetRequest(projectID int64) ProjectGetRequest

NewProjectGetRequest creates a new ProjectGetRequest with the provided project ID. The ID is required to load a project.

func (ProjectGetRequest) HTTPRequest added in v0.0.6

func (p ProjectGetRequest) HTTPRequest(ctx context.Context, server string) (*http.Request, error)

HTTPRequest creates an HTTP request for the ProjectGetRequest.

type ProjectGetRequestPath added in v0.0.6

type ProjectGetRequestPath struct {
	// ID is the unique identifier of the project to be retrieved.
	ID int64 `json:"id"`
}

ProjectGetRequestPath contains the path parameters for loading a single project.

type ProjectGetResponse added in v0.0.6

type ProjectGetResponse struct {
	Project Project `json:"project"`
}

ProjectGetResponse contains all the information related to a project.

https://apidocs.teamwork.com/docs/teamwork/v3/projects/get-projects-api-v3-projects-project-id-json

func ProjectGet added in v0.0.6

func ProjectGet(
	ctx context.Context,
	engine *twapi.Engine,
	req ProjectGetRequest,
) (*ProjectGetResponse, error)

ProjectGet retrieves a single project using the provided request and returns the response.

Example
package main

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"strings"

	twapi "github.com/teamwork/twapi-go-sdk"
	"github.com/teamwork/twapi-go-sdk/projects"
	"github.com/teamwork/twapi-go-sdk/session"
)

func main() {
	address, stop, err := startProjectServer() // mock server for demonstration purposes
	if err != nil {
		fmt.Printf("failed to start server: %s", err)
		return
	}
	defer stop()

	ctx := context.Background()
	engine := twapi.NewEngine(session.NewBearerToken("your_token", fmt.Sprintf("http://%s", address)))

	projectResponse, err := projects.ProjectGet(ctx, engine, projects.ProjectGetRequest{
		Path: projects.ProjectGetRequestPath{
			ID: 12345,
		},
	})
	if err != nil {
		fmt.Printf("failed to retrieve project: %s", err)
	} else {
		fmt.Printf("retrieved project with identifier %d\n", projectResponse.Project.ID)
	}

}

func startProjectServer() (string, func(), error) {
	ln, err := net.Listen("tcp", "localhost:0")
	if err != nil {
		return "", nil, fmt.Errorf("failed to start server: %w", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("POST /projects", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusCreated)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK","id":"12345"}`)
	})
	mux.HandleFunc("PUT /projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("DELETE /projects/{id}", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.PathValue("id") != "12345" {
			http.Error(w, "Not Found", http.StatusNotFound)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"project":{"id":12345}}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"projects":[{"id":12345},{"id":12346}]}`)
	})

	server := &http.Server{
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			if r.Header.Get("Authorization") != "Bearer your_token" {
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}
			r.URL.Path = strings.TrimSuffix(r.URL.Path, ".json")
			mux.ServeHTTP(w, r)
		}),
	}

	stop := make(chan struct{})
	go func() {
		_ = server.Serve(ln)
	}()
	go func() {
		<-stop
		_ = server.Shutdown(context.Background())
	}()

	return ln.Addr().String(), func() {
		close(stop)
	}, nil
}
Output:

retrieved project with identifier 12345

func (*ProjectGetResponse) HandleHTTPResponse added in v0.0.6

func (p *ProjectGetResponse) HandleHTTPResponse(resp *http.Response) error

HandleHTTPResponse handles the HTTP response for the ProjectGetResponse. If some unexpected HTTP status code is returned by the API, a twapi.HTTPError is returned.

type ProjectListRequest added in v0.0.6

type ProjectListRequest struct {
	// Filters contains the filters for loading multiple projects.
	Filters ProjectListRequestFilters
}

ProjectListRequest represents the request body for loading multiple projects.

https://apidocs.teamwork.com/docs/teamwork/v3/projects/get-projects-api-v3-projects-json

func NewProjectListRequest added in v0.0.6

func NewProjectListRequest() ProjectListRequest

NewProjectListRequest creates a new ProjectListRequest with default values.

func (ProjectListRequest) HTTPRequest added in v0.0.6

func (p ProjectListRequest) HTTPRequest(ctx context.Context, server string) (*http.Request, error)

HTTPRequest creates an HTTP request for the ProjectListRequest.

type ProjectListRequestFilters added in v0.0.6

type ProjectListRequestFilters struct {
	// SearchTerm is an optional search term to filter projects by name or
	// description.
	SearchTerm string

	// TagIDs is an optional list of tag IDs to filter projects by tags.
	TagIDs []int64

	// MatchAllTags is an optional flag to indicate if all tags must match. If
	// set to true, only projects matching all specified tags will be returned.
	MatchAllTags *bool

	// Page is the page number to retrieve. Defaults to 1.
	Page int64

	// PageSize is the number of projects to retrieve per page. Defaults to 50.
	PageSize int64
}

ProjectListRequestFilters contains the filters for loading multiple projects.

type ProjectListResponse added in v0.0.6

type ProjectListResponse struct {
	Meta struct {
		Page struct {
			HasMore bool `json:"hasMore"`
		} `json:"page"`
	} `json:"meta"`
	Projects []Project `json:"projects"`
}

ProjectListResponse contains information by multiple projects matching the request filters.

https://apidocs.teamwork.com/docs/teamwork/v3/projects/get-projects-api-v3-projects-json

func ProjectList added in v0.0.6

func ProjectList(
	ctx context.Context,
	engine *twapi.Engine,
	req ProjectListRequest,
) (*ProjectListResponse, error)

ProjectList retrieves multiple projects using the provided request and returns the response.

Example
package main

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"strings"

	twapi "github.com/teamwork/twapi-go-sdk"
	"github.com/teamwork/twapi-go-sdk/projects"
	"github.com/teamwork/twapi-go-sdk/session"
)

func main() {
	address, stop, err := startProjectServer() // mock server for demonstration purposes
	if err != nil {
		fmt.Printf("failed to start server: %s", err)
		return
	}
	defer stop()

	ctx := context.Background()
	engine := twapi.NewEngine(session.NewBearerToken("your_token", fmt.Sprintf("http://%s", address)))

	projectsResponse, err := projects.ProjectList(ctx, engine, projects.ProjectListRequest{
		Filters: projects.ProjectListRequestFilters{
			SearchTerm: "Example",
		},
	})
	if err != nil {
		fmt.Printf("failed to list projects: %s", err)
	} else {
		for _, project := range projectsResponse.Projects {
			fmt.Printf("retrieved project with identifier %d\n", project.ID)
		}
	}

}

func startProjectServer() (string, func(), error) {
	ln, err := net.Listen("tcp", "localhost:0")
	if err != nil {
		return "", nil, fmt.Errorf("failed to start server: %w", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("POST /projects", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusCreated)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK","id":"12345"}`)
	})
	mux.HandleFunc("PUT /projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("DELETE /projects/{id}", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.PathValue("id") != "12345" {
			http.Error(w, "Not Found", http.StatusNotFound)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"project":{"id":12345}}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"projects":[{"id":12345},{"id":12346}]}`)
	})

	server := &http.Server{
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			if r.Header.Get("Authorization") != "Bearer your_token" {
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}
			r.URL.Path = strings.TrimSuffix(r.URL.Path, ".json")
			mux.ServeHTTP(w, r)
		}),
	}

	stop := make(chan struct{})
	go func() {
		_ = server.Serve(ln)
	}()
	go func() {
		<-stop
		_ = server.Shutdown(context.Background())
	}()

	return ln.Addr().String(), func() {
		close(stop)
	}, nil
}
Output:

retrieved project with identifier 12345
retrieved project with identifier 12346

func (*ProjectListResponse) HandleHTTPResponse added in v0.0.6

func (p *ProjectListResponse) HandleHTTPResponse(resp *http.Response) error

HandleHTTPResponse handles the HTTP response for the ProjectListResponse. If some unexpected HTTP status code is returned by the API, a twapi.HTTPError is returned.

type ProjectUpdateRequest added in v0.0.3

type ProjectUpdateRequest struct {
	// Path contains the path parameters for the request.
	Path ProjectUpdateRequestPath

	// Name is the name of the project.
	Name *string `json:"name,omitempty"`

	// Description is the project description.
	Description *string `json:"description,omitempty"`

	// StartAt is the start date for the project.
	StartAt *LegacyDate `json:"start-date,omitempty"`

	// EndAt is the end date for the project.
	EndAt *LegacyDate `json:"end-date,omitempty"`

	// CompanyID is the company/client associated with the project.
	CompanyID *int64 `json:"companyId,omitempty"`

	// OwnerID is the ID of the user who owns the project.
	OwnerID *int64 `json:"projectOwnerId,omitempty"`

	// TagIDs is the list of tag IDs associated with the project.
	TagIDs []int64 `json:"tagIds,omitempty"`
}

ProjectUpdateRequest represents the request body for updating a project. Besides the identifier, all other fields are optional. When a field is not provided, it will not be modified.

https://apidocs.teamwork.com/docs/teamwork/v1/projects/put-projects-id-json

func NewProjectUpdateRequest added in v0.0.6

func NewProjectUpdateRequest(projectID int64) ProjectUpdateRequest

NewProjectUpdateRequest creates a new ProjectUpdateRequest with the provided project ID. The ID is required to update a project.

func (ProjectUpdateRequest) HTTPRequest added in v0.0.3

func (c ProjectUpdateRequest) HTTPRequest(ctx context.Context, server string) (*http.Request, error)

HTTPRequest creates an HTTP request for the ProjectUpdateRequest.

type ProjectUpdateRequestPath added in v0.0.6

type ProjectUpdateRequestPath struct {
	// ID is the unique identifier of the project to be updated.
	ID int64
}

ProjectUpdateRequestPath contains the path parameters for updating a project.

type ProjectUpdateResponse added in v0.0.3

type ProjectUpdateResponse struct{}

ProjectUpdateResponse represents the response body for updating a project.

https://apidocs.teamwork.com/docs/teamwork/v1/projects/put-projects-id-json

func ProjectUpdate added in v0.0.3

func ProjectUpdate(
	ctx context.Context,
	engine *twapi.Engine,
	req ProjectUpdateRequest,
) (*ProjectUpdateResponse, error)

ProjectUpdate creates a new project using the provided request and returns the response.

Example
package main

import (
	"context"
	"fmt"
	"net"
	"net/http"
	"strings"

	twapi "github.com/teamwork/twapi-go-sdk"
	"github.com/teamwork/twapi-go-sdk/projects"
	"github.com/teamwork/twapi-go-sdk/session"
)

func main() {
	address, stop, err := startProjectServer() // mock server for demonstration purposes
	if err != nil {
		fmt.Printf("failed to start server: %s", err)
		return
	}
	defer stop()

	ctx := context.Background()
	engine := twapi.NewEngine(session.NewBearerToken("your_token", fmt.Sprintf("http://%s", address)))

	_, err = projects.ProjectUpdate(ctx, engine, projects.ProjectUpdateRequest{
		Path: projects.ProjectUpdateRequestPath{
			ID: 12345,
		},
		Description: twapi.Ptr("This is an updated description."),
	})
	if err != nil {
		fmt.Printf("failed to update project: %s", err)
	} else {
		fmt.Println("project updated!")
	}

}

func startProjectServer() (string, func(), error) {
	ln, err := net.Listen("tcp", "localhost:0")
	if err != nil {
		return "", nil, fmt.Errorf("failed to start server: %w", err)
	}

	mux := http.NewServeMux()
	mux.HandleFunc("POST /projects", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusCreated)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK","id":"12345"}`)
	})
	mux.HandleFunc("PUT /projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.Header.Get("Content-Type") != "application/json" {
			http.Error(w, "Unsupported Media Type", http.StatusUnsupportedMediaType)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("DELETE /projects/{id}", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"STATUS":"OK"}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects/{id}", func(w http.ResponseWriter, r *http.Request) {
		if r.PathValue("id") != "12345" {
			http.Error(w, "Not Found", http.StatusNotFound)
			return
		}
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"project":{"id":12345}}`)
	})
	mux.HandleFunc("GET /projects/api/v3/projects", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
		w.Header().Set("Content-Type", "application/json")
		_, _ = fmt.Fprintln(w, `{"projects":[{"id":12345},{"id":12346}]}`)
	})

	server := &http.Server{
		Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			if r.Header.Get("Authorization") != "Bearer your_token" {
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}
			r.URL.Path = strings.TrimSuffix(r.URL.Path, ".json")
			mux.ServeHTTP(w, r)
		}),
	}

	stop := make(chan struct{})
	go func() {
		_ = server.Serve(ln)
	}()
	go func() {
		<-stop
		_ = server.Shutdown(context.Background())
	}()

	return ln.Addr().String(), func() {
		close(stop)
	}, nil
}
Output:

project updated!

func (*ProjectUpdateResponse) HandleHTTPResponse added in v0.0.3

func (c *ProjectUpdateResponse) HandleHTTPResponse(resp *http.Response) error

HandleHTTPResponse handles the HTTP response for the ProjectUpdateResponse. If some unexpected HTTP status code is returned by the API, a twapi.HTTPError is returned.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL