mirror of
https://github.com/Luzifer/twitch-bot.git
synced 2024-12-20 20:01:17 +00:00
150 lines
4.6 KiB
Go
150 lines
4.6 KiB
Go
package twitch
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/mitchellh/hashstructure/v2"
|
|
)
|
|
|
|
type (
|
|
// GetVideoOpts contain the query parameter for the GetVideos query
|
|
//
|
|
// See https://dev.twitch.tv/docs/api/reference/#get-videos for details
|
|
GetVideoOpts struct {
|
|
ID string // Required: Exactly one of ID, UserID, GameID
|
|
UserID string // Required: Exactly one of ID, UserID, GameID
|
|
GameID string // Required: Exactly one of ID, UserID, GameID
|
|
Language string // Optional: Use only with GameID
|
|
Period GetVideoOptsPeriod // Optional: Use only with GameID or UserID
|
|
Sort GetVideoOptsSort // Optional: Use only with GameID or UserID
|
|
Type GetVideoOptsType // Optional: Use only with GameID or UserID
|
|
First int64 // Optional: Use only with GameID or UserID
|
|
After string // Optional: Use only with UserID
|
|
Before string // Optional: Use only with UserID
|
|
}
|
|
|
|
// GetVideoOptsPeriod represents a filter used to filter the list of
|
|
// videos by when they were published
|
|
GetVideoOptsPeriod string
|
|
// GetVideoOptsSort represents the order to sort the returned videos in
|
|
GetVideoOptsSort string
|
|
// GetVideoOptsType represents a filter used to filter the list of
|
|
// videos by the video's type
|
|
GetVideoOptsType string
|
|
|
|
// Video contains information about a published video
|
|
Video struct {
|
|
ID string `json:"id"`
|
|
StreamID *string `json:"stream_id"`
|
|
UserID string `json:"user_id"`
|
|
UserLogin string `json:"user_login"`
|
|
UserName string `json:"user_name"`
|
|
Title string `json:"title"`
|
|
Description string `json:"description"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
PublishedAt time.Time `json:"published_at"`
|
|
URL string `json:"url"`
|
|
ThumbnailURL string `json:"thumbnail_url"`
|
|
Viewable string `json:"viewable"`
|
|
ViewCount int64 `json:"view_count"`
|
|
Language string `json:"language"`
|
|
Type string `json:"type"`
|
|
Duration string `json:"duration"`
|
|
MutedSegments []struct {
|
|
Duration int64 `json:"duration"`
|
|
Offset int64 `json:"offset"`
|
|
} `json:"muted_segments"`
|
|
}
|
|
)
|
|
|
|
// List of filters for GetVideoOpts.Period
|
|
const (
|
|
GetVideoOptsPeriodAll GetVideoOptsPeriod = "all"
|
|
GetVideoOptsPeriodDay GetVideoOptsPeriod = "day"
|
|
GetVideoOptsPeriodMonth GetVideoOptsPeriod = "month"
|
|
GetVideoOptsPeriodWeek GetVideoOptsPeriod = "week"
|
|
)
|
|
|
|
// List of sort options for GetVideoOpts.Sort
|
|
const (
|
|
GetVideoOptsSortTime GetVideoOptsSort = "time"
|
|
GetVideoOptsSortTrending GetVideoOptsSort = "trending"
|
|
GetVideoOptsSortViews GetVideoOptsSort = "views"
|
|
)
|
|
|
|
// List of types for GetVideoOpts.Type
|
|
const (
|
|
GetVideoOptsTypeAll GetVideoOptsType = "all"
|
|
GetVideoOptsTypeArchive GetVideoOptsType = "archive"
|
|
GetVideoOptsTypeHighlight GetVideoOptsType = "highlight"
|
|
GetVideoOptsTypeUpload GetVideoOptsType = "upload"
|
|
)
|
|
|
|
// GetVideos fetches information about one or more published videos
|
|
func (c *Client) GetVideos(ctx context.Context, opts GetVideoOpts) (videos []Video, err error) {
|
|
optsCacheKey, err := opts.cacheKey()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("getting opts cache key: %w", err)
|
|
}
|
|
|
|
cacheKey := []string{"currentVideos", optsCacheKey}
|
|
if vids := c.apiCache.Get(cacheKey); vids != nil {
|
|
return vids.([]Video), nil
|
|
}
|
|
|
|
var payload struct {
|
|
Data []Video `json:"data"`
|
|
}
|
|
|
|
if err := c.Request(ctx, ClientRequestOpts{
|
|
AuthType: AuthTypeAppAccessToken,
|
|
Method: http.MethodGet,
|
|
OKStatus: http.StatusOK,
|
|
Out: &payload,
|
|
URL: fmt.Sprintf("https://api.twitch.tv/helix/videos?%s", opts.queryParams()),
|
|
}); err != nil {
|
|
return nil, fmt.Errorf("requesting videos: %w", err)
|
|
}
|
|
|
|
// Videos can be changed at any moment, cache for a short period of time
|
|
c.apiCache.Set(cacheKey, twitchMinCacheTime, payload.Data)
|
|
|
|
return payload.Data, nil
|
|
}
|
|
|
|
func (g GetVideoOpts) cacheKey() (string, error) {
|
|
h, err := hashstructure.Hash(g, hashstructure.FormatV2, nil)
|
|
if err != nil {
|
|
return "", fmt.Errorf("hashing opts: %w", err)
|
|
}
|
|
|
|
return strconv.FormatUint(h, 10), nil
|
|
}
|
|
|
|
func (g GetVideoOpts) queryParams() string {
|
|
params := url.Values{}
|
|
|
|
for k, v := range map[string]string{
|
|
"id": g.ID,
|
|
"user_id": g.UserID,
|
|
"game_id": g.GameID,
|
|
"language": g.Language,
|
|
"period": string(g.Period),
|
|
"sort": string(g.Sort),
|
|
"type": string(g.Type),
|
|
"first": strconv.FormatInt(g.First, 10),
|
|
"after": g.After,
|
|
"before": g.Before,
|
|
} {
|
|
if v != "" && v != "0" {
|
|
params.Set(k, v)
|
|
}
|
|
}
|
|
|
|
return params.Encode()
|
|
}
|