github.com/google/go-github/v74@v74.0.0/github/repos_hooks_deliveries.go (about)

     1  // Copyright 2021 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  	"encoding/json"
    11  	"fmt"
    12  	"strings"
    13  )
    14  
    15  // HookDelivery represents the data that is received from GitHub's Webhook Delivery API
    16  //
    17  // GitHub API docs:
    18  // - https://docs.github.com/rest/webhooks/repo-deliveries#list-deliveries-for-a-repository-webhook
    19  // - https://docs.github.com/rest/webhooks/repo-deliveries#get-a-delivery-for-a-repository-webhook
    20  type HookDelivery struct {
    21  	ID             *int64     `json:"id,omitempty"`
    22  	GUID           *string    `json:"guid,omitempty"`
    23  	DeliveredAt    *Timestamp `json:"delivered_at,omitempty"`
    24  	Redelivery     *bool      `json:"redelivery,omitempty"`
    25  	Duration       *float64   `json:"duration,omitempty"`
    26  	Status         *string    `json:"status,omitempty"`
    27  	StatusCode     *int       `json:"status_code,omitempty"`
    28  	Event          *string    `json:"event,omitempty"`
    29  	Action         *string    `json:"action,omitempty"`
    30  	InstallationID *int64     `json:"installation_id,omitempty"`
    31  	RepositoryID   *int64     `json:"repository_id,omitempty"`
    32  
    33  	// Request is populated by GetHookDelivery.
    34  	Request *HookRequest `json:"request,omitempty"`
    35  	// Response is populated by GetHookDelivery.
    36  	Response *HookResponse `json:"response,omitempty"`
    37  }
    38  
    39  func (d HookDelivery) String() string {
    40  	return Stringify(d)
    41  }
    42  
    43  // getHeader common function for GetHeader funcs of HookRequest & HookResponse.
    44  func getHeader(headers map[string]string, key string) string {
    45  	for k, v := range headers {
    46  		if strings.EqualFold(k, key) {
    47  			return v
    48  		}
    49  	}
    50  	return ""
    51  }
    52  
    53  // HookRequest is a part of HookDelivery that contains
    54  // the HTTP headers and the JSON payload of the webhook request.
    55  type HookRequest struct {
    56  	Headers    map[string]string `json:"headers,omitempty"`
    57  	RawPayload *json.RawMessage  `json:"payload,omitempty"`
    58  }
    59  
    60  // GetHeader gets the value associated with the given key (ignoring key case).
    61  func (r *HookRequest) GetHeader(key string) string {
    62  	return getHeader(r.Headers, key)
    63  }
    64  
    65  func (r HookRequest) String() string {
    66  	return Stringify(r)
    67  }
    68  
    69  // HookResponse is a part of HookDelivery that contains
    70  // the HTTP headers and the response body served by the webhook endpoint.
    71  type HookResponse struct {
    72  	Headers    map[string]string `json:"headers,omitempty"`
    73  	RawPayload *json.RawMessage  `json:"payload,omitempty"`
    74  }
    75  
    76  // GetHeader gets the value associated with the given key (ignoring key case).
    77  func (r *HookResponse) GetHeader(key string) string {
    78  	return getHeader(r.Headers, key)
    79  }
    80  
    81  func (r HookResponse) String() string {
    82  	return Stringify(r)
    83  }
    84  
    85  // ListHookDeliveries lists webhook deliveries for a webhook configured in a repository.
    86  //
    87  // GitHub API docs: https://docs.github.com/rest/repos/webhooks#list-deliveries-for-a-repository-webhook
    88  //
    89  //meta:operation GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries
    90  func (s *RepositoriesService) ListHookDeliveries(ctx context.Context, owner, repo string, id int64, opts *ListCursorOptions) ([]*HookDelivery, *Response, error) {
    91  	u := fmt.Sprintf("repos/%v/%v/hooks/%v/deliveries", owner, repo, id)
    92  	u, err := addOptions(u, opts)
    93  	if err != nil {
    94  		return nil, nil, err
    95  	}
    96  
    97  	req, err := s.client.NewRequest("GET", u, nil)
    98  	if err != nil {
    99  		return nil, nil, err
   100  	}
   101  
   102  	deliveries := []*HookDelivery{}
   103  	resp, err := s.client.Do(ctx, req, &deliveries)
   104  	if err != nil {
   105  		return nil, resp, err
   106  	}
   107  
   108  	return deliveries, resp, nil
   109  }
   110  
   111  // GetHookDelivery returns a delivery for a webhook configured in a repository.
   112  //
   113  // GitHub API docs: https://docs.github.com/rest/repos/webhooks#get-a-delivery-for-a-repository-webhook
   114  //
   115  //meta:operation GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}
   116  func (s *RepositoriesService) GetHookDelivery(ctx context.Context, owner, repo string, hookID, deliveryID int64) (*HookDelivery, *Response, error) {
   117  	u := fmt.Sprintf("repos/%v/%v/hooks/%v/deliveries/%v", owner, repo, hookID, deliveryID)
   118  	req, err := s.client.NewRequest("GET", u, nil)
   119  	if err != nil {
   120  		return nil, nil, err
   121  	}
   122  
   123  	h := new(HookDelivery)
   124  	resp, err := s.client.Do(ctx, req, h)
   125  	if err != nil {
   126  		return nil, resp, err
   127  	}
   128  
   129  	return h, resp, nil
   130  }
   131  
   132  // RedeliverHookDelivery redelivers a delivery for a webhook configured in a repository.
   133  //
   134  // GitHub API docs: https://docs.github.com/rest/repos/webhooks#redeliver-a-delivery-for-a-repository-webhook
   135  //
   136  //meta:operation POST /repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}/attempts
   137  func (s *RepositoriesService) RedeliverHookDelivery(ctx context.Context, owner, repo string, hookID, deliveryID int64) (*HookDelivery, *Response, error) {
   138  	u := fmt.Sprintf("repos/%v/%v/hooks/%v/deliveries/%v/attempts", owner, repo, hookID, deliveryID)
   139  	req, err := s.client.NewRequest("POST", u, nil)
   140  	if err != nil {
   141  		return nil, nil, err
   142  	}
   143  
   144  	h := new(HookDelivery)
   145  	resp, err := s.client.Do(ctx, req, h)
   146  	if err != nil {
   147  		return nil, resp, err
   148  	}
   149  
   150  	return h, resp, nil
   151  }
   152  
   153  // ParseRequestPayload parses the request payload. For recognized event types,
   154  // a value of the corresponding struct type will be returned.
   155  func (d *HookDelivery) ParseRequestPayload() (any, error) {
   156  	eType, ok := messageToTypeName[d.GetEvent()]
   157  	if !ok {
   158  		return nil, fmt.Errorf("unsupported event type %q", d.GetEvent())
   159  	}
   160  
   161  	e := &Event{Type: &eType, RawPayload: d.Request.RawPayload}
   162  	return e.ParsePayload()
   163  }