Add Moderation endpoints to API
This commit is contained in:
parent
2b22790188
commit
e941e414e2
|
@ -20,6 +20,7 @@ import (
|
||||||
"go.fifitido.net/twitch/api/goals"
|
"go.fifitido.net/twitch/api/goals"
|
||||||
"go.fifitido.net/twitch/api/gueststar"
|
"go.fifitido.net/twitch/api/gueststar"
|
||||||
"go.fifitido.net/twitch/api/hypetrain"
|
"go.fifitido.net/twitch/api/hypetrain"
|
||||||
|
"go.fifitido.net/twitch/api/moderation"
|
||||||
)
|
)
|
||||||
|
|
||||||
const HelixBaseUrl = "https://api.twitch.tv/helix"
|
const HelixBaseUrl = "https://api.twitch.tv/helix"
|
||||||
|
@ -44,6 +45,7 @@ type API struct {
|
||||||
Goals *goals.Goals
|
Goals *goals.Goals
|
||||||
GuestStar *gueststar.GuestStar
|
GuestStar *gueststar.GuestStar
|
||||||
Hypetrain *hypetrain.Hypetrain
|
Hypetrain *hypetrain.Hypetrain
|
||||||
|
Moderation *moderation.Moderation
|
||||||
}
|
}
|
||||||
|
|
||||||
func New() *API {
|
func New() *API {
|
||||||
|
@ -70,5 +72,6 @@ func New() *API {
|
||||||
Goals: goals.New(client, baseUrl),
|
Goals: goals.New(client, baseUrl),
|
||||||
GuestStar: gueststar.New(client, baseUrl),
|
GuestStar: gueststar.New(client, baseUrl),
|
||||||
Hypetrain: hypetrain.New(client, baseUrl),
|
Hypetrain: hypetrain.New(client, baseUrl),
|
||||||
|
Moderation: moderation.New(client, baseUrl),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddBlockedTermParams struct {
|
||||||
|
// The ID of the broadcaster that owns the list of blocked terms.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddBlockedTermRequest struct {
|
||||||
|
// The word or phrase to block from being used in the broadcaster’s chat room.
|
||||||
|
// The term must contain a minimum of 2 characters and may contain up to a maximum of 500 characters.
|
||||||
|
//
|
||||||
|
// Terms may include a wildcard character (*).
|
||||||
|
// The wildcard character must appear at the beginning or end of a word or set of characters.
|
||||||
|
// For example, *foo or foo*.
|
||||||
|
//
|
||||||
|
// If the blocked term already exists, the response contains the existing blocked term.
|
||||||
|
Text string `json:"text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddBlockedTermResponse struct {
|
||||||
|
// A list that contains the single blocked term that the broadcaster added.
|
||||||
|
Data []BlockedTerm `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds a word or phrase to the broadcaster’s list of blocked terms.
|
||||||
|
// These are the terms that the broadcaster doesn’t want used in their chat room.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:blocked_terms scope.
|
||||||
|
func (m *Moderation) AddBlockedTerm(ctx context.Context, params *AddBlockedTermParams, body *AddBlockedTermRequest) (*AddBlockedTermResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/blocked_terms", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
r, w := io.Pipe()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if err := json.NewEncoder(w).Encode(body); err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
} else {
|
||||||
|
w.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data AddBlockedTermResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddChannelModeratorParams struct {
|
||||||
|
// The ID of the broadcaster that owns the chat room. This ID must match the user ID in the access token.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the user to add as a moderator in the broadcaster’s chat room.
|
||||||
|
UserID string `url:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds a moderator to the broadcaster’s chat room.
|
||||||
|
//
|
||||||
|
// Rate Limits: The broadcaster may add a maximum of 10 moderators within a 10-second window.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the channel:manage:moderators scope.
|
||||||
|
func (m *Moderation) AddChannelModerator(ctx context.Context, params *AddChannelModeratorParams) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/moderators", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AddChannelVIPParams struct {
|
||||||
|
// The ID of the user to give VIP status to.
|
||||||
|
UserID string `url:"user_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster that’s adding the user as a VIP. This ID must match the user ID in the access token.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adds the specified user as a VIP in the broadcaster’s channel.
|
||||||
|
//
|
||||||
|
// Rate Limits: The broadcaster may add a maximum of 10 VIPs within a 10-second window.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the channel:manage:vips scope.
|
||||||
|
func (m *Moderation) AddChannelVIP(ctx context.Context, params *AddChannelVIPParams) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "channels/vips", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,101 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BanUserParams struct {
|
||||||
|
// The ID of the broadcaster whose chat room the user is being banned from.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BanUserRequest struct {
|
||||||
|
// The ID of the user to ban or put in a timeout.
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
|
||||||
|
// To ban a user indefinitely, don’t include this field.
|
||||||
|
//
|
||||||
|
// To put a user in a timeout, include this field and specify the timeout period, in seconds.
|
||||||
|
// The minimum timeout is 1 second and the maximum is 1,209,600 seconds (2 weeks).
|
||||||
|
Duration *int `json:"duration"`
|
||||||
|
|
||||||
|
// The reason the you’re banning the user or putting them in a timeout.
|
||||||
|
// The text is user defined and is limited to a maximum of 500 characters.
|
||||||
|
Reason *string `json:"reason"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BanUserResponse struct {
|
||||||
|
// Identifies the user and type of ban.
|
||||||
|
Data []BanUserResponseData `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BanUserResponseData struct {
|
||||||
|
// The broadcaster whose chat room the user was banned from chatting in.
|
||||||
|
BroadcasterID string `json:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The moderator that banned or put the user in the timeout.
|
||||||
|
ModeratorID string `json:"moderator_id"`
|
||||||
|
|
||||||
|
// The user that was banned or put in a timeout.
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
|
||||||
|
// The UTC date and time (in RFC3339 format) that the ban or timeout was placed.
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
|
||||||
|
// The UTC date and time (in RFC3339 format) that the timeout will end. Is null if the user was banned instead of being put in a timeout.
|
||||||
|
EndTime *time.Time `json:"end_time"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bans a user from participating in the specified broadcaster’s chat room or puts them in a timeout.
|
||||||
|
//
|
||||||
|
// For information about banning or putting users in a timeout, see Ban a User and Timeout a User.
|
||||||
|
//
|
||||||
|
// If the user is currently in a timeout, you can call this endpoint to change the duration of the timeout or ban them altogether.
|
||||||
|
// If the user is currently banned, you cannot call this method to put them in a timeout instead.
|
||||||
|
//
|
||||||
|
// To remove a ban or end a timeout, see Unban user.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:banned_users scope.
|
||||||
|
func (m *Moderation) BanUser(ctx context.Context, params *BanUserParams, body *BanUserRequest) (*BanUserResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/bans", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
r, w := io.Pipe()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if err := json.NewEncoder(w).Encode(body); err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
} else {
|
||||||
|
w.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data BanUserResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,73 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CheckAutoModStatusRequest struct {
|
||||||
|
Data []CheckAutoModStatusRequestData `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CheckAutoModStatusRequestData struct {
|
||||||
|
// A caller-defined ID used to correlate this message with the same message in the response.
|
||||||
|
MsgID string `json:"msg_id"`
|
||||||
|
|
||||||
|
// The message to check.
|
||||||
|
MsgText string `json:"msg_text"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CheckAutoModStatusResponse struct {
|
||||||
|
// The list of messages and whether Twitch would approve them for chat.
|
||||||
|
Data []CheckAutoModStatusResponseData `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CheckAutoModStatusResponseData struct {
|
||||||
|
// The caller-defined ID passed in the request.
|
||||||
|
MsgID string `json:"msg_id"`
|
||||||
|
|
||||||
|
// A Boolean value that indicates whether Twitch would approve the message for chat or hold it for moderator review or block it from chat.
|
||||||
|
// Is true if Twitch would approve the message; otherwise, false if Twitch would hold the message for moderator review or block it from chat.
|
||||||
|
IsPermitted bool `json:"is_permitted"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Checks whether AutoMod would flag the specified message for review.
|
||||||
|
//
|
||||||
|
// AutoMod is a moderation tool that holds inappropriate or harassing chat messages for moderators to review. Moderators approve or deny the messages that AutoMod flags; only approved messages are released to chat. AutoMod detects misspellings and evasive language automatically. For information about AutoMod, see How to Use AutoMod.
|
||||||
|
//
|
||||||
|
// Rate Limits: Rates are limited per channel based on the account type rather than per access token.
|
||||||
|
//
|
||||||
|
// Account type | Limit per minute | Limit per hour
|
||||||
|
// ------------ | ---------------- | --------------
|
||||||
|
// Free | 1 | 10
|
||||||
|
// Normal | 5 | 50
|
||||||
|
// Affiliated | 10 | 100
|
||||||
|
// Partnered | 30 | 300
|
||||||
|
//
|
||||||
|
// The above limits are in addition to the standard Twitch API rate limits.
|
||||||
|
// The rate limit headers in the response represent the Twitch rate limits and not the above limits.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderation:read scope.
|
||||||
|
func (c *Moderation) CheckAutoModStatus(ctx context.Context, broadcasterID string, params *CheckAutoModStatusRequest) (*CheckAutoModStatusResponse, error) {
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "modetation/enforcements/status", RawQuery: url.Values{"broadcaster_id": {broadcasterID}}.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data CheckAutoModStatusResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeleteChatMessagesParams struct {
|
||||||
|
// The ID of the broadcaster that owns the chat room to remove messages from.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
|
||||||
|
// The ID of the message to remove. The id tag in the PRIVMSG tag contains the message’s ID. Restrictions:
|
||||||
|
//
|
||||||
|
// - The message must have been created within the last 6 hours.
|
||||||
|
//
|
||||||
|
// - The message must not belong to the broadcaster.
|
||||||
|
//
|
||||||
|
// - The message must not belong to another moderator.
|
||||||
|
//
|
||||||
|
// If not specified, the request removes all messages in the broadcaster’s chat room.
|
||||||
|
MessageID *string `url:"message_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes a single chat message or all chat messages from the broadcaster’s chat room.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:chat_messages scope.
|
||||||
|
func (m *Moderation) DeleteChatMessages(ctx context.Context, params *DeleteChatMessagesParams) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/chat", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetAutoModSettingsParams struct {
|
||||||
|
// The ID of the broadcaster whose AutoMod settings you want to get.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetAutoModSettingsResponse struct {
|
||||||
|
// The list of AutoMod settings. The list contains a single object that contains all the AutoMod settings.
|
||||||
|
Data []AutoModSettings `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the broadcaster’s AutoMod settings.
|
||||||
|
// The settings are used to automatically block inappropriate or harassing messages from appearing in the broadcaster’s chat room.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:read:automod_settings scope.
|
||||||
|
func (m *Moderation) GetAutoModSettings(ctx context.Context, params *GetAutoModSettingsParams) (*GetAutoModSettingsResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/automod/settings", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data GetAutoModSettingsResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
"go.fifitido.net/twitch/api/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetBannedUsersParams struct {
|
||||||
|
// The ID of the broadcaster whose list of banned users you want to get. This ID must match the user ID in the access token.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// A list of user IDs used to filter the results.
|
||||||
|
// To specify more than one ID, include this parameter for each user you want to get.
|
||||||
|
// For example, user_id=1234&user_id=5678.
|
||||||
|
// You may specify a maximum of 100 IDs.
|
||||||
|
//
|
||||||
|
// The returned list includes only those users that were banned or put in a timeout.
|
||||||
|
// The list is returned in the same order that you specified the IDs.
|
||||||
|
UserID []string `url:"user_id"`
|
||||||
|
|
||||||
|
// The maximum number of items to return per page in the response.
|
||||||
|
// The minimum page size is 1 item per page and the maximum is 100 items per page.
|
||||||
|
// The default is 20.
|
||||||
|
First *int `url:"first"`
|
||||||
|
|
||||||
|
// The cursor used to get the next page of results. The Pagination object in the response contains the cursor’s value.
|
||||||
|
// Read More: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
After *types.Cursor `url:"after"`
|
||||||
|
|
||||||
|
// The cursor used to get the previous page of results. The Pagination object in the response contains the cursor’s value.
|
||||||
|
// Read More: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
Before *types.Cursor `url:"before"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetBannedUsersResponse struct {
|
||||||
|
// The list of banned users. The list contains a single object that contains all the banned users.
|
||||||
|
Data []GetBannedUsersResponseData `json:"data"`
|
||||||
|
|
||||||
|
// Contains information about the pagination in the response.
|
||||||
|
// The object is empty if there are no more pages of results.
|
||||||
|
// Read More: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
Pagination types.Pagination `json:"pagination"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetBannedUsersResponseData struct {
|
||||||
|
// The ID of the banned user.
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
|
||||||
|
// The banned user’s login name.
|
||||||
|
UserLogin string `json:"user_login"`
|
||||||
|
|
||||||
|
// The banned user’s display name.
|
||||||
|
UserName string `json:"user_name"`
|
||||||
|
|
||||||
|
// The UTC date and time (in RFC3339 format) of when the timeout expires, or an empty string if the user is permanently banned.
|
||||||
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
|
|
||||||
|
// The UTC date and time (in RFC3339 format) of when the user was banned.
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
|
||||||
|
// The reason the user was banned or put in a timeout if the moderator provided one.
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
|
||||||
|
// The ID of the moderator that banned the user or put them in a timeout.
|
||||||
|
ModeratorID string `json:"moderator_id"`
|
||||||
|
|
||||||
|
// The moderator’s login name.
|
||||||
|
ModeratorLogin string `json:"moderator_login"`
|
||||||
|
|
||||||
|
// The moderator’s display name.
|
||||||
|
ModeratorName string `json:"moderator_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets all users that the broadcaster banned or put in a timeout.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderation:read or moderator:manage:banned_users scope.
|
||||||
|
func (m *Moderation) GetBannedUsers(ctx context.Context, params *GetBannedUsersParams) (*GetBannedUsersResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/banned", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data GetBannedUsersResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
"go.fifitido.net/twitch/api/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetBlockedTermsParams struct {
|
||||||
|
// The ID of the broadcaster whose blocked terms you're getting.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that has permission to moderate the broadcaster's chat room.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
|
||||||
|
// The maximum number of items to return per page in the response.
|
||||||
|
// The minimum page size is 1 item per page and the maximum is 100 items per page.
|
||||||
|
// The default is 20.
|
||||||
|
First *int `url:"first"`
|
||||||
|
|
||||||
|
// The cursor used to get the next page of results. The Pagination object in the response contains the cursor’s value.
|
||||||
|
After *types.Cursor `url:"after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetBlockedTermsResponse struct {
|
||||||
|
// The list of blocked terms. The list is in descending order of when they were created (see the created_at timestamp).
|
||||||
|
Data []BlockedTerm `json:"data"`
|
||||||
|
|
||||||
|
// Contains information about the pagination in the response.
|
||||||
|
// The object is empty if there are no more pages of results.
|
||||||
|
// Read More: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
Pagination types.Pagination `json:"pagination"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the broadcaster’s list of non-private, blocked words or phrases.
|
||||||
|
// These are the terms that the broadcaster or moderator added manually or that were denied by AutoMod.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:read:blocked_terms or moderator:manage:blocked_terms scope.
|
||||||
|
func (m *Moderation) GetBlockedTerms(ctx context.Context, params *GetBlockedTermsParams) (*GetBlockedTermsResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/blocked_terms", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data GetBlockedTermsResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
"go.fifitido.net/twitch/api/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetModeratedChannelsParams struct {
|
||||||
|
// A user’s ID. Returns the list of channels that this user has moderator privileges in. This ID must match the user ID in the user OAuth token
|
||||||
|
UserID string `url:"user_id"`
|
||||||
|
|
||||||
|
// The cursor used to get the next page of results. The Pagination object in the response contains the cursor’s value.
|
||||||
|
After *types.Cursor `url:"after"`
|
||||||
|
|
||||||
|
// The maximum number of items to return per page in the response.
|
||||||
|
// The minimum page size is 1 item per page and the maximum is 100 items per page.
|
||||||
|
// The default is 20.
|
||||||
|
First *int `url:"first"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetModeratedChannelsResponse struct {
|
||||||
|
// The list of channels that the user has moderator privileges in.
|
||||||
|
Data []GetModeratedChannelsResponseData `json:"data"`
|
||||||
|
|
||||||
|
// Contains information about the pagination in the response.
|
||||||
|
// The object is empty if there are no more pages of results.
|
||||||
|
// Read More: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
Pagination types.Pagination `json:"pagination"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetModeratedChannelsResponseData struct {
|
||||||
|
// An ID that uniquely identifies the channel this user can moderate.
|
||||||
|
BroadcasterID string `json:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The channel’s login name.
|
||||||
|
BroadcasterLogin string `json:"broadcaster_login"`
|
||||||
|
|
||||||
|
// The channels’ display name.
|
||||||
|
BroadcasterName string `json:"broadcaster_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a list of channels that the specified user has moderator privileges in.
|
||||||
|
//
|
||||||
|
// Query parameter user_id must match the user ID in the User-Access token
|
||||||
|
// Requires OAuth Scope: user:read:moderated_channels
|
||||||
|
func (m *Moderation) GetModeratedChannels(ctx context.Context, params *GetModeratedChannelsParams) (*GetModeratedChannelsResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/channels", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data GetModeratedChannelsResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,82 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
"go.fifitido.net/twitch/api/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetModeratorsParams struct {
|
||||||
|
// The ID of the broadcaster whose list of moderators you want to get. This ID must match the user ID in the access token.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// A list of user IDs used to filter the results.
|
||||||
|
// To specify more than one ID, include this parameter for each moderator you want to get.
|
||||||
|
// For example, user_id=1234&user_id=5678.
|
||||||
|
// You may specify a maximum of 100 IDs.
|
||||||
|
//
|
||||||
|
// The returned list includes only the users from the list who are moderators in the broadcaster’s channel.
|
||||||
|
// The list is returned in the same order as you specified the IDs.
|
||||||
|
UserID []string `url:"user_id"`
|
||||||
|
|
||||||
|
// The maximum number of items to return per page in the response.
|
||||||
|
// The minimum page size is 1 item per page and the maximum is 100 items per page.
|
||||||
|
// The default is 20.
|
||||||
|
First *int `url:"first"`
|
||||||
|
|
||||||
|
// The cursor used to get the next page of results. The Pagination object in the response contains the cursor’s value.
|
||||||
|
// Read More: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
After *types.Cursor `url:"after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetModeratorsResponse struct {
|
||||||
|
// The list of moderators. The list contains a single object that contains all the moderators.
|
||||||
|
Data []GetModeratorsResponseData `json:"data"`
|
||||||
|
|
||||||
|
// Contains information about the pagination in the response.
|
||||||
|
// The object is empty if there are no more pages of results.
|
||||||
|
// Read More: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
Pagination types.Pagination `json:"pagination"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetModeratorsResponseData struct {
|
||||||
|
// The ID of the user that has permission to moderate the broadcaster’s channel.
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
|
||||||
|
// The user’s login name.
|
||||||
|
UserLogin string `json:"user_login"`
|
||||||
|
|
||||||
|
// The user’s display name.
|
||||||
|
UserName string `json:"user_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets all users allowed to moderate the broadcaster’s chat room.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderation:read scope.
|
||||||
|
// If your app also adds and removes moderators, you can use the channel:manage:moderators scope instead.
|
||||||
|
func (m *Moderation) GetModerators(ctx context.Context, params *GetModeratorsParams) (*GetModeratorsResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/moderators", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data GetModeratorsResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetShieldModeStatusParams struct {
|
||||||
|
// The ID of the broadcaster whose Shield Mode activation status you want to get.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that is one of the broadcaster’s moderators. This ID must match the user ID in the access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetShieldModeStatusResponse struct {
|
||||||
|
// A list that contains a single object with the broadcaster’s Shield Mode status.
|
||||||
|
Data []ShieldModeStatus `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the broadcaster’s Shield Mode activation status.
|
||||||
|
//
|
||||||
|
// To receive notification when the broadcaster activates and deactivates Shield Mode,
|
||||||
|
// subscribe to the channel.shield_mode.begin and channel.shield_mode.end subscription types.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:read:shield_mode or moderator:manage:shield_mode scope.
|
||||||
|
func (m *Moderation) GetShieldModeStatus(ctx context.Context, params *GetShieldModeStatusParams) (*GetShieldModeStatusResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/shield_mode", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data GetShieldModeStatusResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
"go.fifitido.net/twitch/api/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetVIPsParams struct {
|
||||||
|
// Filters the list for specific VIPs.
|
||||||
|
// To specify more than one user, include the user_id parameter for each user to get. For example, &user_id=1234&user_id=5678.
|
||||||
|
// The maximum number of IDs that you may specify is 100.
|
||||||
|
// Ignores the ID of those users in the list that aren’t VIPs.
|
||||||
|
UserIDs []string `url:"user_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster whose list of VIPs you want to get. This ID must match the user ID in the access token.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The maximum number of items to return per page in the response.
|
||||||
|
// The minimum page size is 1 item per page and the maximum is 100 items per page.
|
||||||
|
// The default is 20.
|
||||||
|
First *int `url:"first"`
|
||||||
|
|
||||||
|
// The cursor used to get the next page of results.
|
||||||
|
// The Pagination object in the response contains the cursor’s value.
|
||||||
|
// Read More: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
After *types.Cursor `url:"after"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetVIPsResponse struct {
|
||||||
|
// The list of VIPs. The list contains a single object that contains all the VIPs.
|
||||||
|
Data []GetVIPsResponseData `json:"data"`
|
||||||
|
|
||||||
|
// Contains information about the pagination in the response.
|
||||||
|
// The object is empty if there are no more pages of results.
|
||||||
|
// Read More: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
Pagination types.Pagination `json:"pagination"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetVIPsResponseData struct {
|
||||||
|
// An ID that uniquely identifies the VIP user.
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
|
||||||
|
// The user’s display name.
|
||||||
|
UserName string `json:"user_name"`
|
||||||
|
|
||||||
|
// The user’s login name.
|
||||||
|
UserLogin string `json:"user_login"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets a list of the broadcaster’s VIPs.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the channel:read:vips scope.
|
||||||
|
// If your app also adds and removes VIP status, you can use the channel:manage:vips scope instead.
|
||||||
|
func (m *Moderation) GetVIPs(ctx context.Context, params GetVIPsParams) (*GetVIPsResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/vips", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var data GetVIPsResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type AutoModAction string
|
||||||
|
|
||||||
|
const (
|
||||||
|
AutoModActionAllow AutoModAction = "ALLOW"
|
||||||
|
AutoModActionDeny AutoModAction = "DENY"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ManageHeldAutoModMessagesRequest struct {
|
||||||
|
// The moderator who is approving or denying the held message. This ID must match the user ID in the access token.
|
||||||
|
UserID string `url:"user_id"`
|
||||||
|
|
||||||
|
// The ID of the message to allow or deny.
|
||||||
|
MsgID string `url:"msg_id"`
|
||||||
|
|
||||||
|
// The action to take for the message.
|
||||||
|
Action AutoModAction `url:"action"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow or deny the message that AutoMod flagged for review.
|
||||||
|
// For information about AutoMod, see How to Use AutoMod: https://help.twitch.tv/s/article/how-to-use-automod
|
||||||
|
//
|
||||||
|
// To get messages that AutoMod is holding for review, subscribe to the automod-queue.<moderator_id>.<channel_id> topic using PubSub.
|
||||||
|
// PubSub sends a notification to your app when AutoMod holds a message for review.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:automod scope.
|
||||||
|
func (m *Moderation) ManageHeldAutoModMessages(ctx context.Context, body *ManageHeldAutoModMessagesRequest) error {
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/automod/message"})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import "time"
|
||||||
|
|
||||||
|
type AutoModSettings struct {
|
||||||
|
// The ID of the broadcaster whose AutoMod settings you want to get.
|
||||||
|
BroadcasterID string `json:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `json:"moderator_id"`
|
||||||
|
|
||||||
|
// The default AutoMod level for the broadcaster. This field is null if the broadcaster has set one or more of the individual settings.
|
||||||
|
OverallLevel int `json:"overall_level"`
|
||||||
|
|
||||||
|
// The Automod level for discrimination against disability.
|
||||||
|
Disability int `json:"disability"`
|
||||||
|
|
||||||
|
// The Automod level for hostility involving aggression.
|
||||||
|
Aggression int `json:"aggression"`
|
||||||
|
|
||||||
|
// The Automod level for discrimination based on sexuality, sex, or gender.
|
||||||
|
SexualitySexOrGender int `json:"sexuality_sex_or_gender"`
|
||||||
|
|
||||||
|
// The Automod level for discrimination against women.
|
||||||
|
Misogyny int `json:"misogyny"`
|
||||||
|
|
||||||
|
// The Automod level for hostility involving name calling or insults.
|
||||||
|
Bullying int `json:"bullying"`
|
||||||
|
|
||||||
|
// The Automod level for profanity.
|
||||||
|
Swearing int `json:"swearing"`
|
||||||
|
|
||||||
|
// The Automod level for racial discrimination.
|
||||||
|
RaceEthnicityOrReligion int `json:"race_ethnicity_or_religion"`
|
||||||
|
|
||||||
|
// The Automod level for sexual content.
|
||||||
|
SexBasedTerms int `json:"sex_based_terms"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BlockedTerm struct {
|
||||||
|
// The broadcaster that owns the list of blocked terms.
|
||||||
|
BroadcasterID string `json:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The moderator that blocked the word or phrase from being used in the broadcaster’s chat room.
|
||||||
|
ModeratorID string `json:"moderator_id"`
|
||||||
|
|
||||||
|
// An ID that identifies this blocked term.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// The blocked word or phrase.
|
||||||
|
Text string `json:"text"`
|
||||||
|
|
||||||
|
// The UTC date and time (in RFC3339 format) that the term was blocked.
|
||||||
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
|
||||||
|
// The UTC date and time (in RFC3339 format) that the term was updated.
|
||||||
|
//
|
||||||
|
// When the term is added, this timestamp is the same as created_at.
|
||||||
|
// The timestamp changes as AutoMod continues to deny the term.
|
||||||
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
|
|
||||||
|
// The UTC date and time (in RFC3339 format) that the blocked term is set to expire.
|
||||||
|
// After the block expires, users may use the term in the broadcaster’s chat room.
|
||||||
|
//
|
||||||
|
// This field is null if the term was added manually or was permanently blocked by AutoMod.
|
||||||
|
ExpiresAt *time.Time `json:"expires_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ShieldModeStatus struct {
|
||||||
|
// A Boolean value that determines whether Shield Mode is active. Is true if Shield Mode is active; otherwise, false.
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
|
||||||
|
// An ID that identifies the moderator that last activated Shield Mode.
|
||||||
|
ModeratorID string `json:"moderator_id"`
|
||||||
|
|
||||||
|
// The moderator’s login name.
|
||||||
|
ModeratorLogin string `json:"moderator_login"`
|
||||||
|
|
||||||
|
// The moderator’s display name.
|
||||||
|
ModeratorName string `json:"moderator_name"`
|
||||||
|
|
||||||
|
// The UTC timestamp (in RFC3339 format) of when Shield Mode was last activated.
|
||||||
|
LastActivatedAt time.Time `json:"last_activated_at"`
|
||||||
|
}
|
|
@ -0,0 +1,18 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Moderation struct {
|
||||||
|
client *http.Client
|
||||||
|
baseUrl *url.URL
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(client *http.Client, baseUrl *url.URL) *Moderation {
|
||||||
|
return &Moderation{
|
||||||
|
client: client,
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RemoveBlockedTermParams struct {
|
||||||
|
// The ID of the broadcaster that owns the list of blocked terms.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
|
||||||
|
// The ID of the blocked term to remove from the broadcaster’s list of blocked terms.
|
||||||
|
ID string `url:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes the word or phrase from the broadcaster’s list of blocked terms.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:blocked_terms scope.
|
||||||
|
func (m *Moderation) RemoveBlockedTerm(ctx context.Context, params *RemoveBlockedTermParams) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/blocks", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RemoveChannelModeratorParams struct {
|
||||||
|
// The ID of the broadcaster that owns the chat room. This ID must match the user ID in the access token.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the user to remove as a moderator from the broadcaster’s chat room.
|
||||||
|
UserID string `url:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes a moderator from the broadcaster’s chat room.
|
||||||
|
//
|
||||||
|
// Rate Limits: The broadcaster may remove a maximum of 10 moderators within a 10-second window.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the channel:manage:moderators scope.
|
||||||
|
func (m *Moderation) RemoveChannelModerator(ctx context.Context, params *RemoveChannelModeratorParams) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/moderators", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RemoveChannelVIPParams struct {
|
||||||
|
// The ID of the user to remove VIP status from.
|
||||||
|
UserID string `url:"user_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster who owns the channel where the user has VIP status.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes the specified user as a VIP in the broadcaster’s channel.
|
||||||
|
//
|
||||||
|
// If the broadcaster is removing the user’s VIP status, the ID in the broadcaster_id query parameter must match the user ID in the access token;
|
||||||
|
// otherwise, if the user is removing their VIP status themselves, the ID in the user_id query parameter must match the user ID in the access token.
|
||||||
|
//
|
||||||
|
// Rate Limits: The broadcaster may remove a maximum of 10 VIPs within a 10-second window.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the channel:manage:vips scope.
|
||||||
|
func (m *Moderation) RemoveChannelVIP(ctx context.Context, params *RemoveChannelVIPParams) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "channels/vips", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UnbanUserParams struct {
|
||||||
|
// The ID of the broadcaster whose chat room the user is banned from chatting in.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
|
||||||
|
// The ID of the user to remove the ban or timeout from.
|
||||||
|
UserID string `url:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes the ban or timeout that was placed on the specified user.
|
||||||
|
//
|
||||||
|
// # To ban a user, see Ban user
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:banned_users scope.
|
||||||
|
func (m *Moderation) UnbanUser(ctx context.Context, params *UnbanUserParams) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/bans", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodDelete, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateAutoModSettingsParams struct {
|
||||||
|
// The ID of the broadcaster whose AutoMod settings you want to update.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that has permission to moderate the broadcaster’s chat room.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Because PUT is an overwrite operation, you must include all the fields that you want set after the operation completes.
|
||||||
|
// Typically, you’ll send a GET request, update the fields you want to change, and pass that object in the PUT request.
|
||||||
|
//
|
||||||
|
// You may set either overall_level or the individual settings like aggression, but not both.
|
||||||
|
//
|
||||||
|
// Setting overall_level applies default values to the individual settings.
|
||||||
|
// However, setting overall_level to 4 does not necessarily mean that it applies 4 to all the individual settings.
|
||||||
|
// Instead, it applies a set of recommended defaults to the rest of the settings.
|
||||||
|
// For example, if you set overall_level to 2, Twitch provides some filtering on discrimination and sexual content,
|
||||||
|
// but more filtering on hostility (see the first example response).
|
||||||
|
//
|
||||||
|
// If overall_level is currently set and you update swearing to 3, overall_level will be set to null and all settings other than swearing will be set to 0.
|
||||||
|
// The same is true if individual settings are set and you update overall_level to 3 — all the individual settings are updated to reflect the default level.
|
||||||
|
//
|
||||||
|
// Note that if you set all the individual settings to values that match what overall_level would have set them to,
|
||||||
|
// Twitch changes AutoMod to use the default AutoMod level instead of using the individual settings.
|
||||||
|
//
|
||||||
|
// Valid values for all levels are from 0 (no filtering) through 4 (most aggressive filtering).
|
||||||
|
// These levels affect how aggressively AutoMod holds back messages for moderators to review before they appear in chat or are denied (not shown).
|
||||||
|
type UpdateAutoModSettingsRequest struct {
|
||||||
|
// The Automod level for hostility involving aggression.
|
||||||
|
Aggression int `json:"aggression"`
|
||||||
|
|
||||||
|
// The Automod level for hostility involving name calling or insults.
|
||||||
|
Bullying int `json:"bullying"`
|
||||||
|
|
||||||
|
// The Automod level for discrimination against disability.
|
||||||
|
Disability int `json:"disability"`
|
||||||
|
|
||||||
|
// The Automod level for discrimination against women.
|
||||||
|
Misogyny int `json:"misogyny"`
|
||||||
|
|
||||||
|
// The default AutoMod level for the broadcaster.
|
||||||
|
OverallLevel int `json:"overall_level"`
|
||||||
|
|
||||||
|
// The Automod level for discrimination based on sexuality, sex, or gender.
|
||||||
|
RaceEthnicityOrReligion int `json:"race_ethnicity_or_religion"`
|
||||||
|
|
||||||
|
// The Automod level for sexual content.
|
||||||
|
SexBasedTerms int `json:"sex_based_terms"`
|
||||||
|
|
||||||
|
// The Automod level for discrimination against sexuality, sex, or gender.
|
||||||
|
SexualitySexOrGender int `json:"sexuality_sex_or_gender"`
|
||||||
|
|
||||||
|
// The Automod level for profanity.
|
||||||
|
Swearing int `json:"swearing"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateAutoModSettingsResponse struct {
|
||||||
|
// The list of AutoMod settings. The list contains a single object that contains all the AutoMod settings.
|
||||||
|
Data []AutoModSettings `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the broadcaster’s AutoMod settings.
|
||||||
|
// The settings are used to automatically block inappropriate or harassing messages from appearing in the broadcaster’s chat room.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:automod_settings scope.
|
||||||
|
func (m *Moderation) UpdateAutoModSettings(ctx context.Context, params *UpdateAutoModSettingsParams, body *UpdateAutoModSettingsRequest) (*UpdateAutoModSettingsResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/automod/settings", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
r, w := io.Pipe()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if err := json.NewEncoder(w).Encode(body); err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
} else {
|
||||||
|
w.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.String(), r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data UpdateAutoModSettingsResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package moderation
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateShieldModeStatusParams struct {
|
||||||
|
// The ID of the broadcaster whose Shield Mode you want to activate or deactivate.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or a user that is one of the broadcaster’s moderators. This ID must match the user ID in the access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateShieldModeStatusRequest struct {
|
||||||
|
// A Boolean value that determines whether to activate Shield Mode. Set to true to activate Shield Mode; otherwise, false to deactivate Shield Mode.
|
||||||
|
IsActive bool `json:"is_active"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateShieldModeStatusResponse struct {
|
||||||
|
// A list that contains a single object with the broadcaster’s updated Shield Mode status.
|
||||||
|
Data []ShieldModeStatus `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Activates or deactivates the broadcaster’s Shield Mode.
|
||||||
|
//
|
||||||
|
// Twitch’s Shield Mode feature is like a panic button that broadcasters can push to protect themselves from chat abuse coming from one or more accounts.
|
||||||
|
// When activated, Shield Mode applies the overrides that the broadcaster configured in the Twitch UX.
|
||||||
|
// If the broadcaster hasn’t configured Shield Mode, it applies default overrides.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:shield_mode scope.
|
||||||
|
func (m *Moderation) UpdateShieldModeStatus(ctx context.Context, params *UpdateShieldModeStatusParams) (*UpdateShieldModeStatusResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := m.baseUrl.ResolveReference(&url.URL{Path: "moderation/shield_mode", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
r, w := io.Pipe()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
if err := json.NewEncoder(w).Encode(UpdateShieldModeStatusRequest{IsActive: true}); err != nil {
|
||||||
|
w.CloseWithError(err)
|
||||||
|
} else {
|
||||||
|
w.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPatch, endpoint.String(), r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := m.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data UpdateShieldModeStatusResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
Loading…
Reference in New Issue