Repository: google/go-github
Pull request #2678 (2023-02-25 16:33:11)

Add DicussionCommentEvent Webhook
This commit has changes to enable support to receive DiscussionComment Webhook Event, to fix [google#2497](url) Changes include:
* Addition of event type for this type of event DiscussionCommentEvent
* Changes for identification and mapping of DiscussionCommentEvent
* Addition / Modification of relevant tests
* Addition of files created by go generate

gmlewis: Please run your files through "gofmt" as described in CONTRIBUTING.md.
codecov[bot]: # [Codecov](https://codecov.io/gh/google/go-github/pull/2678?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) Report
> Merging [#2678](https://codecov.io/gh/google/go-github/pull/2678?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (58baa10) into [master](https://codecov.io/gh/google/go-github/commit/099fae4bf5d6700d159c0b4d12f23ad1194ad713?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) (099fae4) will **increase** coverage by `0.00%`.
> The diff coverage is `100.00%`.

```diff
@@           Coverage Diff           @@
##           master    #2678   +/-   ##
=======================================
  Coverage   98.05%   98.05%           
=======================================
  Files         131      131           
  Lines       11442    11444    +2     
=======================================
+ Hits        11219    11221    +2     
  Misses        152      152           
  Partials       71       71           
```


| [Impacted Files](https://codecov.io/gh/google/go-github/pull/2678?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google) | Coverage Δ | |
|---|---|---|
| [github/event\_types.go](https://codecov.io/gh/google/go-github/pull/2678?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google#diff-Z2l0aHViL2V2ZW50X3R5cGVzLmdv) | `100.00% <ø> (ø)` | |
| [github/messages.go](https://codecov.io/gh/google/go-github/pull/2678?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google#diff-Z2l0aHViL21lc3NhZ2VzLmdv) | `100.00% <ø> (ø)` | |
| [github/event.go](https://codecov.io/gh/google/go-github/pull/2678?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google#diff-Z2l0aHViL2V2ZW50Lmdv) | `100.00% <100.00%> (ø)` | |

Help us with your feedback. Take ten seconds to tell us [how you rate us](https://about.codecov.io/nps?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google). Have a feature suggestion? [Share it here.](https://app.codecov.io/gh/feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=google)

apurwaj2: > Thank you, @apurwaj2 ! LGTM.
> 
> Awaiting second LGTM+Approval from any other contributor to this repo before merging.
> 
> Note that I'm OOO until around March 6, so I may not be able to merge this before then if we don't get an approval shortly.

Sure. Thanks, for approving. 

Patch:
diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml
index cf4edcb6..d57bb7f4 100644
--- a/.github/workflows/linter.yml
+++ b/.github/workflows/linter.yml
@@ -26,8 +26,8 @@ jobs:
     - uses: actions/checkout@v3
 
     - name: golangci-lint ${{ matrix.working-directory }}
-      uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5 #v3.4.0
+      uses: golangci/golangci-lint-action@v3
       with:
-        version: v1.50.1
+        version: latest
         working-directory: ${{ matrix.working-directory}}
         args: --verbose
diff --git a/example/go.mod b/example/go.mod
index 6138d931..a2f2ec9c 100644
--- a/example/go.mod
+++ b/example/go.mod
@@ -6,7 +6,7 @@ require (
 	github.com/bradleyfalzon/ghinstallation/v2 v2.0.4
 	github.com/gofri/go-github-ratelimit v1.0.1
 	github.com/google/go-github/v50 v50.0.0
-	golang.org/x/crypto v0.0.0-20210817164053-32db794688a5
+	golang.org/x/crypto v0.1.0
 	golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
 	google.golang.org/appengine v1.6.7
 )
@@ -16,9 +16,9 @@ require (
 	github.com/golang/protobuf v1.3.2 // indirect
 	github.com/google/go-github/v41 v41.0.0 // indirect
 	github.com/google/go-querystring v1.1.0 // indirect
-	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
-	golang.org/x/sys v0.1.0 // indirect
-	golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
+	golang.org/x/net v0.7.0 // indirect
+	golang.org/x/sys v0.5.0 // indirect
+	golang.org/x/term v0.5.0 // indirect
 )
 
 // Use version at HEAD, not the latest published.
diff --git a/example/go.sum b/example/go.sum
index 9b12b78d..71e7a992 100644
--- a/example/go.sum
+++ b/example/go.sum
@@ -15,25 +15,47 @@ github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27u
 github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg=
 github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
 github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU=
+golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
+golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
diff --git a/github/event.go b/github/event.go
index 44c5f46f..1aabf13b 100644
--- a/github/event.go
+++ b/github/event.go
@@ -53,6 +53,8 @@ func (e *Event) ParsePayload() (payload interface{}, err error) {
 		payload = &DeploymentStatusEvent{}
 	case "DiscussionEvent":
 		payload = &DiscussionEvent{}
+	case "DiscussionCommentEvent":
+		payload = &DiscussionCommentEvent{}
 	case "ForkEvent":
 		payload = &ForkEvent{}
 	case "GitHubAppAuthorizationEvent":
diff --git a/github/event_types.go b/github/event_types.go
index 50c7b567..598d98d4 100644
--- a/github/event_types.go
+++ b/github/event_types.go
@@ -189,6 +189,39 @@ type DeploymentStatusEvent struct {
 	Installation *Installation `json:"installation,omitempty"`
 }
 
+// DiscussionCommentEvent represents a webhook event for a comment on discussion.
+// The Webhook event name is "discussion_comment".
+//
+// GitHub API docs: https://docs.github.com/webhooks-and-events/webhooks/webhook-events-and-payloads#discussion_comment
+type DiscussionCommentEvent struct {
+	// Action is the action that was performed on the comment.
+	// Possible values are: "created", "edited", "deleted". ** check what all can be added
+	Action       *string            `json:"action,omitempty"`
+	Discussion   *Discussion        `json:"discussion,omitempty"`
+	Comment      *CommentDiscussion `json:"comment,omitempty"`
+	Repo         *Repository        `json:"repository,omitempty"`
+	Org          *Organization      `json:"organization,omitempty"`
+	Sender       *User              `json:"sender,omitempty"`
+	Installation *Installation      `json:"installation,omitempty"`
+}
+
+// CommentDiscussion represents a comment in a GitHub DiscussionCommentEvent.
+type CommentDiscussion struct {
+	AuthorAssociation *string    `json:"author_association,omitempty"`
+	Body              *string    `json:"body,omitempty"`
+	ChildCommentCount *int       `json:"child_comment_count,omitempty"`
+	CreatedAt         *Timestamp `json:"created_at,omitempty"`
+	DiscussionID      *int64     `json:"discussion_id,omitempty"`
+	HTMLURL           *string    `json:"html_url,omitempty"`
+	ID                *int64     `json:"id,omitempty"`
+	NodeID            *string    `json:"node_id,omitempty"`
+	ParentID          *int64     `json:"parent_id,omitempty"`
+	Reactions         *Reactions `json:"reactions,omitempty"`
+	RepositoryURL     *string    `json:"repository_url,omitempty"`
+	UpdatedAt         *Timestamp `json:"updated_at,omitempty"`
+	User              *User      `json:"user,omitempty"`
+}
+
 // DiscussionEvent represents a webhook event for a discussion.
 // The Webhook event name is "discussion".
 //
diff --git a/github/github-accessors.go b/github/github-accessors.go
index a7d800e2..eba1036f 100644
--- a/github/github-accessors.go
+++ b/github/github-accessors.go
@@ -2854,6 +2854,110 @@ func (c *Comment) GetCreatedAt() Timestamp {
 	return *c.CreatedAt
 }
 
+// GetAuthorAssociation returns the AuthorAssociation field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetAuthorAssociation() string {
+	if c == nil || c.AuthorAssociation == nil {
+		return ""
+	}
+	return *c.AuthorAssociation
+}
+
+// GetBody returns the Body field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetBody() string {
+	if c == nil || c.Body == nil {
+		return ""
+	}
+	return *c.Body
+}
+
+// GetChildCommentCount returns the ChildCommentCount field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetChildCommentCount() int {
+	if c == nil || c.ChildCommentCount == nil {
+		return 0
+	}
+	return *c.ChildCommentCount
+}
+
+// GetCreatedAt returns the CreatedAt field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetCreatedAt() Timestamp {
+	if c == nil || c.CreatedAt == nil {
+		return Timestamp{}
+	}
+	return *c.CreatedAt
+}
+
+// GetDiscussionID returns the DiscussionID field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetDiscussionID() int64 {
+	if c == nil || c.DiscussionID == nil {
+		return 0
+	}
+	return *c.DiscussionID
+}
+
+// GetHTMLURL returns the HTMLURL field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetHTMLURL() string {
+	if c == nil || c.HTMLURL == nil {
+		return ""
+	}
+	return *c.HTMLURL
+}
+
+// GetID returns the ID field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetID() int64 {
+	if c == nil || c.ID == nil {
+		return 0
+	}
+	return *c.ID
+}
+
+// GetNodeID returns the NodeID field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetNodeID() string {
+	if c == nil || c.NodeID == nil {
+		return ""
+	}
+	return *c.NodeID
+}
+
+// GetParentID returns the ParentID field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetParentID() int64 {
+	if c == nil || c.ParentID == nil {
+		return 0
+	}
+	return *c.ParentID
+}
+
+// GetReactions returns the Reactions field.
+func (c *CommentDiscussion) GetReactions() *Reactions {
+	if c == nil {
+		return nil
+	}
+	return c.Reactions
+}
+
+// GetRepositoryURL returns the RepositoryURL field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetRepositoryURL() string {
+	if c == nil || c.RepositoryURL == nil {
+		return ""
+	}
+	return *c.RepositoryURL
+}
+
+// GetUpdatedAt returns the UpdatedAt field if it's non-nil, zero value otherwise.
+func (c *CommentDiscussion) GetUpdatedAt() Timestamp {
+	if c == nil || c.UpdatedAt == nil {
+		return Timestamp{}
+	}
+	return *c.UpdatedAt
+}
+
+// GetUser returns the User field.
+func (c *CommentDiscussion) GetUser() *User {
+	if c == nil {
+		return nil
+	}
+	return c.User
+}
+
 // GetTotalCommitComments returns the TotalCommitComments field if it's non-nil, zero value otherwise.
 func (c *CommentStats) GetTotalCommitComments() int {
 	if c == nil || c.TotalCommitComments == nil {
@@ -5046,6 +5150,62 @@ func (d *DiscussionComment) GetURL() string {
 	return *d.URL
 }
 
+// GetAction returns the Action field if it's non-nil, zero value otherwise.
+func (d *DiscussionCommentEvent) GetAction() string {
+	if d == nil || d.Action == nil {
+		return ""
+	}
+	return *d.Action
+}
+
+// GetComment returns the Comment field.
+func (d *DiscussionCommentEvent) GetComment() *CommentDiscussion {
+	if d == nil {
+		return nil
+	}
+	return d.Comment
+}
+
+// GetDiscussion returns the Discussion field.
+func (d *DiscussionCommentEvent) GetDiscussion() *Discussion {
+	if d == nil {
+		return nil
+	}
+	return d.Discussion
+}
+
+// GetInstallation returns the Installation field.
+func (d *DiscussionCommentEvent) GetInstallation() *Installation {
+	if d == nil {
+		return nil
+	}
+	return d.Installation
+}
+
+// GetOrg returns the Org field.
+func (d *DiscussionCommentEvent) GetOrg() *Organization {
+	if d == nil {
+		return nil
+	}
+	return d.Org
+}
+
+// GetRepo returns the Repo field.
+func (d *DiscussionCommentEvent) GetRepo() *Repository {
+	if d == nil {
+		return nil
+	}
+	return d.Repo
+}
+
+// GetSender returns the Sender field.
+func (d *DiscussionCommentEvent) GetSender() *User {
+	if d == nil {
+		return nil
+	}
+	return d.Sender
+}
+
 // GetAction returns the Action field if it's non-nil, zero value otherwise.
 func (d *DiscussionEvent) GetAction() string {
 	if d == nil || d.Action == nil {
diff --git a/github/messages.go b/github/messages.go
index ceac6d9b..0943b9e9 100644
--- a/github/messages.go
+++ b/github/messages.go
@@ -56,6 +56,7 @@ var (
 		"deployment":                     "DeploymentEvent",
 		"deployment_status":              "DeploymentStatusEvent",
 		"discussion":                     "DiscussionEvent",
+		"discussion_comment":             "DiscussionCommentEvent",
 		"fork":                           "ForkEvent",
 		"github_app_authorization":       "GitHubAppAuthorizationEvent",
 		"gollum":                         "GollumEvent",
diff --git a/github/teams.go b/github/teams.go
index 963a69b3..0ee7c200 100644
--- a/github/teams.go
+++ b/github/teams.go
@@ -913,7 +913,7 @@ type ListExternalGroupsOptions struct {
 	ListOptions
 }
 
-// ListExternalGroups lists external groups connected to a team on GitHub.
+// ListExternalGroups lists external groups in an organization on GitHub.
 //
 // GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/teams/external-groups#list-external-groups-in-an-organization
 func (s *TeamsService) ListExternalGroups(ctx context.Context, org string, opts *ListExternalGroupsOptions) (*ExternalGroupList, *Response, error) {
@@ -937,6 +937,26 @@ func (s *TeamsService) ListExternalGroups(ctx context.Context, org string, opts
 	return externalGroups, resp, nil
 }
 
+// ListExternalGroupsForTeamBySlug lists external groups connected to a team on GitHub.
+//
+// GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/teams/external-groups#list-a-connection-between-an-external-group-and-a-team
+func (s *TeamsService) ListExternalGroupsForTeamBySlug(ctx context.Context, org, slug string) (*ExternalGroupList, *Response, error) {
+	u := fmt.Sprintf("orgs/%v/teams/%v/external-groups", org, slug)
+
+	req, err := s.client.NewRequest("GET", u, nil)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	externalGroups := new(ExternalGroupList)
+	resp, err := s.client.Do(ctx, req, externalGroups)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return externalGroups, resp, nil
+}
+
 // UpdateConnectedExternalGroup updates the connection between an external group and a team.
 //
 // GitHub API docs: https://docs.github.com/en/enterprise-cloud@latest/rest/teams/external-groups#update-the-connection-between-an-external-group-and-a-team
diff --git a/go.mod b/go.mod
index ceb9aff0..a62e4f55 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,7 @@ require (
 
 require (
 	github.com/golang/protobuf v1.3.2 // indirect
-	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 // indirect
+	golang.org/x/net v0.7.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 )
 
diff --git a/go.sum b/go.sum
index fc6f776a..e7977858 100644
--- a/go.sum
+++ b/go.sum
@@ -6,22 +6,41 @@ github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
 github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
+github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg=
+golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
+golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
-golang.org/x/net v0.0.0-20210226172049-e18ecbb05110 h1:qWPm9rbaAMKs8Bq/9LRpbMqxWRVUAQwMI9fVrssnTfw=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
+golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
+golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
+golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
+golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
diff --git a/scrape/go.mod b/scrape/go.mod
index 3aa019c5..653f279f 100644
--- a/scrape/go.mod
+++ b/scrape/go.mod
@@ -5,7 +5,7 @@ go 1.13
 require (
 	github.com/PuerkitoBio/goquery v1.8.1
 	github.com/google/go-cmp v0.5.9
-	github.com/google/go-github/v50 v50.0.0
-	github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119
+	github.com/google/go-github/v50 v50.1.0
+	github.com/xlzd/gotp v0.1.0
 	golang.org/x/net v0.7.0
 )
diff --git a/scrape/go.sum b/scrape/go.sum
index a67b4395..496eb3f6 100644
--- a/scrape/go.sum
+++ b/scrape/go.sum
@@ -8,12 +8,12 @@ github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
 github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
-github.com/google/go-github/v50 v50.0.0 h1:gdO1AeuSZZK4iYWwVbjni7zg8PIQhp7QfmPunr016Jk=
-github.com/google/go-github/v50 v50.0.0/go.mod h1:Ev4Tre8QoKiolvbpOSG3FIi4Mlon3S2Nt9W5JYqKiwA=
+github.com/google/go-github/v50 v50.1.0 h1:hMUpkZjklC5GJ+c3GquSqOP/T4BNsB7XohaPhtMOzRk=
+github.com/google/go-github/v50 v50.1.0/go.mod h1:Ev4Tre8QoKiolvbpOSG3FIi4Mlon3S2Nt9W5JYqKiwA=
 github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
 github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
-github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119 h1:YyPWX3jLOtYKulBR6AScGIs74lLrJcgeKRwcbAuQOG4=
-github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8=
+github.com/xlzd/gotp v0.1.0 h1:37blvlKCh38s+fkem+fFh7sMnceltoIEBYTVXyoa5Po=
+github.com/xlzd/gotp v0.1.0/go.mod h1:ndLJ3JKzi3xLmUProq4LLxCuECL93dG9WASNLpHz8qg=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=


Test patch:
diff --git a/github/event_types_test.go b/github/event_types_test.go
index fdc0809e..7c84146f 100644
--- a/github/event_types_test.go
+++ b/github/event_types_test.go
@@ -5740,6 +5740,420 @@ func TestDeploymentStatusEvent_Marshal(t *testing.T) {
 	testJSONMarshal(t, u, want)
 }
 
+func TestDiscussionCommentEvent_Marshal(t *testing.T) {
+	testJSONMarshal(t, &DiscussionCommentEvent{}, "{}")
+
+	u := &DiscussionCommentEvent{
+		Comment: &CommentDiscussion{
+			AuthorAssociation: String("aa"),
+			Body:              String("bo"),
+			ChildCommentCount: Int(1),
+			CreatedAt:         &Timestamp{referenceTime},
+			DiscussionID:      Int64(1),
+			HTMLURL:           String("hurl"),
+			ID:                Int64(1),
+			NodeID:            String("nid"),
+			ParentID:          Int64(1),
+			Reactions: &Reactions{
+				TotalCount: Int(1),
+				PlusOne:    Int(1),
+				MinusOne:   Int(1),
+				Laugh:      Int(1),
+				Confused:   Int(1),
+				Heart:      Int(1),
+				Hooray:     Int(1),
+				Rocket:     Int(1),
+				Eyes:       Int(1),
+				URL:        String("url"),
+			},
+			RepositoryURL: String("rurl"),
+			UpdatedAt:     &Timestamp{referenceTime},
+			User: &User{
+				Login:     String("l"),
+				ID:        Int64(1),
+				NodeID:    String("n"),
+				URL:       String("u"),
+				ReposURL:  String("r"),
+				EventsURL: String("e"),
+				AvatarURL: String("a"),
+			},
+		},
+		Discussion: &Discussion{
+			RepositoryURL: String("rurl"),
+			DiscussionCategory: &DiscussionCategory{
+				ID:           Int64(1),
+				NodeID:       String("nid"),
+				RepositoryID: Int64(1),
+				Emoji:        String("emoji"),
+				Name:         String("name"),
+				Description:  String("description"),
+				CreatedAt:    &Timestamp{referenceTime},
+				UpdatedAt:    &Timestamp{referenceTime},
+				Slug:         String("slug"),
+				IsAnswerable: Bool(false),
+			},
+			HTMLURL: String("hurl"),
+			ID:      Int64(1),
+			NodeID:  String("nurl"),
+			Number:  Int(1),
+			Title:   String("title"),
+			User: &User{
+				Login:     String("l"),
+				ID:        Int64(1),
+				NodeID:    String("n"),
+				URL:       String("u"),
+				ReposURL:  String("r"),
+				EventsURL: String("e"),
+				AvatarURL: String("a"),
+			},
+			State:             String("st"),
+			Locked:            Bool(false),
+			Comments:          Int(1),
+			CreatedAt:         &Timestamp{referenceTime},
+			UpdatedAt:         &Timestamp{referenceTime},
+			AuthorAssociation: String("aa"),
+			Body:              String("bo"),
+		},
+		Repo: &Repository{
+			ID:   Int64(1),
+			URL:  String("s"),
+			Name: String("n"),
+		},
+		Org: &Organization{
+			BillingEmail:                         String("be"),
+			Blog:                                 String("b"),
+			Company:                              String("c"),
+			Email:                                String("e"),
+			TwitterUsername:                      String("tu"),
+			Location:                             String("loc"),
+			Name:                                 String("n"),
+			Description:                          String("d"),
+			IsVerified:                           Bool(true),
+			HasOrganizationProjects:              Bool(true),
+			HasRepositoryProjects:                Bool(true),
+			DefaultRepoPermission:                String("drp"),
+			MembersCanCreateRepos:                Bool(true),
+			MembersCanCreateInternalRepos:        Bool(true),
+			MembersCanCreatePrivateRepos:         Bool(true),
+			MembersCanCreatePublicRepos:          Bool(false),
+			MembersAllowedRepositoryCreationType: String("marct"),
+			MembersCanCreatePages:                Bool(true),
+			MembersCanCreatePublicPages:          Bool(false),
+			MembersCanCreatePrivatePages:         Bool(true),
+		},
+		Sender: &User{
+			Login:     String("l"),
+			ID:        Int64(1),
+			NodeID:    String("n"),
+			URL:       String("u"),
+			ReposURL:  String("r"),
+			EventsURL: String("e"),
+			AvatarURL: String("a"),
+		},
+		Installation: &Installation{
+			ID:       Int64(1),
+			NodeID:   String("nid"),
+			AppID:    Int64(1),
+			AppSlug:  String("as"),
+			TargetID: Int64(1),
+			Account: &User{
+				Login:           String("l"),
+				ID:              Int64(1),
+				URL:             String("u"),
+				AvatarURL:       String("a"),
+				GravatarID:      String("g"),
+				Name:            String("n"),
+				Company:         String("c"),
+				Blog:            String("b"),
+				Location:        String("l"),
+				Email:           String("e"),
+				Hireable:        Bool(true),
+				Bio:             String("b"),
+				TwitterUsername: String("t"),
+				PublicRepos:     Int(1),
+				Followers:       Int(1),
+				Following:       Int(1),
+				CreatedAt:       &Timestamp{referenceTime},
+				SuspendedAt:     &Timestamp{referenceTime},
+			},
+			AccessTokensURL:     String("atu"),
+			RepositoriesURL:     String("ru"),
+			HTMLURL:             String("hu"),
+			TargetType:          String("tt"),
+			SingleFileName:      String("sfn"),
+			RepositorySelection: String("rs"),
+			Events:              []string{"e"},
+			SingleFilePaths:     []string{"s"},
+			Permissions: &InstallationPermissions{
+				Actions:                       String("a"),
+				Administration:                String("ad"),
+				Checks:                        String("c"),
+				Contents:                      String("co"),
+				ContentReferences:             String("cr"),
+				Deployments:                   String("d"),
+				Environments:                  String("e"),
+				Issues:                        String("i"),
+				Metadata:                      String("md"),
+				Members:                       String("m"),
+				OrganizationAdministration:    String("oa"),
+				OrganizationHooks:             String("oh"),
+				OrganizationPlan:              String("op"),
+				OrganizationPreReceiveHooks:   String("opr"),
+				OrganizationProjects:          String("op"),
+				OrganizationSecrets:           String("os"),
+				OrganizationSelfHostedRunners: String("osh"),
+				OrganizationUserBlocking:      String("oub"),
+				Packages:                      String("pkg"),
+				Pages:                         String("pg"),
+				PullRequests:                  String("pr"),
+				RepositoryHooks:               String("rh"),
+				RepositoryProjects:            String("rp"),
+				RepositoryPreReceiveHooks:     String("rprh"),
+				Secrets:                       String("s"),
+				SecretScanningAlerts:          String("ssa"),
+				SecurityEvents:                String("se"),
+				SingleFile:                    String("sf"),
+				Statuses:                      String("s"),
+				TeamDiscussions:               String("td"),
+				VulnerabilityAlerts:           String("va"),
+				Workflows:                     String("w"),
+			},
+			CreatedAt:              &Timestamp{referenceTime},
+			UpdatedAt:              &Timestamp{referenceTime},
+			HasMultipleSingleFiles: Bool(false),
+			SuspendedBy: &User{
+				Login:           String("l"),
+				ID:              Int64(1),
+				URL:             String("u"),
+				AvatarURL:       String("a"),
+				GravatarID:      String("g"),
+				Name:            String("n"),
+				Company:         String("c"),
+				Blog:            String("b"),
+				Location:        String("l"),
+				Email:           String("e"),
+				Hireable:        Bool(true),
+				Bio:             String("b"),
+				TwitterUsername: String("t"),
+				PublicRepos:     Int(1),
+				Followers:       Int(1),
+				Following:       Int(1),
+				CreatedAt:       &Timestamp{referenceTime},
+				SuspendedAt:     &Timestamp{referenceTime},
+			},
+			SuspendedAt: &Timestamp{referenceTime},
+		},
+	}
+
+	want := `{
+		"comment": {
+			"author_association": "aa",
+			"body": "bo",
+			"child_comment_count": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"discussion_id": 1,
+			"html_url": "hurl",
+			"id": 1,
+			"node_id": "nid",
+			"parent_id": 1,
+			"reactions": {
+				"total_count": 1,
+				"+1": 1,
+				"-1": 1,
+				"laugh": 1,
+				"confused": 1,
+				"heart": 1,
+				"hooray": 1,
+				"rocket": 1,
+				"eyes": 1,
+				"url": "url"
+			},
+			"repository_url": "rurl",
+			"updated_at": ` + referenceTimeStr + `,
+			"user": {
+				"login": "l",
+				"id": 1,
+				"node_id": "n",
+				"avatar_url": "a",
+				"url": "u",
+				"events_url": "e",
+				"repos_url": "r"
+			}
+		},
+		"discussion": {
+			"repository_url": "rurl",
+			"category": {
+				"id": 1,
+				"node_id": "nid",
+				"repository_id": 1,
+				"emoji": "emoji",
+				"name": "name",
+				"description": "description",
+				"created_at": ` + referenceTimeStr + `,
+				"updated_at": ` + referenceTimeStr + `,
+				"slug": "slug",
+				"is_answerable": false
+			},
+			"html_url": "hurl",
+			"id": 1,
+			"node_id": "nurl",
+			"number": 1,
+			"title": "title",
+			"user": {
+				"login": "l",
+				"id": 1,
+				"node_id": "n",
+				"avatar_url": "a",
+				"url": "u",
+				"events_url": "e",
+				"repos_url": "r"
+			},
+			"state": "st",
+			"locked": false,
+			"comments": 1,
+			"created_at": ` + referenceTimeStr + `,
+			"updated_at": ` + referenceTimeStr + `,
+			"author_association": "aa",
+			"body": "bo"
+		},
+		"repository": {
+			"id": 1,
+			"name": "n",
+			"url": "s"
+		},
+		"organization": {
+			"name": "n",
+			"company": "c",
+			"blog": "b",
+			"location": "loc",
+			"email": "e",
+			"twitter_username": "tu",
+			"description": "d",
+			"billing_email": "be",
+			"is_verified": true,
+			"has_organization_projects": true,
+			"has_repository_projects": true,
+			"default_repository_permission": "drp",
+			"members_can_create_repositories": true,
+			"members_can_create_public_repositories": false,
+			"members_can_create_private_repositories": true,
+			"members_can_create_internal_repositories": true,
+			"members_allowed_repository_creation_type": "marct",
+			"members_can_create_pages": true,
+			"members_can_create_public_pages": false,
+			"members_can_create_private_pages": true
+		},
+		"sender": {
+			"login": "l",
+			"id": 1,
+			"node_id": "n",
+			"avatar_url": "a",
+			"url": "u",
+			"events_url": "e",
+			"repos_url": "r"
+		},
+		"installation": {
+			"id": 1,
+			"node_id": "nid",
+			"app_id": 1,
+			"app_slug": "as",
+			"target_id": 1,
+			"account": {
+				"login": "l",
+				"id": 1,
+				"avatar_url": "a",
+				"gravatar_id": "g",
+				"name": "n",
+				"company": "c",
+				"blog": "b",
+				"location": "l",
+				"email": "e",
+				"hireable": true,
+				"bio": "b",
+				"twitter_username": "t",
+				"public_repos": 1,
+				"followers": 1,
+				"following": 1,
+				"created_at": ` + referenceTimeStr + `,
+				"suspended_at": ` + referenceTimeStr + `,
+				"url": "u"
+			},
+			"access_tokens_url": "atu",
+			"repositories_url": "ru",
+			"html_url": "hu",
+			"target_type": "tt",
+			"single_file_name": "sfn",
+			"repository_selection": "rs",
+			"events": [
+				"e"
+			],
+			"single_file_paths": [
+				"s"
+			],
+			"permissions": {
+				"actions": "a",
+				"administration": "ad",
+				"checks": "c",
+				"contents": "co",
+				"content_references": "cr",
+				"deployments": "d",
+				"environments": "e",
+				"issues": "i",
+				"metadata": "md",
+				"members": "m",
+				"organization_administration": "oa",
+				"organization_hooks": "oh",
+				"organization_plan": "op",
+				"organization_pre_receive_hooks": "opr",
+				"organization_projects": "op",
+				"organization_secrets": "os",
+				"organization_self_hosted_runners": "osh",
+				"organization_user_blocking": "oub",
+				"packages": "pkg",
+				"pages": "pg",
+				"pull_requests": "pr",
+				"repository_hooks": "rh",
+				"repository_projects": "rp",
+				"repository_pre_receive_hooks": "rprh",
+				"secrets": "s",
+				"secret_scanning_alerts": "ssa",
+				"security_events": "se",
+				"single_file": "sf",
+				"statuses": "s",
+				"team_discussions": "td",
+				"vulnerability_alerts": "va",
+				"workflows": "w"
+			},
+			"created_at": ` + referenceTimeStr + `,
+			"updated_at": ` + referenceTimeStr + `,
+			"has_multiple_single_files": false,
+			"suspended_by": {
+				"login": "l",
+				"id": 1,
+				"avatar_url": "a",
+				"gravatar_id": "g",
+				"name": "n",
+				"company": "c",
+				"blog": "b",
+				"location": "l",
+				"email": "e",
+				"hireable": true,
+				"bio": "b",
+				"twitter_username": "t",
+				"public_repos": 1,
+				"followers": 1,
+				"following": 1,
+				"created_at": ` + referenceTimeStr + `,
+				"suspended_at": ` + referenceTimeStr + `,
+				"url": "u"
+			},
+			"suspended_at": ` + referenceTimeStr + `
+		}
+	}`
+
+	testJSONMarshal(t, u, want)
+}
+
 func TestDiscussionEvent_Marshal(t *testing.T) {
 	testJSONMarshal(t, &DiscussionEvent{}, "{}")
 
diff --git a/github/github-accessors_test.go b/github/github-accessors_test.go
index 2bd40a94..044a45bd 100644
--- a/github/github-accessors_test.go
+++ b/github/github-accessors_test.go
@@ -3373,6 +3373,130 @@ func TestComment_GetCreatedAt(tt *testing.T) {
 	c.GetCreatedAt()
 }
 
+func TestCommentDiscussion_GetAuthorAssociation(tt *testing.T) {
+	var zeroValue string
+	c := &CommentDiscussion{AuthorAssociation: &zeroValue}
+	c.GetAuthorAssociation()
+	c = &CommentDiscussion{}
+	c.GetAuthorAssociation()
+	c = nil
+	c.GetAuthorAssociation()
+}
+
+func TestCommentDiscussion_GetBody(tt *testing.T) {
+	var zeroValue string
+	c := &CommentDiscussion{Body: &zeroValue}
+	c.GetBody()
+	c = &CommentDiscussion{}
+	c.GetBody()
+	c = nil
+	c.GetBody()
+}
+
+func TestCommentDiscussion_GetChildCommentCount(tt *testing.T) {
+	var zeroValue int
+	c := &CommentDiscussion{ChildCommentCount: &zeroValue}
+	c.GetChildCommentCount()
+	c = &CommentDiscussion{}
+	c.GetChildCommentCount()
+	c = nil
+	c.GetChildCommentCount()
+}
+
+func TestCommentDiscussion_GetCreatedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	c := &CommentDiscussion{CreatedAt: &zeroValue}
+	c.GetCreatedAt()
+	c = &CommentDiscussion{}
+	c.GetCreatedAt()
+	c = nil
+	c.GetCreatedAt()
+}
+
+func TestCommentDiscussion_GetDiscussionID(tt *testing.T) {
+	var zeroValue int64
+	c := &CommentDiscussion{DiscussionID: &zeroValue}
+	c.GetDiscussionID()
+	c = &CommentDiscussion{}
+	c.GetDiscussionID()
+	c = nil
+	c.GetDiscussionID()
+}
+
+func TestCommentDiscussion_GetHTMLURL(tt *testing.T) {
+	var zeroValue string
+	c := &CommentDiscussion{HTMLURL: &zeroValue}
+	c.GetHTMLURL()
+	c = &CommentDiscussion{}
+	c.GetHTMLURL()
+	c = nil
+	c.GetHTMLURL()
+}
+
+func TestCommentDiscussion_GetID(tt *testing.T) {
+	var zeroValue int64
+	c := &CommentDiscussion{ID: &zeroValue}
+	c.GetID()
+	c = &CommentDiscussion{}
+	c.GetID()
+	c = nil
+	c.GetID()
+}
+
+func TestCommentDiscussion_GetNodeID(tt *testing.T) {
+	var zeroValue string
+	c := &CommentDiscussion{NodeID: &zeroValue}
+	c.GetNodeID()
+	c = &CommentDiscussion{}
+	c.GetNodeID()
+	c = nil
+	c.GetNodeID()
+}
+
+func TestCommentDiscussion_GetParentID(tt *testing.T) {
+	var zeroValue int64
+	c := &CommentDiscussion{ParentID: &zeroValue}
+	c.GetParentID()
+	c = &CommentDiscussion{}
+	c.GetParentID()
+	c = nil
+	c.GetParentID()
+}
+
+func TestCommentDiscussion_GetReactions(tt *testing.T) {
+	c := &CommentDiscussion{}
+	c.GetReactions()
+	c = nil
+	c.GetReactions()
+}
+
+func TestCommentDiscussion_GetRepositoryURL(tt *testing.T) {
+	var zeroValue string
+	c := &CommentDiscussion{RepositoryURL: &zeroValue}
+	c.GetRepositoryURL()
+	c = &CommentDiscussion{}
+	c.GetRepositoryURL()
+	c = nil
+	c.GetRepositoryURL()
+}
+
+func TestCommentDiscussion_GetUpdatedAt(tt *testing.T) {
+	var zeroValue Timestamp
+	c := &CommentDiscussion{UpdatedAt: &zeroValue}
+	c.GetUpdatedAt()
+	c = &CommentDiscussion{}
+	c.GetUpdatedAt()
+	c = nil
+	c.GetUpdatedAt()
+}
+
+func TestCommentDiscussion_GetUser(tt *testing.T) {
+	c := &CommentDiscussion{}
+	c.GetUser()
+	c = nil
+	c.GetUser()
+}
+
 func TestCommentStats_GetTotalCommitComments(tt *testing.T) {
 	var zeroValue int
 	c := &CommentStats{TotalCommitComments: &zeroValue}
@@ -5921,6 +6045,58 @@ func TestDiscussionComment_GetURL(tt *testing.T) {
 	d.GetURL()
 }
 
+func TestDiscussionCommentEvent_GetAction(tt *testing.T) {
+	var zeroValue string
+	d := &DiscussionCommentEvent{Action: &zeroValue}
+	d.GetAction()
+	d = &DiscussionCommentEvent{}
+	d.GetAction()
+	d = nil
+	d.GetAction()
+}
+
+func TestDiscussionCommentEvent_GetComment(tt *testing.T) {
+	d := &DiscussionCommentEvent{}
+	d.GetComment()
+	d = nil
+	d.GetComment()
+}
+
+func TestDiscussionCommentEvent_GetDiscussion(tt *testing.T) {
+	d := &DiscussionCommentEvent{}
+	d.GetDiscussion()
+	d = nil
+	d.GetDiscussion()
+}
+
+func TestDiscussionCommentEvent_GetInstallation(tt *testing.T) {
+	d := &DiscussionCommentEvent{}
+	d.GetInstallation()
+	d = nil
+	d.GetInstallation()
+}
+
+func TestDiscussionCommentEvent_GetOrg(tt *testing.T) {
+	d := &DiscussionCommentEvent{}
+	d.GetOrg()
+	d = nil
+	d.GetOrg()
+}
+
+func TestDiscussionCommentEvent_GetRepo(tt *testing.T) {
+	d := &DiscussionCommentEvent{}
+	d.GetRepo()
+	d = nil
+	d.GetRepo()
+}
+
+func TestDiscussionCommentEvent_GetSender(tt *testing.T) {
+	d := &DiscussionCommentEvent{}
+	d.GetSender()
+	d = nil
+	d.GetSender()
+}
+
 func TestDiscussionEvent_GetAction(tt *testing.T) {
 	var zeroValue string
 	d := &DiscussionEvent{Action: &zeroValue}
diff --git a/github/messages_test.go b/github/messages_test.go
index 9819ddbe..ee374104 100644
--- a/github/messages_test.go
+++ b/github/messages_test.go
@@ -305,6 +305,10 @@ func TestParseWebHook(t *testing.T) {
 			payload:     &DeploymentStatusEvent{},
 			messageType: "deployment_status",
 		},
+		{
+			payload:     &DiscussionCommentEvent{},
+			messageType: "discussion_comment",
+		},
 		{
 			payload:     &DiscussionEvent{},
 			messageType: "discussion",
diff --git a/github/repos_hooks_deliveries_test.go b/github/repos_hooks_deliveries_test.go
index 44b0f89a..ef453996 100644
--- a/github/repos_hooks_deliveries_test.go
+++ b/github/repos_hooks_deliveries_test.go
@@ -153,6 +153,7 @@ var hookDeliveryPayloadTypeToStruct = map[string]interface{}{
 	"deploy_key":                     &DeployKeyEvent{},
 	"deployment":                     &DeploymentEvent{},
 	"deployment_status":              &DeploymentStatusEvent{},
+	"discussion_comment":             &DiscussionCommentEvent{},
 	"discussion":                     &DiscussionEvent{},
 	"fork":                           &ForkEvent{},
 	"github_app_authorization":       &GitHubAppAuthorizationEvent{},
diff --git a/github/teams_test.go b/github/teams_test.go
index 93e658af..d86fab7f 100644
--- a/github/teams_test.go
+++ b/github/teams_test.go
@@ -1935,6 +1935,79 @@ func TestTeamsService_ListExternalGroups_notFound(t *testing.T) {
 	}
 }
 
+func TestTeamsService_ListExternalGroupsForTeamBySlug(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/orgs/o/teams/t/external-groups", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		fmt.Fprint(w, `{
+			"groups": [
+				{
+					"group_id": 123,
+					"group_name": "Octocat admins",
+					"updated_at": "2006-01-02T15:04:05Z"
+				}
+			]
+		}`)
+	})
+
+	ctx := context.Background()
+	list, _, err := client.Teams.ListExternalGroupsForTeamBySlug(ctx, "o", "t")
+	if err != nil {
+		t.Errorf("Teams.ListExternalGroupsForTeamBySlug returned error: %v", err)
+	}
+
+	want := &ExternalGroupList{
+		Groups: []*ExternalGroup{
+			{
+				GroupID:   Int64(123),
+				GroupName: String("Octocat admins"),
+				UpdatedAt: &Timestamp{Time: referenceTime},
+			},
+		},
+	}
+	if !cmp.Equal(list, want) {
+		t.Errorf("Teams.ListExternalGroupsForTeamBySlug returned %+v, want %+v", list, want)
+	}
+
+	const methodName = "ListExternalGroupsForTeamBySlug"
+	testBadOptions(t, methodName, func() (err error) {
+		_, _, err = client.Teams.ListExternalGroupsForTeamBySlug(ctx, "\n", "\n")
+		return err
+	})
+
+	testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) {
+		got, resp, err := client.Teams.ListExternalGroupsForTeamBySlug(ctx, "o", "t")
+		if got != nil {
+			t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got)
+		}
+		return resp, err
+	})
+}
+
+func TestTeamsService_ListExternalGroupsForTeamBySlug_notFound(t *testing.T) {
+	client, mux, _, teardown := setup()
+	defer teardown()
+
+	mux.HandleFunc("/orgs/o/teams/t/external-groups", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, "GET")
+		w.WriteHeader(http.StatusNotFound)
+	})
+
+	ctx := context.Background()
+	eg, resp, err := client.Teams.ListExternalGroupsForTeamBySlug(ctx, "o", "t")
+	if err == nil {
+		t.Errorf("Expected HTTP 404 response")
+	}
+	if got, want := resp.Response.StatusCode, http.StatusNotFound; got != want {
+		t.Errorf("Teams.ListExternalGroupsForTeamBySlug returned status %d, want %d", got, want)
+	}
+	if eg != nil {
+		t.Errorf("Teams.ListExternalGroupsForTeamBySlug returned %+v, want nil", eg)
+	}
+}
+
 func TestTeamsService_UpdateConnectedExternalGroup(t *testing.T) {
 	client, mux, _, teardown := setup()
 	defer teardown()