Add chat endpoints to API
This commit is contained in:
parent
616cb935a0
commit
990b1da80c
|
@ -10,6 +10,7 @@ import (
|
||||||
"go.fifitido.net/twitch/api/channelpoints"
|
"go.fifitido.net/twitch/api/channelpoints"
|
||||||
"go.fifitido.net/twitch/api/channels"
|
"go.fifitido.net/twitch/api/channels"
|
||||||
"go.fifitido.net/twitch/api/charity"
|
"go.fifitido.net/twitch/api/charity"
|
||||||
|
"go.fifitido.net/twitch/api/chat"
|
||||||
"go.fifitido.net/twitch/api/eventsub"
|
"go.fifitido.net/twitch/api/eventsub"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -25,6 +26,7 @@ type API struct {
|
||||||
Channels *channels.Channels
|
Channels *channels.Channels
|
||||||
ChannelPoints *channelpoints.ChannelPoints
|
ChannelPoints *channelpoints.ChannelPoints
|
||||||
Charity *charity.Charity
|
Charity *charity.Charity
|
||||||
|
Chat *chat.Chat
|
||||||
EventSub *eventsub.EventSub
|
EventSub *eventsub.EventSub
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +44,7 @@ func New() *API {
|
||||||
Channels: channels.New(client, baseUrl),
|
Channels: channels.New(client, baseUrl),
|
||||||
ChannelPoints: channelpoints.New(client, baseUrl),
|
ChannelPoints: channelpoints.New(client, baseUrl),
|
||||||
Charity: charity.New(client, baseUrl),
|
Charity: charity.New(client, baseUrl),
|
||||||
|
Chat: chat.New(client, baseUrl),
|
||||||
EventSub: eventsub.New(client, baseUrl),
|
EventSub: eventsub.New(client, baseUrl),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Chat struct {
|
||||||
|
client *http.Client
|
||||||
|
baseUrl *url.URL
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(client *http.Client, baseUrl *url.URL) *Chat {
|
||||||
|
return &Chat{
|
||||||
|
client: client,
|
||||||
|
baseUrl: baseUrl,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetChannelChatBadgesResponse struct {
|
||||||
|
// The list of chat badges. The list is sorted in ascending order by set_id, and within a set, the list is sorted in ascending order by id.
|
||||||
|
Data []Badge `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the broadcaster’s list of custom chat badges. The list is empty if the broadcaster hasn’t created custom chat badges.
|
||||||
|
// For information about custom badges,
|
||||||
|
// see subscriber badges: https://help.twitch.tv/s/article/subscriber-badge-guide
|
||||||
|
// and Bits badges: https://help.twitch.tv/s/article/custom-bit-badges-guide.
|
||||||
|
//
|
||||||
|
// Requires an app access token or user access token.
|
||||||
|
func (c *Chat) GetChannelChatBadges(ctx context.Context, broadcasterID string) (*GetChannelChatBadgesResponse, error) {
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/badges", RawQuery: "broadcaster_id=" + broadcasterID})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, 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 GetChannelChatBadgesResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetChannelEmotesResponse struct {
|
||||||
|
// The list of emotes that the specified broadcaster created.
|
||||||
|
// If the broadcaster hasn't created custom emotes, the list is empty.
|
||||||
|
Data []ChannelEmote `json:"data"`
|
||||||
|
|
||||||
|
// A templated URL. Use the values from the id, format, scale, and theme_mode fields to replace the like-named placeholder strings
|
||||||
|
// in the templated URL to create a CDN (content delivery network) URL that you use to fetch the emote.
|
||||||
|
// For information about what the template looks like and how to use it to fetch emotes.
|
||||||
|
// See Emote CDN URL format: https://dev.twitch.tv/docs/irc/emotes#cdn-template
|
||||||
|
// You should use this template instead of using the URLs in the images object.
|
||||||
|
Template string `json:"template"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ChannelEmote struct {
|
||||||
|
// An ID that identifies this emote.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// The name of the emote. This is the name that viewers type in the chat window to get the emote to appear.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// The image URLs for the emote. These image URLs always provide a static, non-animated emote image with a light background.
|
||||||
|
//
|
||||||
|
// NOTE: You should use the templated URL in the template field to fetch the image instead of using these URLs.
|
||||||
|
Images EmoteImages `json:"images"`
|
||||||
|
|
||||||
|
// The subscriber tier at which the emote is unlocked.
|
||||||
|
// This field contains the tier information only if emote_type is set to subscriptions, otherwise, it's an empty string.
|
||||||
|
Tier string `json:"tier"`
|
||||||
|
|
||||||
|
// The type of emote. The possible values are:
|
||||||
|
//
|
||||||
|
// bitstier — A custom Bits tier emote.
|
||||||
|
//
|
||||||
|
// follower — A custom follower emote.
|
||||||
|
//
|
||||||
|
// subscriptions — A custom subscriber emote.
|
||||||
|
EmoteType string `json:"emote_type"`
|
||||||
|
|
||||||
|
// An ID that identifies the emote set that the emote belongs to.
|
||||||
|
EmoteSetID string `json:"emote_set_id"`
|
||||||
|
|
||||||
|
// The formats that the emote is available in.
|
||||||
|
// For example, if the emote is available only as a static PNG, the array contains only static.
|
||||||
|
// But if the emote is available as a static PNG and an animated GIF, the array contains static and animated.
|
||||||
|
// The possible formats are:
|
||||||
|
//
|
||||||
|
// animated — An animated GIF is available for this emote.
|
||||||
|
//
|
||||||
|
// static — A static PNG file is available for this emote.
|
||||||
|
Formats []EmoteFormat `json:"format"`
|
||||||
|
|
||||||
|
// The sizes that the emote is available in.
|
||||||
|
// For example, if the emote is available in small and medium sizes, the array contains 1.0 and 2.0.
|
||||||
|
// Possible sizes are:
|
||||||
|
//
|
||||||
|
// 1.0 — A small version (28px x 28px) is available.
|
||||||
|
//
|
||||||
|
// 2.0 — A medium version (56px x 56px) is available.
|
||||||
|
//
|
||||||
|
// 3.0 — A large version (112px x 112px) is available.
|
||||||
|
Scales []EmoteScale `json:"scale"`
|
||||||
|
|
||||||
|
// The background themes that the emote is available in. Possible themes are:
|
||||||
|
//
|
||||||
|
// dark, light
|
||||||
|
ThemeMode []EmoteThemeMode `json:"theme_mode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the broadcaster’s list of custom emotes.
|
||||||
|
// Broadcasters create these custom emotes for users who subscribe to or follow the channel or cheer Bits in the channel’s chat window.
|
||||||
|
// Learn More: https://dev.twitch.tv/docs/irc/emotes
|
||||||
|
//
|
||||||
|
// For information about the custom emotes
|
||||||
|
// see subscriber emotes: https://help.twitch.tv/s/article/subscriber-emote-guide,
|
||||||
|
// Bits tier emotes: https://help.twitch.tv/s/article/custom-bit-badges-guide?language=bg#slots,
|
||||||
|
// and follower emotes: https://blog.twitch.tv/en/2021/06/04/kicking-off-10-years-with-our-biggest-emote-update-ever/
|
||||||
|
//
|
||||||
|
// NOTE: With the exception of custom follower emotes, users may use custom emotes in any Twitch chat.
|
||||||
|
//
|
||||||
|
// Requires an app access token or user access token.
|
||||||
|
func (c *Chat) GetChannelEmotes(ctx context.Context, broadcasterID string) (*GetChannelEmotesResponse, error) {
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/emotes", RawQuery: "broadcaster_id=" + broadcasterID})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var response GetChannelEmotesResponse
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetChatSettingsParams struct {
|
||||||
|
// The ID of the broadcaster whose chat settings you want to get.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or one of the broadcaster’s moderators.
|
||||||
|
//
|
||||||
|
// This field is required only if you want to include the non_moderator_chat_delay and non_moderator_chat_delay_duration settings in the response.
|
||||||
|
//
|
||||||
|
// If you specify this field, this ID must match the user ID in the user access token.
|
||||||
|
ModeratorID *string `url:"moderator_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetChatSettingsResponse struct {
|
||||||
|
// The list of chat settings. The list contains a single object with all the settings.
|
||||||
|
Data []Settings `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the broadcaster’s chat settings.
|
||||||
|
//
|
||||||
|
// For an overview of chat settings,
|
||||||
|
// see Chat Commands for Broadcasters and Moderators: https://help.twitch.tv/s/article/chat-commands#AllMods
|
||||||
|
// and Moderator Preferences: https://help.twitch.tv/s/article/setting-up-moderation-for-your-twitch-channel#modpreferences
|
||||||
|
//
|
||||||
|
// Requires an app access token or user access token.
|
||||||
|
func (c *Chat) GetChatSettings(ctx context.Context, params *GetChatSettingsParams) (*GetChatSettingsResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/settings", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, 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 GetChatSettingsResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,84 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
"go.fifitido.net/twitch/api/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetChattersParams struct {
|
||||||
|
// The ID of the broadcaster whose list of chatters you want to get.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster or one of the broadcaster’s moderators.
|
||||||
|
// 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 1,000.
|
||||||
|
// The default is 100.
|
||||||
|
First *int `url:"first,omitempty"`
|
||||||
|
|
||||||
|
// 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,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetChattersResponse struct {
|
||||||
|
// The list of users that are connected to the broadcaster’s chat room.
|
||||||
|
// The list is empty if no users are connected to the chat room.
|
||||||
|
Data []Chatter `json:"data"`
|
||||||
|
|
||||||
|
// Contains the information used to page through the list of results. The object is empty if there are no more pages left to page through.
|
||||||
|
// Read more: https://dev.twitch.tv/docs/api/guide#pagination
|
||||||
|
Pagination types.Pagination `json:"pagination"`
|
||||||
|
|
||||||
|
// The total number of users that are connected to the broadcaster’s chat room.
|
||||||
|
// As you page through the list, the number of users may change as users join and leave the chat room.
|
||||||
|
Total int `json:"total"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Chatter struct {
|
||||||
|
// The ID of a user that’s connected to the broadcaster’s chat room.
|
||||||
|
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 the list of users that are connected to the broadcaster’s chat session.
|
||||||
|
//
|
||||||
|
// NOTE: There is a delay between when users join and leave a chat and when the list is updated accordingly.
|
||||||
|
//
|
||||||
|
// To determine whether a user is a moderator or VIP, use the Get Moderators and Get VIPs endpoints. You can check the roles of up to 100 users.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:read:chatters scope.
|
||||||
|
func (c *Chat) GetChatters(ctx context.Context, params *GetChattersParams) (*GetChattersResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/chatters", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
var response GetChattersResponse
|
||||||
|
if err := json.NewDecoder(resp.Body).Decode(&response); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &response, nil
|
||||||
|
}
|
|
@ -0,0 +1,116 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetEmoteSetsParams struct {
|
||||||
|
// An ID that identifies the emote set to get. Include this parameter for each emote set you want to get.
|
||||||
|
// For example, emote_set_id=1234&emote_set_id=5678. You may specify a maximum of 25 IDs.
|
||||||
|
// The response contains only the IDs that were found and ignores duplicate IDs.
|
||||||
|
//
|
||||||
|
// To get emote set IDs, use the Get Channel Emotes API.
|
||||||
|
EmoteSetIDs []string `url:"emote_set_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetEmoteSetsResponse struct {
|
||||||
|
// The list of emotes found in the specified emote sets. The list is empty if none of the IDs were found.
|
||||||
|
// The list is in the same order as the set IDs specified in the request. Each set contains one or more emoticons.
|
||||||
|
Data []EmoteSetEmote `json:"data"`
|
||||||
|
|
||||||
|
// A templated URL. Use the values from the id, format, scale, and theme_mode fields to replace the like-named placeholder strings
|
||||||
|
// in the templated URL to create a CDN (content delivery network) URL that you use to fetch the emote.
|
||||||
|
// For information about what the template looks like and how to use it to fetch emotes.
|
||||||
|
// See Emote CDN URL format: https://dev.twitch.tv/docs/irc/emotes#cdn-template
|
||||||
|
// You should use this template instead of using the URLs in the images object.
|
||||||
|
Template string `json:"template"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmoteSetEmote struct {
|
||||||
|
// An ID that identifies this emote.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// The name of the emote. This is the name that viewers type in the chat window to get the emote to appear.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// The image URLs for the emote. These image URLs always provide a static, non-animated emote image with a light background.
|
||||||
|
//
|
||||||
|
// NOTE: You should use the templated URL in the template field to fetch the image instead of using these URLs.
|
||||||
|
Images EmoteImages `json:"images"`
|
||||||
|
|
||||||
|
// The type of emote. The possible values are:
|
||||||
|
//
|
||||||
|
// bitstier — A custom Bits tier emote.
|
||||||
|
//
|
||||||
|
// follower — A custom follower emote.
|
||||||
|
//
|
||||||
|
// subscriptions — A custom subscriber emote.
|
||||||
|
EmoteType string `json:"emote_type"`
|
||||||
|
|
||||||
|
// An ID that identifies the emote set that the emote belongs to.
|
||||||
|
EmoteSetID string `json:"emote_set_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster who owns the emote.
|
||||||
|
OwnerID string `json:"owner_id"`
|
||||||
|
|
||||||
|
// The formats that the emote is available in.
|
||||||
|
// For example, if the emote is available only as a static PNG, the array contains only static.
|
||||||
|
// But if the emote is available as a static PNG and an animated GIF, the array contains static and animated.
|
||||||
|
// The possible formats are:
|
||||||
|
//
|
||||||
|
// animated — An animated GIF is available for this emote.
|
||||||
|
//
|
||||||
|
// static — A static PNG file is available for this emote.
|
||||||
|
Formats []EmoteFormat `json:"format"`
|
||||||
|
|
||||||
|
// The sizes that the emote is available in.
|
||||||
|
// For example, if the emote is available in small and medium sizes, the array contains 1.0 and 2.0.
|
||||||
|
// Possible sizes are:
|
||||||
|
//
|
||||||
|
// 1.0 — A small version (28px x 28px) is available.
|
||||||
|
//
|
||||||
|
// 2.0 — A medium version (56px x 56px) is available.
|
||||||
|
//
|
||||||
|
// 3.0 — A large version (112px x 112px) is available.
|
||||||
|
Scales []EmoteScale `json:"scale"`
|
||||||
|
|
||||||
|
// The background themes that the emote is available in. Possible themes are:
|
||||||
|
//
|
||||||
|
// dark, light
|
||||||
|
ThemeMode []EmoteThemeMode `json:"theme_mode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets emotes for one or more specified emote sets.
|
||||||
|
//
|
||||||
|
// An emote set groups emotes that have a similar context. For example, Twitch places all the subscriber emotes that a broadcaster uploads for their channel in the same emote set.
|
||||||
|
//
|
||||||
|
// Learn More: https://dev.twitch.tv/docs/irc/emotes
|
||||||
|
//
|
||||||
|
// Requires an app access token or user access token.
|
||||||
|
func (c *Chat) GetEmoteSets(ctx context.Context, params *GetEmoteSetsParams) (*GetEmoteSetsResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/emotes/set", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, 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 GetEmoteSetsResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetGlobalChatBadgesResponse struct {
|
||||||
|
// The list of chat badges. The list is sorted in ascending order by set_id, and within a set, the list is sorted in ascending order by id.
|
||||||
|
Data []Badge `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets Twitch’s list of chat badges, which users may use in any channel’s chat room.
|
||||||
|
// For information about chat badges, see Twitch Chat Badges Guide: https://help.twitch.tv/s/article/twitch-chat-badges-guide
|
||||||
|
//
|
||||||
|
// Requires an app access token or user access token.
|
||||||
|
func (c *Chat) GetGlobalChatBadges(ctx context.Context) (*GetGlobalChatBadgesResponse, error) {
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/badges/global"})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, 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 GetGlobalChatBadgesResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetGlobalEmotesResponse struct {
|
||||||
|
// The list of global emotes.
|
||||||
|
Data []GlobalEmote `json:"data"`
|
||||||
|
|
||||||
|
// A templated URL. Use the values from the id, format, scale, and theme_mode fields to replace the like-named placeholder strings
|
||||||
|
// in the templated URL to create a CDN (content delivery network) URL that you use to fetch the emote.
|
||||||
|
// For information about what the template looks like and how to use it to fetch emotes.
|
||||||
|
// See Emote CDN URL format: https://dev.twitch.tv/docs/irc/emotes#cdn-template
|
||||||
|
// You should use this template instead of using the URLs in the images object.
|
||||||
|
Template string `json:"template"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GlobalEmote struct {
|
||||||
|
// An ID that identifies this emote.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// The name of the emote. This is the name that viewers type in the chat window to get the emote to appear.
|
||||||
|
Name string `json:"name"`
|
||||||
|
|
||||||
|
// The image URLs for the emote. These image URLs always provide a static, non-animated emote image with a light background.
|
||||||
|
//
|
||||||
|
// NOTE: You should use the templated URL in the template field to fetch the image instead of using these URLs.
|
||||||
|
Images EmoteImages `json:"images"`
|
||||||
|
|
||||||
|
// The formats that the emote is available in.
|
||||||
|
// For example, if the emote is available only as a static PNG, the array contains only static.
|
||||||
|
// But if the emote is available as a static PNG and an animated GIF, the array contains static and animated.
|
||||||
|
// The possible formats are:
|
||||||
|
//
|
||||||
|
// animated — An animated GIF is available for this emote.
|
||||||
|
//
|
||||||
|
// static — A static PNG file is available for this emote.
|
||||||
|
Formats []EmoteFormat `json:"format"`
|
||||||
|
|
||||||
|
// The sizes that the emote is available in.
|
||||||
|
// For example, if the emote is available in small and medium sizes, the array contains 1.0 and 2.0.
|
||||||
|
// Possible sizes are:
|
||||||
|
//
|
||||||
|
// 1.0 — A small version (28px x 28px) is available.
|
||||||
|
//
|
||||||
|
// 2.0 — A medium version (56px x 56px) is available.
|
||||||
|
//
|
||||||
|
// 3.0 — A large version (112px x 112px) is available.
|
||||||
|
Scales []EmoteScale `json:"scale"`
|
||||||
|
|
||||||
|
// The background themes that the emote is available in. Possible themes are:
|
||||||
|
//
|
||||||
|
// dark, light
|
||||||
|
ThemeMode []EmoteThemeMode `json:"theme_mode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the list of global emotes. Global emotes are Twitch-created emotes that users can use in any Twitch chat.
|
||||||
|
//
|
||||||
|
// Learn More: https://dev.twitch.tv/docs/irc/emotes
|
||||||
|
//
|
||||||
|
// Requires an app access token or user access token.
|
||||||
|
func (c *Chat) GetGlobalEmotes(ctx context.Context) (*GetGlobalEmotesResponse, error) {
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/emotes/global"})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, 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 GetGlobalEmotesResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetUserChatColorParams struct {
|
||||||
|
// The ID of the user whose username color you want to get.
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
// The API ignores duplicate IDs and IDs that weren’t found.
|
||||||
|
UserIDs []string `url:"user_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetUserChatColorResponse struct {
|
||||||
|
// The list of users and the color code they use for their name.
|
||||||
|
Data []UserChatColor `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserChatColor struct {
|
||||||
|
// An ID that uniquely identifies the user.
|
||||||
|
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"`
|
||||||
|
|
||||||
|
// The Hex color code that the user uses in chat for their name.
|
||||||
|
// If the user hasn’t specified a color in their settings, the string is empty.
|
||||||
|
Color string `json:"color"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gets the color used for the user’s name in chat.
|
||||||
|
//
|
||||||
|
// Requires an app access token or user access token.
|
||||||
|
func (c *Chat) GetUserChatColor(ctx context.Context, params *GetUserChatColorParams) (*GetUserChatColorResponse, error) {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/color", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodGet, 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 GetUserChatColorResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
type EmoteImages struct {
|
||||||
|
// A URL to the small version (28px x 28px) of the emote.
|
||||||
|
URL1x string `json:"url_1x"`
|
||||||
|
|
||||||
|
// A URL to the medium version (56px x 56px) of the emote.
|
||||||
|
URL2x string `json:"url_2x"`
|
||||||
|
|
||||||
|
// A URL to the large version (112px x 112px) of the emote.
|
||||||
|
URL4x string `json:"url_4x"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type EmoteFormat string
|
||||||
|
|
||||||
|
const (
|
||||||
|
EmoteFormatStatic EmoteFormat = "static"
|
||||||
|
EmoteFormatAnimated EmoteFormat = "animated"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EmoteScale string
|
||||||
|
|
||||||
|
const (
|
||||||
|
// 1.0 — A small version (28px x 28px) is available.
|
||||||
|
EmoteScale1 EmoteScale = "1.0"
|
||||||
|
|
||||||
|
// 2.0 — A medium version (56px x 56px) is available.
|
||||||
|
EmoteScale2 EmoteScale = "2x"
|
||||||
|
|
||||||
|
// 3.0 — A large version (112px x 112px) is available.
|
||||||
|
EmoteScale4 EmoteScale = "4x"
|
||||||
|
)
|
||||||
|
|
||||||
|
type EmoteThemeMode string
|
||||||
|
|
||||||
|
const (
|
||||||
|
EmoteThemeModeDark EmoteThemeMode = "dark"
|
||||||
|
EmoteThemeModeLight EmoteThemeMode = "light"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Badge struct {
|
||||||
|
// An ID that identifies this set of chat badges. For example, Bits or Subscriber.
|
||||||
|
SetID string `json:"set_id"`
|
||||||
|
|
||||||
|
// The list of chat badges in this set.
|
||||||
|
Versions []BadgeVersion `json:"versions"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BadgeVersion struct {
|
||||||
|
// An ID that identifies this version of the badge. The ID can be any value.
|
||||||
|
// For example, for Bits, the ID is the Bits tier level, but for World of Warcraft, it could be Alliance or Horde.
|
||||||
|
ID string `json:"id"`
|
||||||
|
|
||||||
|
// A URL to the small version (18px x 18px) of the badge.
|
||||||
|
ImageURL1x string `json:"image_url_1x"`
|
||||||
|
|
||||||
|
// A URL to the medium version (36px x 36px) of the badge.
|
||||||
|
ImageURL2x string `json:"image_url_2x"`
|
||||||
|
|
||||||
|
// A URL to the large version (72px x 72px) of the badge.
|
||||||
|
ImageURL4x string `json:"image_url_4x"`
|
||||||
|
|
||||||
|
// The title of the badge.
|
||||||
|
Title string `json:"title"`
|
||||||
|
|
||||||
|
// The description of the badge.
|
||||||
|
Description string `json:"description"`
|
||||||
|
|
||||||
|
// The action to take when clicking on the badge. Set to null if no action is specified.
|
||||||
|
ClickAction *string `json:"click_action"`
|
||||||
|
|
||||||
|
// The URL to navigate to when clicking on the badge. Set to null if no URL is specified.
|
||||||
|
ClickURL *string `json:"click_url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Settings struct {
|
||||||
|
// The ID of the broadcaster specified in the request.
|
||||||
|
BroadcasterID string `json:"broadcaster_id"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether chat messages must contain only emotes. Is true if chat messages may contain only emotes; otherwise, false.
|
||||||
|
EmoteMode bool `json:"emote_mode"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether the broadcaster restricts the chat room to followers only.
|
||||||
|
//
|
||||||
|
// Is true if the broadcaster restricts the chat room to followers only; otherwise, false.
|
||||||
|
//
|
||||||
|
// See the follower_mode_duration field for how long users must follow the broadcaster before being able to participate in the chat room.
|
||||||
|
FollowerMode bool `json:"follower_mode"`
|
||||||
|
|
||||||
|
// The length of time, in minutes, that users must follow the broadcaster before being able to participate in the chat room.
|
||||||
|
// Is null if follower_mode is false.
|
||||||
|
FollowerModeDuration *int `json:"follower_mode_duration"`
|
||||||
|
|
||||||
|
// The moderator’s ID.
|
||||||
|
// The response includes this field only if the request specifies a user access token that includes the moderator:read:chat_settings scope.
|
||||||
|
ModeratorID *string `json:"moderator_id"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether the broadcaster adds a short delay before chat messages appear in the chat room.
|
||||||
|
// This gives chat moderators and bots a chance to remove them before viewers can see the message.
|
||||||
|
// See the non_moderator_chat_delay_duration field for the length of the delay.
|
||||||
|
// Is true if the broadcaster applies a delay; otherwise, false.
|
||||||
|
//
|
||||||
|
// The response includes this field only if the request specifies a user access token that includes the moderator:read:chat_settings
|
||||||
|
// scope and the user in the moderator_id query parameter is one of the broadcaster’s moderators.
|
||||||
|
NonModeratorChatDelay *bool `json:"non_moderator_chat_delay"`
|
||||||
|
|
||||||
|
// The amount of time, in seconds, that messages are delayed before appearing in chat. Is null if non_moderator_chat_delay is false.
|
||||||
|
//
|
||||||
|
// The response includes this field only if the request specifies a user access token that includes the moderator:read:chat_settings
|
||||||
|
// scope and the user in the moderator_id query parameter is one of the broadcaster’s moderators.
|
||||||
|
NonModeratorChatDelayDuration *int `json:"non_moderator_chat_delay_duration"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether the broadcaster limits how often users in the chat room are allowed to send messages.
|
||||||
|
//
|
||||||
|
// Is true if the broadcaster applies a delay; otherwise, false.
|
||||||
|
//
|
||||||
|
// See the slow_mode_wait_time field for the delay.
|
||||||
|
SlowMode bool `json:"slow_mode"`
|
||||||
|
|
||||||
|
// The amount of time, in seconds, that users must wait between sending messages.
|
||||||
|
//
|
||||||
|
// Is null if slow_mode is false.
|
||||||
|
SlowModeWaitTime *int `json:"slow_mode_wait_time"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether only users that subscribe to the broadcaster’s channel may talk in the chat room.
|
||||||
|
//
|
||||||
|
// Is true if the broadcaster restricts the chat room to subscribers only; otherwise, false.
|
||||||
|
SubscriberMode bool `json:"subscriber_mode"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether the broadcaster requires users to post only unique messages in the chat room.
|
||||||
|
//
|
||||||
|
// Is true if the broadcaster requires unique messages only; otherwise, false.
|
||||||
|
UniqueChatMode bool `json:"unique_chat_mode"`
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
"go.fifitido.net/twitch/api/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SendChatAnnouncementParams struct {
|
||||||
|
// The ID of the broadcaster that owns the chat room to send the announcement to.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of a user who has permission to moderate the broadcaster’s chat room, or the broadcaster’s ID if they’re sending the announcement.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SendChatAnnouncementRequest struct {
|
||||||
|
// The announcement to make in the broadcaster’s chat room.
|
||||||
|
// Announcements are limited to a maximum of 500 characters; announcements longer than 500 characters are truncated.
|
||||||
|
Message string `json:"message"`
|
||||||
|
|
||||||
|
// The color used to highlight the announcement. Possible case-sensitive values are:
|
||||||
|
//
|
||||||
|
// If color is set to primary or is not set, the channel’s accent color is used to highlight the announcement
|
||||||
|
// (see Profile Accent Color under profile settings, Channel and Videos, and Brand).
|
||||||
|
Color *types.AccentColor `json:"color"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sends an announcement to the broadcaster’s chat room.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:announcements scope.
|
||||||
|
func (c *Chat) SendChatAnnouncement(ctx context.Context, params *SendChatAnnouncementParams, body *SendChatAnnouncementRequest) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/announcements", 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 err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SendChatMessageRequest struct {
|
||||||
|
// The ID of the broadcaster whose chat room the message will be sent to.
|
||||||
|
BroadcasterID string `json:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the user sending the message. This ID must match the user ID in the user access token.
|
||||||
|
SenderID string `json:"sender_id"`
|
||||||
|
|
||||||
|
// The message to send. The message is limited to a maximum of 500 characters. Chat messages can also include emoticons.
|
||||||
|
// To include emoticons, use the name of the emote. The names are case sensitive. Don’t include colons around the name (e.g., :bleedPurple:).
|
||||||
|
// If Twitch recognizes the name, Twitch converts the name to the emote before writing the chat message to the chat room
|
||||||
|
Message string `json:"message"`
|
||||||
|
|
||||||
|
// The ID of the chat message being replied to.
|
||||||
|
ReplyParentMessageID *string `json:"reply_parent_message_id,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SendChatMessageResponse struct {
|
||||||
|
Data []SendChatMessageData `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type SendChatMessageData struct {
|
||||||
|
// The message id for the message that was sent.
|
||||||
|
MessageID string `json:"message_id"`
|
||||||
|
|
||||||
|
// If the message passed all checks and was sent
|
||||||
|
IsSent bool `json:"is_sent"`
|
||||||
|
|
||||||
|
// The reason the message was dropped, if any.
|
||||||
|
DropReason []DropReason `json:"drop_reason,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DropReason struct {
|
||||||
|
// Code for why the message was dropped.
|
||||||
|
Code string `json:"code"`
|
||||||
|
|
||||||
|
// Message for why the message was dropped.
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sends a message to the broadcaster’s chat room.
|
||||||
|
//
|
||||||
|
// Requires an app access token or user access token that includes the user:write:chat scope.
|
||||||
|
// If app access token used, then additionally requires user:bot scope from chatting user,
|
||||||
|
// and either channel:bot scope from broadcaster or moderator status.
|
||||||
|
func (c *Chat) SendChatMessage(ctx context.Context, body *SendChatMessageRequest) (*SendChatMessageResponse, error) {
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/messages"})
|
||||||
|
|
||||||
|
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 := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data SendChatMessageResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type SendShoutoutParams struct {
|
||||||
|
// The ID of the broadcaster that’s sending the Shoutout.
|
||||||
|
FromBroadcasterID string `url:"from_broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of the broadcaster that’s receiving the Shoutout.
|
||||||
|
ToBroadcasterID string `url:"to_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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sends a Shoutout to the specified broadcaster.
|
||||||
|
// Typically, you send Shoutouts when you or one of your moderators notice another broadcaster in your chat,
|
||||||
|
// the other broadcaster is coming up in conversation, or after they raid your broadcast.
|
||||||
|
//
|
||||||
|
// Twitch’s Shoutout feature is a great way for you to show support for other broadcasters and help them grow.
|
||||||
|
// Viewers who do not follow the other broadcaster will see a pop-up Follow button in your chat that they can click to follow the other broadcaster.
|
||||||
|
// Learn More: https://help.twitch.tv/s/article/shoutouts
|
||||||
|
//
|
||||||
|
// Rate Limits The broadcaster may send a Shoutout once every 2 minutes.
|
||||||
|
// They may send the same broadcaster a Shoutout once every 60 minutes.
|
||||||
|
//
|
||||||
|
// To receive notifications when a Shoutout is sent or received, subscribe to the channel.shoutout.create and channel.shoutout.receive subscription types.
|
||||||
|
// The channel.shoutout.create event includes cooldown periods that indicate when the broadcaster may send another
|
||||||
|
// Shoutout without exceeding the endpoint’s rate limit.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:shoutouts scope.
|
||||||
|
func (c *Chat) SendShoutout(ctx context.Context, params *SendShoutoutParams) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/shoutouts", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPost, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateChatSettingsParams struct {
|
||||||
|
// The ID of the broadcaster whose chat settings you want to update.
|
||||||
|
BroadcasterID string `url:"broadcaster_id"`
|
||||||
|
|
||||||
|
// The ID of a user that has permission to moderate the broadcaster’s chat room, or the broadcaster’s ID if they’re making the update.
|
||||||
|
// This ID must match the user ID in the user access token.
|
||||||
|
ModeratorID string `url:"moderator_id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateChatSettingsRequest struct {
|
||||||
|
// A Boolean value that determines whether chat messages must contain only emotes.
|
||||||
|
//
|
||||||
|
// Set to true if only emotes are allowed; otherwise, false. The default is false.
|
||||||
|
EmoteMode *bool `json:"emote_mode"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether the broadcaster restricts the chat room to followers only.
|
||||||
|
//
|
||||||
|
// Set to true if the broadcaster restricts the chat room to followers only; otherwise, false. The default is true.
|
||||||
|
//
|
||||||
|
// To specify how long users must follow the broadcaster before being able to participate in the chat room, see the follower_mode_duration field.
|
||||||
|
FollowerMode *bool `json:"follower_mode"`
|
||||||
|
|
||||||
|
// The length of time, in minutes, that users must follow the broadcaster before being able to participate in the chat room.
|
||||||
|
// Set only if follower_mode is true.
|
||||||
|
// Possible values are: 0 (no restriction) through 129600 (3 months).
|
||||||
|
// The default is 0.
|
||||||
|
FollowerModeDuration *int `json:"follower_mode_duration"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether the broadcaster adds a short delay before chat messages appear in the chat room.
|
||||||
|
// This gives chat moderators and bots a chance to remove them before viewers can see the message.
|
||||||
|
//
|
||||||
|
// Set to true if the broadcaster applies a delay; otherwise, false.
|
||||||
|
// The default is false.
|
||||||
|
//
|
||||||
|
// To specify the length of the delay, see the non_moderator_chat_delay_duration field.
|
||||||
|
NonModeratorChatDelay *bool `json:"non_moderator_chat_delay"`
|
||||||
|
|
||||||
|
// The amount of time, in seconds, that messages are delayed before appearing in chat. Set only if non_moderator_chat_delay is true.
|
||||||
|
// Possible values are:
|
||||||
|
//
|
||||||
|
// 2 — 2 second delay (recommended)
|
||||||
|
//
|
||||||
|
// 4 — 4 second delay
|
||||||
|
//
|
||||||
|
// 6 — 6 second delay
|
||||||
|
NonModeratorChatDelayDuration *int `json:"non_moderator_chat_delay_duration"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether the broadcaster limits how often users in the chat room are allowed to send messages.
|
||||||
|
// Set to true if the broadcaster applies a wait period between messages; otherwise, false.
|
||||||
|
// The default is false.
|
||||||
|
//
|
||||||
|
// To specify the delay, see the slow_mode_wait_time field.
|
||||||
|
SlowMode bool `json:"slow_mode"`
|
||||||
|
|
||||||
|
// The amount of time, in seconds, that users must wait between sending messages.
|
||||||
|
// Set only if slow_mode is true.
|
||||||
|
//
|
||||||
|
// Possible values are: 3 (3 second delay) through 120 (2 minute delay). The default is 30 seconds.
|
||||||
|
SlowModeWaitTime *int `json:"slow_mode_wait_time"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether only users that subscribe to the broadcaster’s channel may talk in the chat room.
|
||||||
|
//
|
||||||
|
// Set to true if the broadcaster restricts the chat room to subscribers only; otherwise, false.
|
||||||
|
// The default is false.
|
||||||
|
SubscriberMode *bool `json:"subscriber_mode"`
|
||||||
|
|
||||||
|
// A Boolean value that determines whether the broadcaster requires users to post only unique messages in the chat room.
|
||||||
|
//
|
||||||
|
// Set to true if the broadcaster allows only unique messages; otherwise, false.
|
||||||
|
// The default is false.
|
||||||
|
UniqueChatMode *bool `json:"unique_chat_mode"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateChatSettingsResponse struct {
|
||||||
|
// The list of chat settings. The list contains a single object with all the settings.
|
||||||
|
Data []Settings `json:"data"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the broadcaster’s chat settings.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the moderator:manage:chat_settings scope.
|
||||||
|
func (c *Chat) UpdateChatSettings(ctx context.Context, params *UpdateChatSettingsParams, body *UpdateChatSettingsRequest) (*UpdateChatSettingsResponse, error) {
|
||||||
|
v, _ := query.Values(body)
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/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.MethodPatch, endpoint.String(), r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
var data UpdateChatSettingsResponse
|
||||||
|
if err := json.NewDecoder(res.Body).Decode(&data); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &data, nil
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
package chat
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/google/go-querystring/query"
|
||||||
|
)
|
||||||
|
|
||||||
|
type UpdateUserChatColorParams struct {
|
||||||
|
// The ID of the user whose chat color you want to update. This ID must match the user ID in the access token.
|
||||||
|
UserID string `url:"user_id"`
|
||||||
|
|
||||||
|
// The color to use for the user's name in chat. All users may specify one of the following named color values:
|
||||||
|
//
|
||||||
|
// blue, blue_violet, cadet_blue, chocolate, coral, dodger_blue, firebrick
|
||||||
|
// golden_rod, green, hot_pink, orange_red, red, sea_green, spring_green, yellow_green
|
||||||
|
//
|
||||||
|
// Turbo and Prime users may specify a named color or a Hex color code like #9146FF. If you use a Hex color code, remember to URL encode it.
|
||||||
|
Color string `url:"color"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Updates the color used for the user’s name in chat.
|
||||||
|
//
|
||||||
|
// Requires a user access token that includes the user:manage:chat_color scope.
|
||||||
|
func (c *Chat) UpdateUserChatColor(ctx context.Context, params *UpdateUserChatColorParams) error {
|
||||||
|
v, _ := query.Values(params)
|
||||||
|
endpoint := c.baseUrl.ResolveReference(&url.URL{Path: "chat/color", RawQuery: v.Encode()})
|
||||||
|
|
||||||
|
req, err := http.NewRequestWithContext(ctx, http.MethodPut, endpoint.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := c.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer res.Body.Close()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -81,3 +81,13 @@ type CurrencyAmount struct {
|
||||||
// The ISO-4217 three-letter currency code that identifies the type of currency in value.
|
// The ISO-4217 three-letter currency code that identifies the type of currency in value.
|
||||||
Currency string `json:"currency"`
|
Currency string `json:"currency"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AccentColor string
|
||||||
|
|
||||||
|
const (
|
||||||
|
AccentColorPrimary AccentColor = "primary"
|
||||||
|
AccentColorBlue AccentColor = "blue"
|
||||||
|
AccentColorGreen AccentColor = "green"
|
||||||
|
AccentColorOrange AccentColor = "orange"
|
||||||
|
AccentColorPurple AccentColor = "purple"
|
||||||
|
)
|
||||||
|
|
11
ptr_types.go
11
ptr_types.go
|
@ -150,3 +150,14 @@ func ToSortOrder(s *types.SortOrder) types.SortOrder {
|
||||||
}
|
}
|
||||||
return *s
|
return *s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func AccentColor(s types.AccentColor) *types.AccentColor {
|
||||||
|
return &s
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToAccentColor(s *types.AccentColor) types.AccentColor {
|
||||||
|
if s == nil {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
return *s
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue