func (client *Client) GetFolderByTitle(ctx context.Context, title string) (*Folder, error) {
	resp, err := client.get(ctx, "/api/folders?limit=1000")
	if err != nil {
		return nil, err
	}
	defer func() { _ = resp.Body.Close() }()
	if resp.StatusCode != http.StatusOK {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return nil, err
		}
		return nil, fmt.Errorf("could list folders: %s (HTTP status %d)", body, resp.StatusCode)
	}
	var folders []Folder
	if err := decodeJSON(resp.Body, &folders); err != nil {
		return nil, err
	}
	for i := range folders {
		if strings.EqualFold(folders[i].Title, title) {
			return &folders[i], nil
		}
	}
	return nil, ErrFolderNotFound
}
GetFolderByTitle finds a folder, given its title.
package grabana
import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"github.com/K-Phoen/grabana/alert"
	"github.com/K-Phoen/grabana/dashboard"
	"github.com/grafana-tools/sdk"
)
var ErrFolderNotFound = errors.New("folder not found")
var ErrAlertChannelNotFound = errors.New("alert channel not found")
type Dashboard struct {
	ID  uint   `json:"id"`
	UID string `json:"uid"`
	URL string `json:"url"`
}
type Folder struct {
	ID    uint   `json:"id"`
	UID   string `json:"uid"`
	Title string `json:"title"`
}
type Option func(client *Client)
type requestModifier func(request *http.Request)
type Client struct {
	http             *http.Client
	host             string
	requestModifiers []requestModifier
}
func NewClient(http *http.Client, host string, options ...Option) *Client {
	client := &Client{
		http: http,
		host: host,
	}
	for _, opt := range options {
		opt(client)
	}
	return client
}
func WithAPIToken(token string) Option {
	return func(client *Client) {
		client.requestModifiers = append(client.requestModifiers, func(request *http.Request) {
			request.Header.Add("Authorization", fmt.Sprintf("Bearer %s", token))
		})
	}
}
func WithBasicAuth(username string, password string) Option {
	return func(client *Client) {
		client.requestModifiers = append(client.requestModifiers, func(request *http.Request) {
			request.SetBasicAuth(username, password)
		})
	}
}
func (client *Client) modifyRequest(request *http.Request) {
	for _, modifier := range client.requestModifiers {
		modifier(request)
	}
}
func (client *Client) FindOrCreateFolder(ctx context.Context, name string) (*Folder, error) {
	folder, err := client.GetFolderByTitle(ctx, name)
	if err != nil && err != ErrFolderNotFound {
		return nil, fmt.Errorf("could not find or create folder: %w", err)
	}
	if folder == nil {
		folder, err = client.CreateFolder(ctx, name)
		if err != nil {
			return nil, fmt.Errorf("could not find create folder: %w", err)
		}
	}
	return folder, nil
}
func (client *Client) CreateFolder(ctx context.Context, name string) (*Folder, error) {
	buf, err := json.Marshal(struct {
		Title string `json:"title"`
	}{
		Title: name,
	})
	if err != nil {
		return nil, err
	}
	resp, err := client.postJSON(ctx, "/api/folders", buf)
	if err != nil {
		return nil, err
	}
	defer func() { _ = resp.Body.Close() }()
	if resp.StatusCode != http.StatusOK {
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			return nil, err
		}
		return nil, fmt.Errorf("could not create folder: %s (HTTP status %d)", body, resp.StatusCode)
	}
	var folder Folder
	if err := decodeJSON(resp.Body, &folder); err != nil {
		return nil, err
	}
	return &folder, nil
}