2022-10-25 16:47:30 +00:00
|
|
|
package twitch
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"context"
|
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
2023-05-11 12:42:32 +00:00
|
|
|
"strings"
|
2022-10-25 16:47:30 +00:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
)
|
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
// AddChannelVIP adds the given user as a VIP in the given channel
|
|
|
|
func (c *Client) AddChannelVIP(ctx context.Context, channel, userName string) error {
|
|
|
|
broadcaster, err := c.GetIDForUsername(ctx, channel)
|
2022-12-05 17:58:10 +00:00
|
|
|
if err != nil {
|
2024-01-01 16:52:18 +00:00
|
|
|
return errors.Wrap(err, "getting ID for channel name")
|
2022-12-05 17:58:10 +00:00
|
|
|
}
|
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
userID, err := c.GetIDForUsername(ctx, userName)
|
2022-12-05 17:58:10 +00:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "getting ID for user name")
|
|
|
|
}
|
|
|
|
|
|
|
|
return errors.Wrap(
|
2024-01-01 16:52:18 +00:00
|
|
|
c.Request(ctx, ClientRequestOpts{
|
2023-07-01 14:48:21 +00:00
|
|
|
AuthType: AuthTypeBearerToken,
|
2022-12-05 17:58:10 +00:00
|
|
|
Method: http.MethodPost,
|
|
|
|
OKStatus: http.StatusNoContent,
|
|
|
|
URL: fmt.Sprintf("https://api.twitch.tv/helix/channels/vips?broadcaster_id=%s&user_id=%s", broadcaster, userID),
|
|
|
|
}),
|
|
|
|
"executing request",
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
// ModifyChannelInformation adjusts category and title for the given
|
|
|
|
// channel
|
|
|
|
func (c *Client) ModifyChannelInformation(ctx context.Context, channel string, category, title *string) error {
|
|
|
|
if category == nil && title == nil {
|
2022-10-25 16:47:30 +00:00
|
|
|
return errors.New("netiher game nor title provided")
|
|
|
|
}
|
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
broadcaster, err := c.GetIDForUsername(ctx, channel)
|
2022-10-25 16:47:30 +00:00
|
|
|
if err != nil {
|
2024-01-01 16:52:18 +00:00
|
|
|
return errors.Wrap(err, "getting ID for channel name")
|
2022-10-25 16:47:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
data := struct {
|
|
|
|
GameID *string `json:"game_id,omitempty"`
|
|
|
|
Title *string `json:"title,omitempty"`
|
|
|
|
}{
|
|
|
|
Title: title,
|
|
|
|
}
|
|
|
|
|
|
|
|
switch {
|
2024-01-01 16:52:18 +00:00
|
|
|
case category == nil:
|
2022-10-25 16:47:30 +00:00
|
|
|
// We don't set the GameID
|
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
case (*category)[0] == '@':
|
2022-10-25 16:47:30 +00:00
|
|
|
// We got an ID and don't need to resolve
|
2024-01-01 16:52:18 +00:00
|
|
|
gameID := (*category)[1:]
|
2022-10-25 16:47:30 +00:00
|
|
|
data.GameID = &gameID
|
|
|
|
|
|
|
|
default:
|
2024-01-01 16:52:18 +00:00
|
|
|
categories, err := c.SearchCategories(ctx, *category)
|
2022-10-25 16:47:30 +00:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "searching for game")
|
|
|
|
}
|
|
|
|
|
|
|
|
switch len(categories) {
|
|
|
|
case 0:
|
|
|
|
return errors.New("no matching game found")
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
data.GameID = &categories[0].ID
|
|
|
|
|
|
|
|
default:
|
|
|
|
// Multiple matches: Search for exact one
|
|
|
|
for _, c := range categories {
|
2024-01-01 16:52:18 +00:00
|
|
|
if strings.EqualFold(c.Name, *category) {
|
2022-10-25 16:47:30 +00:00
|
|
|
gid := c.ID
|
|
|
|
data.GameID = &gid
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if data.GameID == nil {
|
|
|
|
// No exact match found: This is an error
|
|
|
|
return errors.New("no exact game match found")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
body := new(bytes.Buffer)
|
|
|
|
if err := json.NewEncoder(body).Encode(data); err != nil {
|
|
|
|
return errors.Wrap(err, "encoding payload")
|
|
|
|
}
|
|
|
|
|
|
|
|
return errors.Wrap(
|
2024-01-01 16:52:18 +00:00
|
|
|
c.Request(ctx, ClientRequestOpts{
|
2023-07-01 14:48:21 +00:00
|
|
|
AuthType: AuthTypeBearerToken,
|
2022-10-25 16:47:30 +00:00
|
|
|
Body: body,
|
|
|
|
Method: http.MethodPatch,
|
|
|
|
OKStatus: http.StatusNoContent,
|
|
|
|
URL: fmt.Sprintf("https://api.twitch.tv/helix/channels?broadcaster_id=%s", broadcaster),
|
|
|
|
}),
|
|
|
|
"executing request",
|
|
|
|
)
|
|
|
|
}
|
2022-12-05 17:58:10 +00:00
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
// RemoveChannelVIP removes the given user as a VIP in the given channel
|
|
|
|
func (c *Client) RemoveChannelVIP(ctx context.Context, channel, userName string) error {
|
|
|
|
broadcaster, err := c.GetIDForUsername(ctx, channel)
|
2022-12-05 17:58:10 +00:00
|
|
|
if err != nil {
|
2024-01-01 16:52:18 +00:00
|
|
|
return errors.Wrap(err, "getting ID for channel name")
|
2022-12-05 17:58:10 +00:00
|
|
|
}
|
|
|
|
|
2024-01-01 16:52:18 +00:00
|
|
|
userID, err := c.GetIDForUsername(ctx, userName)
|
2022-12-05 17:58:10 +00:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "getting ID for user name")
|
|
|
|
}
|
|
|
|
|
|
|
|
return errors.Wrap(
|
2024-01-01 16:52:18 +00:00
|
|
|
c.Request(ctx, ClientRequestOpts{
|
2023-07-01 14:48:21 +00:00
|
|
|
AuthType: AuthTypeBearerToken,
|
2022-12-05 17:58:10 +00:00
|
|
|
Method: http.MethodDelete,
|
|
|
|
OKStatus: http.StatusNoContent,
|
|
|
|
URL: fmt.Sprintf("https://api.twitch.tv/helix/channels/vips?broadcaster_id=%s&user_id=%s", broadcaster, userID),
|
|
|
|
}),
|
|
|
|
"executing request",
|
|
|
|
)
|
|
|
|
}
|
2023-03-14 14:34:08 +00:00
|
|
|
|
|
|
|
// RunCommercial starts a commercial on the specified channel
|
|
|
|
func (c *Client) RunCommercial(ctx context.Context, channel string, duration int64) error {
|
2024-01-01 16:52:18 +00:00
|
|
|
channelID, err := c.GetIDForUsername(ctx, channel)
|
2023-03-14 14:34:08 +00:00
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "getting ID for channel name")
|
|
|
|
}
|
|
|
|
|
|
|
|
payload := struct {
|
|
|
|
BroadcasterID string `json:"broadcaster_id"`
|
|
|
|
Length int64 `json:"length"`
|
|
|
|
}{
|
|
|
|
BroadcasterID: channelID,
|
|
|
|
Length: duration,
|
|
|
|
}
|
|
|
|
|
|
|
|
body := new(bytes.Buffer)
|
|
|
|
if err := json.NewEncoder(body).Encode(payload); err != nil {
|
|
|
|
return errors.Wrap(err, "encoding payload")
|
|
|
|
}
|
|
|
|
|
|
|
|
return errors.Wrap(
|
2024-01-01 16:52:18 +00:00
|
|
|
c.Request(ctx, ClientRequestOpts{
|
2023-07-01 14:48:21 +00:00
|
|
|
AuthType: AuthTypeBearerToken,
|
2023-03-14 14:34:08 +00:00
|
|
|
Body: body,
|
|
|
|
Method: http.MethodPost,
|
|
|
|
OKStatus: http.StatusOK,
|
|
|
|
URL: "https://api.twitch.tv/helix/channels/commercial",
|
|
|
|
}),
|
|
|
|
"executing request",
|
|
|
|
)
|
|
|
|
}
|