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 }