func (s *ProjectsService) GetProjectHook(pid interface{}, hook int, options ...OptionFunc) (*ProjectHook, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s/hooks/%d", url.QueryEscape(project), hook)
	req, err := s.client.NewRequest("GET", u, nil, options)
	if err != nil {
		return nil, nil, err
	}
	ph := new(ProjectHook)
	resp, err := s.client.Do(req, ph)
	if err != nil {
		return nil, resp, err
	}
	return ph, resp, err
}
GetProjectHook gets a specific hook for a project.

GitLab API docs:
https://docs.gitlab.com/ce/api/projects.html#get-project-hook
package gitlab
import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/url"
	"os"
	"time"
)
type ProjectsService struct {
	client *Client
}
type Project struct {
	ID                                        int               `json:"id"`
	Description                               string            `json:"description"`
	DefaultBranch                             string            `json:"default_branch"`
	Public                                    bool              `json:"public"`
	Visibility                                VisibilityValue   `json:"visibility"`
	SSHURLToRepo                              string            `json:"ssh_url_to_repo"`
	HTTPURLToRepo                             string            `json:"http_url_to_repo"`
	WebURL                                    string            `json:"web_url"`
	TagList                                   []string          `json:"tag_list"`
	Owner                                     *User             `json:"owner"`
	Name                                      string            `json:"name"`
	NameWithNamespace                         string            `json:"name_with_namespace"`
	Path                                      string            `json:"path"`
	PathWithNamespace                         string            `json:"path_with_namespace"`
	IssuesEnabled                             bool              `json:"issues_enabled"`
	OpenIssuesCount                           int               `json:"open_issues_count"`
	MergeRequestsEnabled                      bool              `json:"merge_requests_enabled"`
	ApprovalsBeforeMerge                      int               `json:"approvals_before_merge"`
	JobsEnabled                               bool              `json:"jobs_enabled"`
	WikiEnabled                               bool              `json:"wiki_enabled"`
	SnippetsEnabled                           bool              `json:"snippets_enabled"`
	ContainerRegistryEnabled                  bool              `json:"container_registry_enabled"`
	CreatedAt                                 *time.Time        `json:"created_at,omitempty"`
	LastActivityAt                            *time.Time        `json:"last_activity_at,omitempty"`
	CreatorID                                 int               `json:"creator_id"`
	Namespace                                 *ProjectNamespace `json:"namespace"`
	Permissions                               *Permissions      `json:"permissions"`
	Archived                                  bool              `json:"archived"`
	AvatarURL                                 string            `json:"avatar_url"`
	SharedRunnersEnabled                      bool              `json:"shared_runners_enabled"`
	ForksCount                                int               `json:"forks_count"`
	StarCount                                 int               `json:"star_count"`
	RunnersToken                              string            `json:"runners_token"`
	PublicJobs                                bool              `json:"public_jobs"`
	OnlyAllowMergeIfPipelineSucceeds          bool              `json:"only_allow_merge_if_pipeline_succeeds"`
	OnlyAllowMergeIfAllDiscussionsAreResolved bool              `json:"only_allow_merge_if_all_discussions_are_resolved"`
	LFSEnabled                                bool              `json:"lfs_enabled"`
	RequestAccessEnabled                      bool              `json:"request_access_enabled"`
	ForkedFromProject                         *ForkParent       `json:"forked_from_project"`
	SharedWithGroups                          []struct {
		GroupID          int    `json:"group_id"`
		GroupName        string `json:"group_name"`
		GroupAccessLevel int    `json:"group_access_level"`
	} `json:"shared_with_groups"`
	Statistics *ProjectStatistics `json:"statistics"`
}
type Repository struct {
	Name              string          `json:"name"`
	Description       string          `json:"description"`
	WebURL            string          `json:"web_url"`
	AvatarURL         string          `json:"avatar_url"`
	GitSSHURL         string          `json:"git_ssh_url"`
	GitHTTPURL        string          `json:"git_http_url"`
	Namespace         string          `json:"namespace"`
	Visibility        VisibilityValue `json:"visibility"`
	PathWithNamespace string          `json:"path_with_namespace"`
	DefaultBranch     string          `json:"default_branch"`
	Homepage          string          `json:"homepage"`
	URL               string          `json:"url"`
	SSHURL            string          `json:"ssh_url"`
	HTTPURL           string          `json:"http_url"`
}
type ProjectNamespace struct {
	CreatedAt   *time.Time `json:"created_at"`
	Description string     `json:"description"`
	ID          int        `json:"id"`
	Name        string     `json:"name"`
	OwnerID     int        `json:"owner_id"`
	Path        string     `json:"path"`
	UpdatedAt   *time.Time `json:"updated_at"`
}
type StorageStatistics struct {
	StorageSize      int64 `json:"storage_size"`
	RepositorySize   int64 `json:"repository_size"`
	LfsObjectsSize   int64 `json:"lfs_objects_size"`
	JobArtifactsSize int64 `json:"job_artifacts_size"`
}
type ProjectStatistics struct {
	StorageStatistics
	CommitCount int `json:"commit_count"`
}
type Permissions struct {
	ProjectAccess *ProjectAccess `json:"project_access"`
	GroupAccess   *GroupAccess   `json:"group_access"`
}
type ProjectAccess struct {
	AccessLevel       AccessLevelValue       `json:"access_level"`
	NotificationLevel NotificationLevelValue `json:"notification_level"`
}
type GroupAccess struct {
	AccessLevel       AccessLevelValue       `json:"access_level"`
	NotificationLevel NotificationLevelValue `json:"notification_level"`
}
type ForkParent struct {
	HTTPURLToRepo     string `json:"http_url_to_repo"`
	ID                int    `json:"id"`
	Name              string `json:"name"`
	NameWithNamespace string `json:"name_with_namespace"`
	Path              string `json:"path"`
	PathWithNamespace string `json:"path_with_namespace"`
	WebURL            string `json:"web_url"`
}
func (s Project) String() string {
	return Stringify(s)
}
type ListProjectsOptions struct {
	ListOptions
	Archived   *bool            `url:"archived,omitempty" json:"archived,omitempty"`
	OrderBy    *string          `url:"order_by,omitempty" json:"order_by,omitempty"`
	Sort       *string          `url:"sort,omitempty" json:"sort,omitempty"`
	Search     *string          `url:"search,omitempty" json:"search,omitempty"`
	Simple     *bool            `url:"simple,omitempty" json:"simple,omitempty"`
	Owned      *bool            `url:"owned,omitempty" json:"owned,omitempty"`
	Membership *bool            `url:"membership,omitempty" json:"membership,omitempty"`
	Starred    *bool            `url:"starred,omitempty" json:"starred,omitempty"`
	Statistics *bool            `url:"statistics,omitempty" json:"statistics,omitempty"`
	Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
}
func (s *ProjectsService) ListProjects(opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) {
	req, err := s.client.NewRequest("GET", "projects", opt, options)
	if err != nil {
		return nil, nil, err
	}
	var p []*Project
	resp, err := s.client.Do(req, &p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
func (s *ProjectsService) ListUserProjects(uid interface{}, opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) {
	user, err := parseID(uid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("users/%s/projects", user)
	req, err := s.client.NewRequest("GET", u, opt, options)
	if err != nil {
		return nil, nil, err
	}
	var p []*Project
	resp, err := s.client.Do(req, &p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
func (s *ProjectsService) GetProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s", url.QueryEscape(project))
	req, err := s.client.NewRequest("GET", u, nil, options)
	if err != nil {
		return nil, nil, err
	}
	p := new(Project)
	resp, err := s.client.Do(req, p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
type ProjectEvent struct {
	Title          interface{} `json:"title"`
	ProjectID      int         `json:"project_id"`
	ActionName     string      `json:"action_name"`
	TargetID       interface{} `json:"target_id"`
	TargetType     interface{} `json:"target_type"`
	AuthorID       int         `json:"author_id"`
	AuthorUsername string      `json:"author_username"`
	Data           struct {
		Before            string      `json:"before"`
		After             string      `json:"after"`
		Ref               string      `json:"ref"`
		UserID            int         `json:"user_id"`
		UserName          string      `json:"user_name"`
		Repository        *Repository `json:"repository"`
		Commits           []*Commit   `json:"commits"`
		TotalCommitsCount int         `json:"total_commits_count"`
	} `json:"data"`
	TargetTitle interface{} `json:"target_title"`
}
func (s ProjectEvent) String() string {
	return Stringify(s)
}
type GetProjectEventsOptions struct {
	ListOptions
}
func (s *ProjectsService) GetProjectEvents(pid interface{}, opt *GetProjectEventsOptions, options ...OptionFunc) ([]*ProjectEvent, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s/events", url.QueryEscape(project))
	req, err := s.client.NewRequest("GET", u, opt, options)
	if err != nil {
		return nil, nil, err
	}
	var p []*ProjectEvent
	resp, err := s.client.Do(req, &p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
type CreateProjectOptions struct {
	Name                                      *string          `url:"name,omitempty" json:"name,omitempty"`
	Path                                      *string          `url:"path,omitempty" json:"path,omitempty"`
	DefaultBranch                             *string          `url:"default_branch,omitempty" json:"default_branch,omitempty"`
	NamespaceID                               *int             `url:"namespace_id,omitempty" json:"namespace_id,omitempty"`
	Description                               *string          `url:"description,omitempty" json:"description,omitempty"`
	IssuesEnabled                             *bool            `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"`
	MergeRequestsEnabled                      *bool            `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"`
	JobsEnabled                               *bool            `url:"jobs_enabled,omitempty" json:"jobs_enabled,omitempty"`
	WikiEnabled                               *bool            `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"`
	SnippetsEnabled                           *bool            `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"`
	ContainerRegistryEnabled                  *bool            `url:"container_registry_enabled,omitempty" json:"container_registry_enabled,omitempty"`
	SharedRunnersEnabled                      *bool            `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"`
	Visibility                                *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
	ImportURL                                 *string          `url:"import_url,omitempty" json:"import_url,omitempty"`
	PublicJobs                                *bool            `url:"public_jobs,omitempty" json:"public_jobs,omitempty"`
	OnlyAllowMergeIfPipelineSucceeds          *bool            `url:"only_allow_merge_if_pipeline_succeeds,omitempty" json:"only_allow_merge_if_pipeline_succeeds,omitempty"`
	OnlyAllowMergeIfAllDiscussionsAreResolved *bool            `url:"only_allow_merge_if_all_discussions_are_resolved,omitempty" json:"only_allow_merge_if_all_discussions_are_resolved,omitempty"`
	LFSEnabled                                *bool            `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"`
	RequestAccessEnabled                      *bool            `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"`
}
func (s *ProjectsService) CreateProject(opt *CreateProjectOptions, options ...OptionFunc) (*Project, *Response, error) {
	req, err := s.client.NewRequest("POST", "projects", opt, options)
	if err != nil {
		return nil, nil, err
	}
	p := new(Project)
	resp, err := s.client.Do(req, p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
type CreateProjectForUserOptions CreateProjectOptions
func (s *ProjectsService) CreateProjectForUser(user int, opt *CreateProjectForUserOptions, options ...OptionFunc) (*Project, *Response, error) {
	u := fmt.Sprintf("projects/user/%d", user)
	req, err := s.client.NewRequest("POST", u, opt, options)
	if err != nil {
		return nil, nil, err
	}
	p := new(Project)
	resp, err := s.client.Do(req, p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
type EditProjectOptions CreateProjectOptions
func (s *ProjectsService) EditProject(pid interface{}, opt *EditProjectOptions, options ...OptionFunc) (*Project, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s", url.QueryEscape(project))
	req, err := s.client.NewRequest("PUT", u, opt, options)
	if err != nil {
		return nil, nil, err
	}
	p := new(Project)
	resp, err := s.client.Do(req, p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
func (s *ProjectsService) ForkProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s/fork", url.QueryEscape(project))
	req, err := s.client.NewRequest("POST", u, nil, options)
	if err != nil {
		return nil, nil, err
	}
	p := new(Project)
	resp, err := s.client.Do(req, p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
func (s *ProjectsService) StarProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s/star", url.QueryEscape(project))
	req, err := s.client.NewRequest("POST", u, nil, options)
	if err != nil {
		return nil, nil, err
	}
	p := new(Project)
	resp, err := s.client.Do(req, p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
func (s *ProjectsService) UnstarProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s/unstar", url.QueryEscape(project))
	req, err := s.client.NewRequest("POST", u, nil, options)
	if err != nil {
		return nil, nil, err
	}
	p := new(Project)
	resp, err := s.client.Do(req, p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
func (s *ProjectsService) ArchiveProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s/archive", url.QueryEscape(project))
	req, err := s.client.NewRequest("POST", u, nil, options)
	if err != nil {
		return nil, nil, err
	}
	p := new(Project)
	resp, err := s.client.Do(req, p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
func (s *ProjectsService) UnarchiveProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s/unarchive", url.QueryEscape(project))
	req, err := s.client.NewRequest("POST", u, nil, options)
	if err != nil {
		return nil, nil, err
	}
	p := new(Project)
	resp, err := s.client.Do(req, p)
	if err != nil {
		return nil, resp, err
	}
	return p, resp, err
}
func (s *ProjectsService) DeleteProject(pid interface{}, options ...OptionFunc) (*Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, err
	}
	u := fmt.Sprintf("projects/%s", url.QueryEscape(project))
	req, err := s.client.NewRequest("DELETE", u, nil, options)
	if err != nil {
		return nil, err
	}
	return s.client.Do(req, nil)
}
type ShareWithGroupOptions struct {
	GroupID     *int              `url:"group_id" json:"group_id"`
	GroupAccess *AccessLevelValue `url:"group_access" json:"group_access"`
	ExpiresAt   *string           `url:"expires_at" json:"expires_at"`
}
func (s *ProjectsService) ShareProjectWithGroup(pid interface{}, opt *ShareWithGroupOptions, options ...OptionFunc) (*Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, err
	}
	u := fmt.Sprintf("projects/%s/share", url.QueryEscape(project))
	req, err := s.client.NewRequest("POST", u, opt, options)
	if err != nil {
		return nil, err
	}
	return s.client.Do(req, nil)
}
type ProjectMember struct {
	ID          int              `json:"id"`
	Username    string           `json:"username"`
	Email       string           `json:"email"`
	Name        string           `json:"name"`
	State       string           `json:"state"`
	CreatedAt   *time.Time       `json:"created_at"`
	AccessLevel AccessLevelValue `json:"access_level"`
}
type ProjectHook struct {
	ID                    int        `json:"id"`
	URL                   string     `json:"url"`
	ProjectID             int        `json:"project_id"`
	PushEvents            bool       `json:"push_events"`
	IssuesEvents          bool       `json:"issues_events"`
	MergeRequestsEvents   bool       `json:"merge_requests_events"`
	TagPushEvents         bool       `json:"tag_push_events"`
	NoteEvents            bool       `json:"note_events"`
	JobEvents             bool       `json:"job_events"`
	PipelineEvents        bool       `json:"pipeline_events"`
	WikiPageEvents        bool       `json:"wiki_page_events"`
	EnableSSLVerification bool       `json:"enable_ssl_verification"`
	CreatedAt             *time.Time `json:"created_at"`
}
type ListProjectHooksOptions struct {
	ListOptions
}
func (s *ProjectsService) ListProjectHooks(pid interface{}, opt *ListProjectHooksOptions, options ...OptionFunc) ([]*ProjectHook, *Response, error) {
	project, err := parseID(pid)
	if err != nil {
		return nil, nil, err
	}
	u := fmt.Sprintf("projects/%s/hooks", url.QueryEscape(project))
	req, err := s.client.NewRequest("GET", u, opt, options)
	if err != nil {
		return nil, nil, err
	}
	var ph []*ProjectHook
	resp, err := s.client.Do(req, &ph)
	if err != nil {
		return nil, resp, err
	}
	return ph, resp, err
}