Content-Length: 402006 | pFad | http://github.com/nicklaw5/helix/commit/b1b883a0af8473782f0bad8cfb10f1c905162123

24 feat: warn chat user endpoint · nicklaw5/helix@b1b883a · GitHub
Skip to content

Commit

Permalink
feat: warn chat user endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
jackmcguire1 committed Jul 4, 2024
1 parent 22863cc commit b1b883a
Show file tree
Hide file tree
Showing 4 changed files with 201 additions and 0 deletions.
1 change: 1 addition & 0 deletions SUPPORTED_ENDPOINTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,3 +124,4 @@
- [x] Delete Videos
- [x] Send Whisper
- [x] Get Webhook Subscriptions
- [x] Warn Chat User
28 changes: 28 additions & 0 deletions docs/moderation_docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -314,3 +314,31 @@ if err != nil {

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

## Warn Chat User

Requires a user access token that includes the moderator:manage:warnings scope. Query parameter moderator_id must match the user_id in the user access token.

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

resp, err := client.SendModeratorWarnMessage(
&SendModeratorWarnChatMessageParams{
BroadcasterID: "1234",
ModeratorID: "5678",
UserID: "9876",
Reason: "Test warning message",
},
)
if err != nil {
// handle error
}

fmt.Printf("%+v\n", resp)
```
61 changes: 61 additions & 0 deletions moderation.go
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,64 @@ func (c *Client) GetModeratedChannels(params *GetModeratedChannelsParams) (*GetM

return moderatedChannels, nil
}

type SendModeratorWarnChatMessageParams struct {
// The ID of the broadcaster whose chat room the message will be sent to
BroadcasterID string `query:"broadcaster_id"`

ModeratorID string `query:"moderator_id"`

// The ID of the user sent the WARN message
UserID string `json:"user_id"`

// The warn message to send.
Reason string `json:"reason"`

// The ID of the chat message being replied to
ReplyParentMessageID string `json:"reply_parent_message_id,omitempty"`
}

type ModeratorWarnChatMessage struct {
BroadcasterID string `json:"broadcaster_id"`
ModeratorID string `json:"moderator_id"`
UserID string `json:"user_id"`
Reason string `json:"reason"`
}

type ManyModeratorWarnChatMessages struct {
Message ModeratorWarnChatMessage `json:"data"`
}

type SendModeratorWarnChatResponse struct {
ResponseCommon

Data ModeratorWarnChatMessage
}

// SendModeratorWarnMessage Sends a warning message to a user in the broadcaster’s chat.
// Required moderator:manage:warnings
func (c *Client) SendModeratorWarnMessage(params *SendModeratorWarnChatMessageParams) (*SendModeratorWarnChatResponse, error) {
if params.BroadcasterID == "" {
return nil, errors.New("error: broadcaster id must be specified")
}
if params.ModeratorID == "" {
return nil, errors.New("error: moderator id must be specified")
}
if params.UserID == "" {
return nil, errors.New("error: user id must be specified")
}

resp, err := c.postAsJSON("moderation/warnings", &ManyModeratorWarnChatMessages{}, params)
if err != nil {
return nil, err
}

messageResponse := &SendModeratorWarnChatResponse{}
resp.HydrateResponseCommon(&messageResponse.ResponseCommon)
messageResponse.Data.UserID = resp.Data.(*ManyModeratorWarnChatMessages).Message.UserID
messageResponse.Data.BroadcasterID = resp.Data.(*ManyModeratorWarnChatMessages).Message.BroadcasterID
messageResponse.Data.ModeratorID = resp.Data.(*ManyModeratorWarnChatMessages).Message.ModeratorID
messageResponse.Data.Reason = resp.Data.(*ManyModeratorWarnChatMessages).Message.Reason

return messageResponse, nil
}
111 changes: 111 additions & 0 deletions moderation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1117,3 +1117,114 @@ func TestGetModeratedChannels(t *testing.T) {
t.Error("expected error does match return error")
}
}

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

testCases := []struct {
statusCode int
options *Options
params *SendModeratorWarnChatMessageParams
respBody string
errorMsg string
}{
{
http.StatusOK,
&Options{ClientID: "my-client-id", UserAccessToken: "moderator-access-token"},
&SendModeratorWarnChatMessageParams{
BroadcasterID: "1234",
ModeratorID: "5678",
UserID: "9876",
Reason: "Test warning message",
},
`{"data": {"broadcaster_id": "1234", "moderator_id": "5678", "user_id": "9876", "reason": "Test warning message"}}`,
"",
},
{
http.StatusUnauthorized,
&Options{ClientID: "my-client-id", UserAccessToken: "invalid-access-token"},
&SendModeratorWarnChatMessageParams{
BroadcasterID: "1234",
ModeratorID: "5678",
Reason: "Test warning message",
},
`{"error":"Unauthorized","status":401,"message":"Invalid OAuth token"}`,
"error: user id must be specified",
},
{
http.StatusUnauthorized,
&Options{ClientID: "my-client-id", UserAccessToken: "invalid-access-token"},
&SendModeratorWarnChatMessageParams{
BroadcasterID: "1234",
ModeratorID: "5678",
UserID: "9876",
Reason: "Test warning message",
},
`{"error":"Unauthorized","status":401,"message":"Invalid OAuth token"}`,
"",
},
// Add more test cases as needed
}

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

resp, err := c.SendModeratorWarnMessage(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)
}

if resp.StatusCode > http.StatusOK {
continue
}

if resp.Data.BroadcasterID != testCase.params.BroadcasterID {
t.Errorf("expected broadcaster id to be %s, got %s", testCase.params.BroadcasterID, resp.Data.BroadcasterID)
}

if resp.Data.ModeratorID != testCase.params.ModeratorID {
t.Errorf("expected moderator id to be %s, got %s", testCase.params.ModeratorID, resp.Data.ModeratorID)
}

if resp.Data.UserID != testCase.params.UserID {
t.Errorf("expected user id to be %s, got %s", testCase.params.UserID, resp.Data.UserID)
}

if resp.Data.Reason != testCase.params.Reason {
t.Errorf("expected reason to be %s, got %s", testCase.params.Reason, resp.Data.Reason)
}
}

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

_, err := c.SendModeratorWarnMessage(&SendModeratorWarnChatMessageParams{
BroadcasterID: "1234",
ModeratorID: "5678",
UserID: "9876",
Reason: "Test warning message",
})
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 b1b883a

Please sign in to comment.








ApplySandwichStrip

pFad - (p)hone/(F)rame/(a)nonymizer/(d)eclutterfier!      Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

Fetched URL: http://github.com/nicklaw5/helix/commit/b1b883a0af8473782f0bad8cfb10f1c905162123

Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy