...

Source file src/github.com/google/go-github/v47/github/repos_hooks.go

Documentation: github.com/google/go-github/v47/github

     1  // Copyright 2013 The go-github AUTHORS. All rights reserved.
     2  //
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file.
     5  
     6  package github
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  	"net/http"
    12  	"net/url"
    13  	"strings"
    14  	"time"
    15  )
    16  
    17  // WebHookPayload represents the data that is received from GitHub when a push
    18  // event hook is triggered. The format of these payloads pre-date most of the
    19  // GitHub v3 API, so there are lots of minor incompatibilities with the types
    20  // defined in the rest of the API. Therefore, several types are duplicated
    21  // here to account for these differences.
    22  //
    23  // GitHub API docs: https://help.github.com/articles/post-receive-hooks
    24  //
    25  // Deprecated: Please use PushEvent instead.
    26  type WebHookPayload = PushEvent
    27  
    28  // WebHookCommit represents the commit variant we receive from GitHub in a
    29  // WebHookPayload.
    30  //
    31  // Deprecated: Please use HeadCommit instead.
    32  type WebHookCommit = HeadCommit
    33  
    34  // WebHookAuthor represents the author or committer of a commit, as specified
    35  // in a WebHookCommit. The commit author may not correspond to a GitHub User.
    36  //
    37  // Deprecated: Please use CommitAuthor instead.
    38  // NOTE Breaking API change: the `Username` field is now called `Login`.
    39  type WebHookAuthor = CommitAuthor
    40  
    41  // Hook represents a GitHub (web and service) hook for a repository.
    42  type Hook struct {
    43  	CreatedAt    *time.Time             `json:"created_at,omitempty"`
    44  	UpdatedAt    *time.Time             `json:"updated_at,omitempty"`
    45  	URL          *string                `json:"url,omitempty"`
    46  	ID           *int64                 `json:"id,omitempty"`
    47  	Type         *string                `json:"type,omitempty"`
    48  	Name         *string                `json:"name,omitempty"`
    49  	TestURL      *string                `json:"test_url,omitempty"`
    50  	PingURL      *string                `json:"ping_url,omitempty"`
    51  	LastResponse map[string]interface{} `json:"last_response,omitempty"`
    52  
    53  	// Only the following fields are used when creating a hook.
    54  	// Config is required.
    55  	Config map[string]interface{} `json:"config,omitempty"`
    56  	Events []string               `json:"events,omitempty"`
    57  	Active *bool                  `json:"active,omitempty"`
    58  }
    59  
    60  func (h Hook) String() string {
    61  	return Stringify(h)
    62  }
    63  
    64  // createHookRequest is a subset of Hook and is used internally
    65  // by CreateHook to pass only the known fields for the endpoint.
    66  //
    67  // See https://github.com/google/go-github/issues/1015 for more
    68  // information.
    69  type createHookRequest struct {
    70  	// Config is required.
    71  	Name   string                 `json:"name"`
    72  	Config map[string]interface{} `json:"config,omitempty"`
    73  	Events []string               `json:"events,omitempty"`
    74  	Active *bool                  `json:"active,omitempty"`
    75  }
    76  
    77  // CreateHook creates a Hook for the specified repository.
    78  // Config is a required field.
    79  //
    80  // Note that only a subset of the hook fields are used and hook must
    81  // not be nil.
    82  //
    83  // GitHub API docs: https://docs.github.com/en/rest/webhooks/repos#create-a-repository-webhook
    84  func (s *RepositoriesService) CreateHook(ctx context.Context, owner, repo string, hook *Hook) (*Hook, *Response, error) {
    85  	u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
    86  
    87  	hookReq := &createHookRequest{
    88  		Name:   "web",
    89  		Events: hook.Events,
    90  		Active: hook.Active,
    91  		Config: hook.Config,
    92  	}
    93  
    94  	req, err := s.client.NewRequest("POST", u, hookReq)
    95  	if err != nil {
    96  		return nil, nil, err
    97  	}
    98  
    99  	h := new(Hook)
   100  	resp, err := s.client.Do(ctx, req, h)
   101  	if err != nil {
   102  		return nil, resp, err
   103  	}
   104  
   105  	return h, resp, nil
   106  }
   107  
   108  // ListHooks lists all Hooks for the specified repository.
   109  //
   110  // GitHub API docs: https://docs.github.com/en/rest/webhooks/repos#list-repository-webhooks
   111  func (s *RepositoriesService) ListHooks(ctx context.Context, owner, repo string, opts *ListOptions) ([]*Hook, *Response, error) {
   112  	u := fmt.Sprintf("repos/%v/%v/hooks", owner, repo)
   113  	u, err := addOptions(u, opts)
   114  	if err != nil {
   115  		return nil, nil, err
   116  	}
   117  
   118  	req, err := s.client.NewRequest("GET", u, nil)
   119  	if err != nil {
   120  		return nil, nil, err
   121  	}
   122  
   123  	var hooks []*Hook
   124  	resp, err := s.client.Do(ctx, req, &hooks)
   125  	if err != nil {
   126  		return nil, resp, err
   127  	}
   128  
   129  	return hooks, resp, nil
   130  }
   131  
   132  // GetHook returns a single specified Hook.
   133  //
   134  // GitHub API docs: https://docs.github.com/en/rest/webhooks/repos#get-a-repository-webhook
   135  func (s *RepositoriesService) GetHook(ctx context.Context, owner, repo string, id int64) (*Hook, *Response, error) {
   136  	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
   137  	req, err := s.client.NewRequest("GET", u, nil)
   138  	if err != nil {
   139  		return nil, nil, err
   140  	}
   141  	h := new(Hook)
   142  	resp, err := s.client.Do(ctx, req, h)
   143  	if err != nil {
   144  		return nil, resp, err
   145  	}
   146  
   147  	return h, resp, nil
   148  }
   149  
   150  // EditHook updates a specified Hook.
   151  //
   152  // GitHub API docs: https://docs.github.com/en/rest/webhooks/repos#update-a-repository-webhook
   153  func (s *RepositoriesService) EditHook(ctx context.Context, owner, repo string, id int64, hook *Hook) (*Hook, *Response, error) {
   154  	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
   155  	req, err := s.client.NewRequest("PATCH", u, hook)
   156  	if err != nil {
   157  		return nil, nil, err
   158  	}
   159  	h := new(Hook)
   160  	resp, err := s.client.Do(ctx, req, h)
   161  	if err != nil {
   162  		return nil, resp, err
   163  	}
   164  
   165  	return h, resp, nil
   166  }
   167  
   168  // DeleteHook deletes a specified Hook.
   169  //
   170  // GitHub API docs: https://docs.github.com/en/rest/webhooks/repos#delete-a-repository-webhook
   171  func (s *RepositoriesService) DeleteHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
   172  	u := fmt.Sprintf("repos/%v/%v/hooks/%d", owner, repo, id)
   173  	req, err := s.client.NewRequest("DELETE", u, nil)
   174  	if err != nil {
   175  		return nil, err
   176  	}
   177  	return s.client.Do(ctx, req, nil)
   178  }
   179  
   180  // PingHook triggers a 'ping' event to be sent to the Hook.
   181  //
   182  // GitHub API docs: https://docs.github.com/en/rest/webhooks/repos#ping-a-repository-webhook
   183  func (s *RepositoriesService) PingHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
   184  	u := fmt.Sprintf("repos/%v/%v/hooks/%d/pings", owner, repo, id)
   185  	req, err := s.client.NewRequest("POST", u, nil)
   186  	if err != nil {
   187  		return nil, err
   188  	}
   189  	return s.client.Do(ctx, req, nil)
   190  }
   191  
   192  // TestHook triggers a test Hook by github.
   193  //
   194  // GitHub API docs: https://docs.github.com/en/rest/webhooks/repos#test-the-push-repository-webhook
   195  func (s *RepositoriesService) TestHook(ctx context.Context, owner, repo string, id int64) (*Response, error) {
   196  	u := fmt.Sprintf("repos/%v/%v/hooks/%d/tests", owner, repo, id)
   197  	req, err := s.client.NewRequest("POST", u, nil)
   198  	if err != nil {
   199  		return nil, err
   200  	}
   201  	return s.client.Do(ctx, req, nil)
   202  }
   203  
   204  // Subscribe lets servers register to receive updates when a topic is updated.
   205  //
   206  // GitHub API docs: https://docs.github.com/en/rest/webhooks#pubsubhubbub
   207  func (s *RepositoriesService) Subscribe(ctx context.Context, owner, repo, event, callback string, secret []byte) (*Response, error) {
   208  	req, err := s.createWebSubRequest("subscribe", owner, repo, event, callback, secret)
   209  	if err != nil {
   210  		return nil, err
   211  	}
   212  
   213  	return s.client.Do(ctx, req, nil)
   214  }
   215  
   216  // Unsubscribe lets servers unregister to no longer receive updates when a topic is updated.
   217  //
   218  // GitHub API docs: https://docs.github.com/en/rest/webhooks#pubsubhubbub
   219  func (s *RepositoriesService) Unsubscribe(ctx context.Context, owner, repo, event, callback string, secret []byte) (*Response, error) {
   220  	req, err := s.createWebSubRequest("unsubscribe", owner, repo, event, callback, secret)
   221  	if err != nil {
   222  		return nil, err
   223  	}
   224  
   225  	return s.client.Do(ctx, req, nil)
   226  }
   227  
   228  // createWebSubRequest returns a subscribe/unsubscribe request that implements
   229  // the WebSub (formerly PubSubHubbub) protocol.
   230  //
   231  // See: https://www.w3.org/TR/websub/#subscriber-sends-subscription-request
   232  func (s *RepositoriesService) createWebSubRequest(hubMode, owner, repo, event, callback string, secret []byte) (*http.Request, error) {
   233  	topic := fmt.Sprintf(
   234  		"https://github.com/%s/%s/events/%s",
   235  		owner,
   236  		repo,
   237  		event,
   238  	)
   239  	form := url.Values{}
   240  	form.Add("hub.mode", hubMode)
   241  	form.Add("hub.topic", topic)
   242  	form.Add("hub.callback", callback)
   243  	if secret != nil {
   244  		form.Add("hub.secret", string(secret))
   245  	}
   246  	body := strings.NewReader(form.Encode())
   247  
   248  	req, err := s.client.NewFormRequest("hub", body)
   249  	if err != nil {
   250  		return nil, err
   251  	}
   252  
   253  	return req, nil
   254  }
   255  

View as plain text