Skip to content

Commit

Permalink
Merge pull request #166 from Maniarr/feature/implements_get_moderators
Browse files Browse the repository at this point in the history
Implements GetModerators method
  • Loading branch information
nicklaw5 authored Jan 5, 2023
2 parents 862633a + 95b5456 commit 91958b4
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 1 deletion.
2 changes: 1 addition & 1 deletion SUPPORTED_ENDPOINTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
- [x] Add Blocked Term
- [x] Remove Blocked Term
- [x] Delete Chat Messages
- [ ] Get Moderators
- [x] Get Moderators
- [ ] Get Moderator Events
- [ ] Remove Channel Moderator
- [ ] Get VIPs
Expand Down
27 changes: 27 additions & 0 deletions docs/moderation_docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,3 +261,30 @@ if err != nil {

fmt.Printf("%+v\n", resp)
```

## Get Moderators

To use this function you need a user access token with the `moderation:read` scope.
`BroadcasterID` is required and need to be the same as the user id of the user access token.

This is an example of how to get moderators of a channel.

```go
client, err := helix.NewClient(&helix.Options{
ClientID: "your-client-id",
UserAccessToken: "your-user-access-token",
})
if err != nil {
// handle error
}

resp, err := client.GetModerators(&helix.GetModeratorsParams{
BroadcasterID: "145328278",
First: 10
})
if err != nil {
// handle error
}

fmt.Printf("%+v\n", resp)
```
46 changes: 46 additions & 0 deletions moderation.go
Original file line number Diff line number Diff line change
Expand Up @@ -291,3 +291,49 @@ func (c *Client) DeleteAllChatMessages(params *DeleteAllChatMessagesParams) (*De

return deletedMessagesResp, nil
}

type GetModeratorsParams struct {
// Required
BroadcasterID string `query:"broadcaster_id"`

// Optional
UserIDs []string `query:"user_id"` // Limit 100
After string `query:"after"`
First int `query:"first"`
}

type Moderator struct {
UserID string `json:"user_id"`
UserLogin string `json:"user_login"`
UserName string `json:"user_name"`
}

type ManyModerators struct {
Moderators []Moderator `json:"data"`
Pagination Pagination `json:"pagination"`
}

type ModeratorsResponse struct {
ResponseCommon
Data ManyModerators
}

// GetModerators Gets all users allowed to moderate the broadcaster’s chat room.
// Required scope: moderation:read
func (c *Client) GetModerators(params *GetModeratorsParams) (*ModeratorsResponse, error) {
if params.BroadcasterID == "" {
return nil, errors.New("broadcaster id must be provided")
}

resp, err := c.get("/moderation/moderators", &ManyModerators{}, params)
if err != nil {
return nil, err
}

moderators := &ModeratorsResponse{}
resp.HydrateResponseCommon(&moderators.ResponseCommon)
moderators.Data.Moderators = resp.Data.(*ManyModerators).Moderators
moderators.Data.Pagination = resp.Data.(*ManyModerators).Pagination

return moderators, nil
}
102 changes: 102 additions & 0 deletions moderation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -622,6 +622,7 @@ func TestDeleteChatMessage(t *testing.T) {
}
c := &Client{
opts: options,
ctx: context.Background(),
}

_, err := c.RemoveBlockedTerm(&RemoveBlockedTermParams{BroadcasterID: "1234", ModeratorID: "1234", ID: "test"})
Expand Down Expand Up @@ -696,6 +697,7 @@ func TestDeleteAllChatMessages(t *testing.T) {
}
c := &Client{
opts: options,
ctx: context.Background(),
}

_, err := c.RemoveBlockedTerm(&RemoveBlockedTermParams{BroadcasterID: "1234", ModeratorID: "1234", ID: "test"})
Expand All @@ -707,3 +709,103 @@ func TestDeleteAllChatMessages(t *testing.T) {
t.Error("expected error does match return error")
}
}

func TestGetModerators(t *testing.T) {
t.Parallel()

testCases := []struct {
statusCode int
options *Options
params *GetModeratorsParams
respBody string
parsed []Moderator
errorMsg string
}{
{
http.StatusOK,
&Options{ClientID: "my-client-id", UserAccessToken: "moderator-access-token"},
&GetModeratorsParams{BroadcasterID: "424596340", First: 2},
`{
"data": [
{
"user_id": "424596340",
"user_login": "quotrok",
"user_name": "quotrok"
}
],
"pagination": {
"cursor": "eyJiIjpudWxsLCJhIjp7IkN1cnNvciI6I..."
}
}`,
[]Moderator{
{
UserID: "424596340",
UserLogin: "quotrok",
UserName: "quotrok",
},
},
"",
},
{
http.StatusBadRequest,
&Options{ClientID: "my-client-id", UserAccessToken: "moderator-access-token"},
&GetModeratorsParams{BroadcasterID: ""},
``,
[]Moderator{},
"broadcaster id must be provided",
},
}

for _, testCase := range testCases {
c := newMockClient(testCase.options, newMockHandler(testCase.statusCode, testCase.respBody, nil))

resp, err := c.GetModerators(testCase.params)

if err != nil {
if err.Error() != testCase.errorMsg {
t.Errorf("expected error message to be %s, got %s", testCase.errorMsg, err.Error())
}
continue
}

if resp.StatusCode != testCase.statusCode {
t.Errorf("expected status code to be %d, got %d", testCase.statusCode, resp.StatusCode)
}

for i, moderator := range resp.Data.Moderators {
if moderator.UserID != testCase.parsed[i].UserID {
t.Errorf("Expected struct field UserID = %s, was %s", testCase.parsed[i].UserID, moderator.UserID)
}

if moderator.UserLogin != testCase.parsed[i].UserLogin {
t.Errorf("Expected struct field BroadcasterName = %s, was %s", testCase.parsed[i].UserLogin, moderator.UserLogin)
}

if moderator.UserName != testCase.parsed[i].UserName {
t.Errorf("Expected struct field BroadcasterLanguage = %s, was %s", testCase.parsed[i].UserName, moderator.UserName)
}
}

}

// Test with HTTP Failure
options := &Options{
ClientID: "my-client-id",
HTTPClient: &badMockHTTPClient{
newMockHandler(0, "", nil),
},
}
c := &Client{
opts: options,
ctx: context.Background(),
}

_, err := c.GetModerators(&GetModeratorsParams{BroadcasterID: "424596340", First: 2})
if err == nil {
t.Error("expected error but got nil")
}

if err.Error() != "Failed to execute API request: Oops, that's bad :(" {
t.Error("expected error does match return error")
}
}

0 comments on commit 91958b4

Please sign in to comment.